ISUCON4 予選に参加しました
昨日は ISUCON4 の予選 (1日目) に参加してきました。
予選の前々日の木曜日の朝に「今年の ISUCON は出たかったなー」などとぼんやり思いつつ会社に行ったところ、向かいの席の @Ajido が偶然にも「ISUCON 出よう!」と言ってくれたので、@shamabe と3人でエントリーしました。3人とも JavaScript が好きなので、実装は Node.js を選択してやってみることにしました。
さて、当日は10時に予選がスタート。自分は DB まわりの面倒を見ることにしたので、各テーブルのスキーマとインデックスを抽出してから、コードを読み始めてアプリの仕様とクエリをひと通り把握。適当なインデックスを作って適用したのがだいたい11時過ぎで、この時のスコアはだいたい 5,000 超えぐらいでした。その後は MySQL の設定 (InnoDB のメモリー関連など) のチューニングやったのですが、特に効果は見られず。今まであまり MySQL の設定チューニングをやったことがなかったのでこれはなかなか辛い…。
そうこうしてる間に他のメンバーがアプリの Cluster 化や Nginx のチューニングをやってくれて、スコアが 20,000 超えてくるように。自分は MySQL の設定チューニングに見切りをつけて、明らかに処理が遅かったブロック判定処理を Redis に置き換える実装を開始。Redis への置き換えは比較的簡単にできたのですが、ベンチマークをパスできなくなり結局原因がつかめないまま数時間を消費。この時はチームのスコアも伸び悩んでいてなかなか辛い時間帯でした。
結局 Redis への置き換えを諦めて、ユーザーと IP のブロック判定処理の SQL の改修をやってみることに。直前のログイン成功時のログの ID を見つけてきてそこを起点にログを抽出するようになっていた SQL を、ブロック判定時に使うしきい値の数のレコードだけを取ってくるシンプルな SQL に変更し、取ってきたレコードの中をループで見てブロック判定をするようにしました。これを適用して、スコアはなんとか 30,000 超えに。
残り1時間を切って、そろそろメンバーのネタ切れ。「試しに他の言語の実装も試してみようか」という話になり、Go の実装に GOMAXPROCS=4 を設定して実行したらスコアがいきなり 40,000 超え。「Node.js はダメな子か…」などとメンバーと話しながら、Node.js の実装でおこなった SQL の変更を Go の実装に適用しようとするも、間に合わずにここで時間切れ。
最終的なスコアはおよそ 43,000 でした。残念ながら1日目の10位以内にも入れず、現状のスコアで予選突破は難しそうですが、チームで「30,000 は超えたいね」なんて話もしていたので、それを超えるスコアが出せたのが嬉しかったです。とはいえ、自分はほとんどスコアに貢献できなかったので、ここまでスコアを引き上げてくれたチームメンバーに本当に感謝です。
こんな感じの ISUCON 初参加でしたが、チームメンバーの改善テクニックが見れたり、自分にとっての課題なんかも分かって、めちゃくちゃ楽しかったです。ISUCON 運営の皆様、本当にありがとうございました!