ISUCONとは
ISUCONとは、「いい感じにスピードアップコンテスト」(Iikanjini Speed Up CONtest)の略でウェブアプリケーションのパフォーマンスを競うイベントです。最大3 人のチームで参加し、与えられた時間内にチューニングを施し、パフォーマンスに基づいたスコアで競います。
今回参加したのは公式イベントではなく、社内イベントです。期間は約1週間で、1人チームとして参加し、結果は5位でした。総参加者100名程度と考えたらなかなか健闘したかなと思います。
実際に何をしたのか忘れないようにメモしたいと思います。
何にトライしたか
アプリケーションはいくつかの言語で作られており(アプリケーションを見てフルスクラッチで別言語で実装し直すのも有り)、私はPHPを選択しました。
不要な通信の削除
用意されているアプリケーションは完璧なものではありません。かなり下手な実装が有ります。これが業務だと「ひどいコードだ!!」と憤慨しますが、ISUCONだと「ひどいコードだ!!やったぜ!!」となります。おもしろいですね。
アプリケーションは(同じサーバにある)別のアプリケーションへHTTPクライアントでアクセスしてWeb APIをやり取りするような仕組みとなっていました。これは明らかに時間のかかる処理になっていたのでコードを移植して直接やりとりするようにしました。
DBチューニング
次に、explainでレコードをフルスキャンしている箇所を修正する。インデックスを貼る。場合によっては非正規化を行う(inner joinしない分高速化したりします)。InnoDBをMEMORYにする。などなどを行いました。今のプロジェクトではまだガッツリDBを触っていなかったので、Macの便利そうなクライアントも特に入れていませんでした。
試してみたのはsquel pro、直感的に色々操作できたので時間のない中すぐに使いこなせました。
フレームワークをやめる
PHPはフレームワークが使われていたので、フレームワークの使用をやめて直接動くように書き直しました。ルーティングはNginxのrewriteに任せました。これはかなり高速化に寄与しました。
リーダブルになるので重宝しますが、やはり速度にはそこそこ影響出るものなんだなぁと思いました。速度的な影響なんて比較したことなかったので、勉強になりました。
あと、業務でフレームワークの利用が当たり前…の人たちだとなかなかフレームワークを無くそうという発想に至らなかったみたいです。
DB削除
ベンチマークを何度か動作させて、チューニングを行っていくとある挙動に気づきます。どうやら今回のベンチマークはランダムに動作しているのではなく、ある法則があるように感じました。その為ベンチマークの動きに合わせたプログラムに書き直すことでDBを使用しないようにしました。
ここからただのウェブアプリケーションではない、ISUCON向けの「何か」に変貌しました。
HTML静的化
先にキャッシュ的なものを用意できるページはPHPから静的HTMLに変更しました。ここまでの処置を行ってからTOP10圏外から一気に5位まで上昇しました。
PHPのmake
PHPにアクセラレータが入っておらず、高速化されない状態だったのでビルドし直しました。ただこれは思ったよりも効果が見えてこなかったような。
その他
- favicon.icoへの通信もあってそのレスポンスもきちんと200で返すと得点が上がりました。
- ログを出力しないようにしました、殆ど効果は見えてこないですがいわゆる「おまじない」的に行ってみました。
- 一部のデータでシェアードメモリを使ってみました、があまり効果は有りませんでした。
- HTMLのminifyをやってみました。があまり効果は有りませんでした。これもおまじない程度かと。
何が足りなかったか
こう少し上のランクに行くには以下が必要だったなーという思いもメモしておきます。
ベンチマークの挙動解析
ベンチマークの挙動をもう少し詳しく調査していれば静的化できる部分がもっとあったようです。
パフォーマンスモニタリング手段の知識
なんとなくモニタリングツールは知っていますが、どうやればどうというアタリをつけられなかったかなーと思います。もう少し場数踏んでいきたいと思います。
チューニング結果の点数確認
チューニングの結果を見ずに場当たり的に行った施策に罠があったようで、転送速度は上がるものの、トータルで見ると点数が下がるというものがありました。しかし結果を見ていないので気づけない。ダメですね。
変態さ
上位チームの中には「Nginxを改造しました」とか「C++でソケットから書きました」という方達がおられました、そういう変態プレイは無かったので次は変態プレイにも挑戦しつつ上位を狙いたいと思います。
最後に
次があればまた出たいです。次はチームで参加してチャットで語り合ったりとかも…。