NaCl 松江本社のyharaです。こんにちは。Webアプリケーションの高速化技術を競うコンテスト「ISUCON」に弊社メンバーで参加し、予選を突破して本戦に出場できることが決定したので、簡単ですが参加記を書こうと思います。
15位のチーム「yarunee」が我々です。最終スコアは11,160 イスコインでした。この記事によると予選突破チームのほとんどはGo言語を使用していたようですが、弊チームは一番使い慣れている言語ということでRubyで参加しました。
ISUCONは2011年から行われているコンテストで、課題となるアプリケーションが与えられ、それを(挙動を大きく変えない範囲で)最も性能が出るよう改造できたチームが優勝、というイベントです。
今回はAlibaba Cloudのクーポンが参加者に付与されて、そこにインスタンスを立てて作業するという流れでした。対象となるアプリは本番の朝にイメージファイルという形で提供されました。
スコアの遷移は以下です。ラスト30分で大きく上がっていることが分かります。
これは何をしたかというと、MySQLとアプリケーションを別ホストにしたのでした。今回はインスタンスを3台まで使ってよいルールだったので、topコマンドで一番CPU負荷が高そうだったMySQLを別ホストに切り出しました。
極めて普通の作業ですが、コンテストという状況から残り時間を見て焦ったり、あるいは別の高速化施策とバッティングしたりすると、簡単には行かなかったかもしれません。実際に必要だった作業は以下です。
/initialize
が、init.shというスクリプトを外部コマンドとして実行しているbind-address 127.0.0.1
だとローカルからしか接続できないのでそこからもう少し上がっているのは、pumaを複数プロセスに変更した結果です。systemdの設定ファイルで rackup -p 8000
となっているところをpumaコマンドに変え、puma -p 8000 -w 4
のようにすることで、ワーカー数を増やすことができます。個数については2→4→5と試して、一番良かった4を採用しました(3は時間の都合で試せませんでした)。
他にやったこととして、Sinatraをdevelopmentからproductionモードに変更したというのがあります。前述のpumaコマンドの場合、puma -p 8000 -e production
のように-e
で設定できます。
10時〜18時という長丁場を快適に戦うためには、サーバ上の環境を快適に整えることも大事です。今回はあまり準備はしていなかったのですが、とりあえず.vimrcに以下を追加したのと、
autocmd FileType netrw nnoremap <buffer> <silent> h -
autocmd FileType netrw nnoremap <buffer> <silent> l <CR>
screenを入れて以下のような.screenrcを作成しました。LoadAVGが出せることはこちらの記事で知ったのですが、たまに便利だったりしました。
escape ^Zt
hardstatus alwayslastline "%{= cd} %-w%{= wk} %n %t* %{-}%+w %= LoadAVG [%l] "
インスタンスが3台あるのでSinatraアプリを3台に配置してロードバランスさせたかったのですが、エラーが出て断念しました。
1つ目のエラーは商品画像がダウンロードできないというもので、これについては画像を1台に寄せる(ロードバランサであるnginxの設定で、/sell
と/upload
はかならずホスト1に飛ぶようにする)ことで解決しました。
一方2つ目のエラーは/new_item/xx.json の商品数が正しくありません
というもので、こちらは未解決です。当該のjsonを返す処理自体は特に分割で壊れるようには見えなかったので、CREATEが壊れているのではという話は出ましたが、どうだったんでしょうか。
アプリケーションコードをいじる系の修正は前田さんがやってくれたので、結果的には僕のコードはほとんど入っていないです。
しいていえばロガーの設定が僕ですね。requireを冒頭以外に書くのはあまり普通ではないですが、今回は元からあるコードと区別しやすい方が良いかなということでこうしています。ロガーはここで使っています(コミットし忘れていますが、実際には$!
がnil
である場合のチェックが必要です)。
予選を突破したということで、10/5(土)の本戦に出場する予定です。メンバー3人とも島根県在住なので、宿と飛行機を取らないとなと話しています。当日はよろしくお願いします。