ISUCON7予選敗退してきました

クソアニメ同好会 (ragi256, oboenikui, bonprosoft)として参加。最終スコアは20103。

180位だった 

実は昨年も参加していたが、そのときは本当に何も出来ずただひたすらオロオロするだけだったので参加記も書く気になれなかった。今年はちょっと書けると思うので書いてみる。

 

前日まで

研究室時代のメンバーで参加することになったので研究室OBのSlackでisucon用のプライベートチャンネルを用意しておく。チーム名決まるまでが長かった。

大雑把な役割分担として自分とoboenikuiがアプリケーションより、bonprosoftがインフラよりで、ということに。使用言語はPython

10/14, 10/15 

oboenikuiは初参加だったので、当日までのどこかで練習する時間をとっておこうということに。とりあえず一週間前の土日の夜にISUCON5予選問題をやろうという話だったが、まず土曜夜の段階でVagrant立ち上げに予想以上に時間がかかり問題に触ることもなく終わった。練習の前日にvagrant upしとけばよかったと少し後悔した。日曜はログとりやボトルネック調査に費やした。

この時点でだいたいどこをどう直すべきかは二人で把握できていたが、実際に手を動かさずに終わる。

10/16

する予定はなかったが、その後も夜に続きをやることにした。ISUCON5予選WriteUpを読んで上位チームの方針を参考にし、どうすると高スコアが出るのかを学ぶ。このあたりで我々にはredisやmemcachedなどのキャッシュの知識がないとわかる。また、前回の敗因の一つとして、Webサーバーのプロファイリングを怠ったことではないかということで、Werkzeugも試すことに。

10/17

Werkzeugのプロファイラを試す。キャッシュも試したかったが色々時間を費やしてしまい翌日に持ち越し。

10/18

いざキャッシュ。memcachedとredisの違いを調べるところから始まり、とりあえずredisを練習することに。MySQLからテーブルをダンプしてredisに入れ、aofで永続化する流れを試した。

前日

当日は出来る限り一緒に臨んだほうがいいということで本番はoboenikui宅に前日から泊まり込みで参戦。雨の影響か体調を崩す。

当日

最初に自分がSSH回りを設定し、皆がログインしてbonprosoftがデプロイの自動化とログ計測回りを準備し、アプリケーションの二人がコードリーディングをする手はずだったが、全然ログインできなかったため結局bonprosoftが全部設定した。

 13:50

チームメンバーが大体確認できるようになったため、ログ計測も兼ねて初回ベンチ。その間にoboenikuiがコードを読み、自分がDB内の構成を確認していた。githubに用意したprivateリポジトリのissueに各自確認した内容を記入していく。

ベンチ結果、とにもかくにもiconの配信がボトルネックになっていることがわかったのでまずはそこに取り組み始める。

15:30

channel_list_infoが全チャンネルとfocus_channelの両方の情報を取得しているので分割し、必要な時に必要な情報を呼ぶようにする。

使っているmacgithubのprivateリポジトリに触るのが初だったため無駄に手間取ってしまった。

17:00

やたらとクエリに*が入ってたのが気になって消し始める。count(*)をcount(1)にしたり、必要な分だけのカラムに絞ったり。このあたりは計測結果のボトルネックから来ているのではなく、とにかく「気になる」というメンバーが多かったためやったが、多分効果はあまりなかったと思う。

しかもtemplateで必要な情報を抜け落としてしまったためにバグを出す始末。

18:00

icon回りの配信が改善されたことで次のボトルネックがmessageに移る。messageとhistoryのN+1は把握していたが上記のバグのせいでなかなか進まず。

20:00

単純にN+1を潰すだけはjoinですぐにできたが、APIの仕様上どうしてもuserをネストしたjsonで返さないといけない。これをMySQLから取得後ループ無しで行う方法がどうしてもわからなかった。MySQLjson_objectを使って試してみるもuserの中身がjsonではなくstringとして判定されてしまい苦しむ。ここがかなり手こずった。

結局諦めておとなしくfor文を回し、user以下が辞書型になるようにした。

が、全然速くならない。というか何か挙動が変だ。

21:00

実は勘違いにより「お、order byでdescしてんのに結局reserveしてるじゃん。これ昇順で取れば一発じゃね」と勝手にdescを消していた。「最新の100件古い順に並べるんだよ!」と終了間際にoboenikuiに言われ絶望。なんだよ昇順って、最古の100件とってどうすんだ。

また、この勘違いのせいでてっきりmessageは1ページに何度も呼ばれるものだと思っていたが、実際は1ページに一回しか呼ばれず上記json周辺は実はさして気にする必要がなかったと知る。

今回の一番の後悔。

 

感想

最後のアレさえきちんと出来ていればあるいは…という悔いが残った。ISUCON6のときとは違ってDBの調整が効いてくるはずの問題だっただけに悔しい。

コードリーディングとアプリケーション把握という課題ができた。

次こそは満足の行く結果を残したい。

 

最後に、運営の皆様に感謝を。今年はベンチが高速快適最高と言うことなしでした。お疲れ様でした。