kotamanegiの取り扱い説明書

のんびり趣味の事を書いてます。

ISUCON11予選 kotamanegiの参加記

概要

ISUCON11予選にチームkotamanegiとして一人で参加し、学生枠で本選に出場できることになりました。 主要な改善点・工夫は

  • DBのindexをきちんと構築する
  • SQLのうちLIMIT句が効きそうなところに追加する
  • 自動デプロイスクリプトを書く
  • POST /api/condition/:jia_isu_uuid に対する実装の、確率でリクエストを破棄する処理を削除

の4点でした。 結果は全体40位/学生4位となり初参加でしたが本選に出場できるほどの好成績を残せました。

開戦前

チーム編成について

初参加なので他人に迷惑をかけたくないという気持ち & 本選に行けると思っていなかったのがあって今回は1人で参加しました。 今年のISUCONに参加してみて、僕の実力で戦えそうな雰囲気だったので来年はぜひチームで出てみたいです。

事前準備

複数台与えられた時のシステム構成だけを考えていました。 DB1台+Web2台で、Web2台間はnginxでいい感じに振り分けるつもりでした。

作業のタイムライン

メモを取っていないため時系列は適当になっています。

開戦 ~ 3時間経過地点まで

  • 0:00 当日マニュアルが開かなくて焦る。 とりあえずAWS Cloud Formationにダウンロードしてきた設定ファイルを投げて環境構築してもらう。
  • 0:05 当日マニュアルが開けるようになる。 初回のベンチマークを実行する。
  • 0:30 scpでファイルの転送が出来るようになる。 ホームディレクトリの内容を全て(!)ダウンロードする。
  • 0:40 ダウンロードしてリポジトリにpushしようとしたが、~/localディレクトリが異常に大きいことに気づく
  • 1:30 ~/localディレクトリのGoコードは外部ライブラリであることに気づく
  • 2:00 各サーバに置いてあるレポジトリについて自動でgit pullするデプロイスクリプトを書く
  • 2:30 ~/webapp/go内のコードを読んでいる最中に、ポータルの質問コーナーを見てアプリケーションマニュアルの存在に気づく
  • 3:00 Goコードを書き換えて実行ファイルを送り込むが、変更が反映されなかった

3時間 ~ 5時間経過地点まで

  • 3:05 ps -axでプロセスを見てみると~/webapp/go/isuconditionを実行しているプロセスを発見する
  • 3:30 サービス名がisucondition.goであることを突き止める
  • 4:00 デプロイスクリプトを書いて改造Goサーバが動作することを確認
  • 4:05 topコマンドでMySQLサーバがボトルネックになっていることを発見、別サーバに分離する作業を始める
  • 5:00 別サーバに分離が完了、ついでにPOST /api/condition/:jia_isu_uuid も分離

5時間経過 ~ 最後まで

  • 5:05 DBにindexを張る作業を始める
  • 5:30 EXPLAINを付けてSELECT文を実行してもindexが使われず、原因究明を始める
  • 5:40 DB系ファイルの転送を忘れていたことが発覚しデプロイスクリプトを修正
  • 6:00 ボトルネックが解消しMySQLサーバのCPU使用率が130%前後に落ち着く、この時スコアが3.5万程度になる
  • 6:30 POST /api/condition/:jia_isu_uuid に対する実装の、確率でリクエストを破棄する処理を削除
  • 7:00 MySQLサーバのCPU使用率が200%に再び戻る、スコアが変化しないことから他のエンドポイントの改善を始める
  • 7:10 SQLにLIMIT句を付ける作業を行い、ベンチマーク実行
  • 7:15 ポータルに障害発生しアクセスできなくなったが、一瞬7万点までスコアが上昇したことが確認できた
  • 7:16 DBを見ているとisu_conditionだけがカラム数80万に達しておりここがボトルネックと判断
  • 8:15まで 障害が発生している間にPOST /api/condition/:jia_isu_uuid をバッチ処理に切り替える実装を書いていた
  • 8:15 競技再開、ベンチマークを実行するが点数が変化せず困惑する
  • 8:30 サーバ側のgitレポジトリ内の内容を操作した結果pullが正常に行えず変更が反映されていないことを確認し、再度ベンチマークを実行
  • 8:32 スコアが1000になりPOST /api/condition/:jia_isu_uuid が動いてないことがわかる
  • 8:35 変更をrevertして元の7万点コードに戻す、何回か実行していると7.5万点までは上がった
  • 8:45 コンテスト終了

分析

自動デプロイスクリプトを初手で書いたのは後半の作業効率の向上にとても効いたと思っています。 万が一環境を破壊したとしてもすぐに環境再構築が出来るというのは精神的にもメリットが大きかったです。 再起動スクリプトも仕組んでいたので再起動試験にも安心して対応できました。

DB的な面では、EXPLAIN句を知っていたおかげでindexが使われていないという致命的なミスを発見できたのが嬉しかったです。 知らなかったらスコアが低いままだったのを考えるとEXPLAIN句は重要な役割を果たしてくれました。

アプリケーション的な改善は後回しにしていたらほぼ改変する暇がなくなってしまいました。 DBの改修で手一杯になっていたのでサーバ構築の事前準備をしていたら時間が取れたのかもと後悔しています。

感想

インフラ系の環境構築コンテストは初めてだったのですが、高速化の様子がうまく可視化されていて楽しかったです。 本選はもうちょっと対策して賞金を狙っていきたいと思います(強欲)