ちゃっくのメモ帳

ちゃっくがメモしときたいことをメモしとくよ

ISUCON8予選参加記

9/16に行われたISUCON8の予選に参加しました。
学生枠にチームIQ1としてkuwa,zakuro,chakkuの3人でチームを組みました。

コードを公開しようと思ったがうちのチームはGitを使わずサーバー上で作業してたので手元にコードが残っていませんでした。

練習

2週間前と1日前の2回練習をした。
2週間前の練習は3人ともISUCON未経験だったので環境構築をしてアプリを動かしてみるという感じで実際にスコアを上げてみるみたいなことはできず。なんとなく他の人の予選のブログをみたりしてた。HackMDに必要そうな情報をまとめたり...
あと、参考実装の言語で最初はgoを動かしていたが、全員が書いたことがあるのがpythonだったのでpythonを使用することにした。
goのほうが早いと予想したがpythonでもそこまでローカルベンチマークに大きな差がなかったのでpythonを採用。

1日前の練習はkuwaさんは寝てた。僕とざくろさんは準備としてVSCodeで画面,ローカルサーバー,terminalの共有をするプラグインを使ってやればいいやって感じの準備をして、その後過去3年分の予選のブログを読んだりして有用そうな情報を集めたりしていた。
このときに方針として「キャッシュコントロール」「N+1問題の解消」をクリアすれば予選通過はできると予想していた。

本番

10時にラボに集まって予選開始。
とりあえずサーバーにsshしてみてファイルをローカルに落とした。
ローカルに環境構築をするのが大変そうだったのでサーバーでtmuxを開いて3人でterminal共有をして作業をしていた。
3人で8時間だとGitで管理するほどではないなってことでGitは使ってない。編集はtmuxに接続してやってるのでコンフリクトみたいなことはしないし。
とりあえずapp.pyを開いてN+1問題を探すと、get_eventの中でN+1問題が発生しているのと数箇所からforの中でget_eventが呼ばれてるのが見て2重のN+1問題になってるなーと思った。
逆に最初に方針を立てていたキャッシュ周りはあんまり適用先が考えられなかったので放棄。逆にサーバーが3台あるので2台のappと1台のDBで構成しようという話になった。

とりあえずget_eventのN+1問題を解消したらすでに昼を過ぎた位の時間になっていた。
お昼ご飯には冷凍カルボナーラとデニッシュパンを温めて食べた。
この時点で8000点くらいになっていて、「複数台構成にしたら単純計算2倍になったらいいね」みたいな会話がなされていた。
昼を食べて、とりあえず「複数台構成」「ORDER BY RAND LIMIT 1」「get_events」あたりの最適化にあたりを絞って作業をした。
僕はORDER BY RAND LIMIT 1を担当したけどあんまりいい方法が思いつかず、SQLを2回発行する方針にしてみたがベンチマークは変わらなかった。
kuwaさんとzakuroさんが複数台構成をしようとしたがh2oでやるのは大変そうだったのでnginxに変更。
残り1時間は再起動テストとかにしようと言っていたら残り30分くらいでデッドロックとデータ競合が発生してしまった。
とりあえずRANDは変更してもあんまりベンチマークが変わらないのでもとに戻し、あとはdebug=Trueを消したりしたがこれでデッドロックとデータ競合が解決するとは思えず、調べているとワーカースレッドが多すぎる可能性が出てきたのでappサーバーはそれぞれワーカースレッドを2ずつにした。ワーカースレッド4で点数が最大29000くらいでワーカースレッドを2ずつにしたら16000くらいになったがこの時点で予選終了。奇しくも8000の2倍の点数で終了。

結果

学生枠で通過してました。

感想

他にもある程度の点数になるとデッドロックガチャになると言っている人がいるので、SQL失敗したらもう一度やり直すみたいなのが必要だったかもしれない。
僕はSQL修行が足りなかったなと感じた...
楽しかったがめちゃめちゃ疲れた.....