isucon#3 オンライン予選2日目に、
@memememomoと「進撃の超大型パティスリー兄弟」として参加してきました。
現在はまだ暫定ではありますが、2日目の1位(総合4位)で予選通過予定とのことです。

過去に isucon#1, isucon#2 と参加してきて、
思ったような結果を残せなかったので、今回は非常に嬉しいです。
チューニング内容的には普通のことしかしておらず、その辺りは他のひとの方が大分詳しい印象。
3度目の挑戦ならではの対策などについて書いてみました。

事前準備

事前に決めていた対応方針は以下のようなものです。
・使用する言語は、Perl(@memememomoの強い要請により)
・2人で並行作業は行わず(インフラ/プログラムで担当分けせず)すべてダブルチェック対応
ボトルネックへの対応に集中する
方針がブレるとisuconの熱気にやられておかしな方向に進んでしまうため、
対策の方針を決めるのは僕たちにとっては重要でした。

当日の朝は、Lingrのログを見たり、AWSのSecurityGroupを作ったりしてました。
また、一日目の上位スコアは公開されていたので、
予選通過ラインは1万点くらいだろうと見積もることもできました。

isuconスタート

git導入して初期準備は完了。
README.mdを読む。
workloadオプションは、ダブルチェックで間違った認識に着地。
なので一回も使ってません。

環境作ったり、システム確認したりで、
チューニングに着手したのは、11:00頃でした。
無駄に指差しダブルチェックしててかなり時間をロスしていたと思います。
初期スコアは、700点くらい。
このときすでに1位は2,000〜3,000点くらいだったと思います。

初期状態ではMySQLボトルネックになっていたので、
スロークエリを改善したり、インデックス貼ったり、
プロキシサーバをapacheからvarnishに変更したり。
この時点でスコアは2,500くらいでトップ10圏外でした。

また、最初からnginxが入っていて怪し過ぎたので
完全削除してインストールし直しました。
isuconでは予め用意されているものはワナにしか見えません。
静的ファイルをnginxに任せて、スコアは若干上がったと思います。

その後、地味にSQLを改善し続けて、
14時過ぎにスコアは3,800くらいとなり、
ここでようやくtop10に入りました。

その後もひたすら普通にSQLの改善を続けて、
15時頃にスコアは4,600くらいに。

そして、残り3時間

予選2日目は、1日目よりも他チームのスコアの伸びが早かったと思います。
この時点でトップはすでに2万を超えていましたし、
僕たちはトップ10から外れていました。
2日目のtop10のスコアは1万を超えてくるかもしれないという不安が過ります。
そろそろ、何らかのブレークスルーを出さなければ負ける時間帯だと思えてきました。
アプリ側でまだまだ改善すべき処理は残っていたのですが、
ワナに掛かってもまだ時間のあるこのタイミングでの
フロントでのキャッシュ対応に切り替えました。
想像以上にキャッシュ対策が上手くハマり、FAILを出しつつも24,000くらいのスコアで一気にトップに。
さらにキャッシュの調整を加え、30,000を超えました。
オンライン予選では、AMIの提出までが勝負なので、
実際にベンチを走らせることができる18:00までに、
もろもろのテストを行うことにしました。
AMIを作成し、他アカウントでインスタンス起動/ベンチ実行。
スコアも問題ないことを確認しました。
そして無事に予選終了。

まとめ

ボトルネック対応に集中したのが良かったと思います。
ダメなところもありましたが、指差しダブルチェックもいい感じでした。
初動が遅かったので本戦ではスピーディに対応したい。
SQLの改善では既存スキーマから大幅に変えることはしませんでしたが、
そのおかげで着実にスコアは上がったものの、
微増といった感じだったので、もっと思い切って変えてもよかったなと思っています。

最後になりましたが、isuconには今回で3回も参加させていただいており、
企画/運営をされておりますLINE/面白法人カヤック/DATAHOTELの皆様には
ほんとうに感謝しております。ありがとうございます!