ISUCON4の予選に参加してきた #isucon

ISUCON4の予選にkyokomiyasuunとチームを組んで参加してきました。
1日目に参加し、最終送信結果は15107、benchmark v2では17124と予選通過には程遠いスコアでした。
しかも、AMI審査方法の通りに実行してみたら見事にレギュレーション違反!
来年リベンジするためにも記録を残しておこうと思います。

予選当日までにやったこと

ISUCON初参加だったので、感覚をつかむために前回予選のAMIを使って3人で練習。
正直、この練習をやってなければもっとひどい結果になっただろうと思えるくらい、問題点や準備しなければならないことが山ほど出てきて泣きそうでした。

アクセスログMySQLのスローログの分析方法を事前に調べて手順化しておき、当日に慌てないように準備することにしました。

使う言語もこの時に決定。得意言語はバラバラで、Perl2人、Go1人だったんですが、作業分担的にGoにすることに。

リポジトリGitHubのプライベートリポジトリ、テキストでのやりとりはSlackを使いました。ISUCON用のチャンネルを作って、そこにGitHubにpushした内容などを通知させるように設定。

予選当日 午前

まずは当日のマニュアルに目を通し、起動したインスタンスのIPをSlackに貼る。
鍵は練習で使用したものを流用。.ssh/configにIPと鍵の場所を書いて簡単にログイン出来るようにした。

ログインしたらまず/home/isucon配下でgit initして remote add & push。
最初は修正は行わずに、アプリケーションの内容やミドルウェアなどの情報を調べることに。
アプリにログインしたあと何も出来なかったので、この機能が動くように修正するのか!?と勘違いしましたが、すぐにログインゲーだと気づく。

次にnginxのログとMySQLのスローログ(long_query_time=0)を出力する設定にしてベンチ初回実行。
access.logはApache::Log::Parserを使って集計、MySQLのスローログはmysqldumpslowを使って集計。

bench.shを作成。内容は、今あるnginxのログとMySQLのスローログをrenameして空にし、nginx、MySQL、supervisordの再起動して、ベンチを実行という感じ。

ひと通り見たので修正方針の話し合い。
login_logテーブルで禁止IPの判断、禁止Userの判断、前回ログイン情報の取得と色々やってたので、これを分割することにする。
禁止IPカウントテーブル、禁止Userカウントテーブルを作り、それをメモリに載せることにした。役割分担は以下。

  • waniji: 初期データ投入スクリプト作成
  • kyokomi: メモリに載せるようにアプリ修正
  • yasuun: nginxの設定周りを修正

午後

禁止IPカウントテーブルと禁止Userカウントテーブルの初期データ投入をPerlで作成。
Perlのアプリ実装を見てみたらlocal配下にDBIx::Sunnyがいたので、perl -I でそこを指定して初期データ投入スクリプトで使った。

禁止IP、禁止Userのカウント情報をメモリに持つ修正が出来てきたので計測したらスコアが12304。
更にnginxで静的ファイルをさばく設定がきて16002。
この時にcannot assign requested addressがでたけど、ローカルポートを食いつぶしてるとはわからず……。

次に、前回今回ログイン情報を持つテーブルを作ってlogin_logを廃止するとこに。
しかし、初期データ投入スクリプトが1分を超えてしまってウンウン悩んである間に時間がなくなってあえなく中断……。

ユーザーテーブルの情報をメモリに持つようにしたが、スコアが下がったので戻し。

この辺りで時間がなくなったのでworkload数を調整して、再起動して問題ないか確認をしてたらタイムアップ。

反省点

  • レギュレーション違反

データをメモリ上にしか持っていなかったので、再起動後のreport内容が不一致となってOUTでした。問題外なので次はこういったことがないように気をつけたい。

  • login_logにインデックスを貼らなかった

スローログを見て遅いのは分かっていたのに、どうせ無くすテーブルだからとインデックスを貼らなかったのが間違いだった。他チームの方の記事を見てみると、インデックスを追加するだけでクエリのチューニングが不要になるくらい早くなるとの事だったので、これは完全に判断ミスでした。

  • ローカルポートの食いつぶしに気が付かなかった

完全に知識と経験不足でした。予選終了後にいろいろ試したところ、ポートの設定を弄らないと20000弱で頭打ちになったので、これを対処できない人は足切りされる感じだった。

まとめ

予選は惨敗だったけど、チーム全員が準備も含めて楽しんでやってたし、色々と良い経験が詰めました!
来年も開催されたら絶対リベンジしたい!