ISUCON12予選突破した。 :old_noto_innocent:

作成日: 2022-07-24
いつものチームでISUCON12予選に参加しました。かれこれ、5回ぐらい参加しているみたいです。50,696点という良いスコアを残せて良かったです。
メンバーと役割分担は次の感じです。
  • 実装とオペが得意な utgw
  • サーバーのこと全部やってくれる nonylene
  • 実装を見て改善点の列挙と検証をする wass(私)
utgwの記事 https://blog.utgw.net/entry/2022/07/24/153718 にはアプリ実装とスコア詳細があります。何をしたか具体的には、こちらを見るとわかります。
nonyleneの記事 https://nonylene.hatenablog.jp/entry/2022/07/24/184518 には分析基盤の構築の話があります。便利すぎたので、ISUCON分析の定番になるまでありそうです。
まとめと個人的な話を書きます。

チームとして良かったこと

sqliteの早期殲滅

10時開始直後にsqliteをmysqlに移行する判断をしました。12時半に移行を完了したので、かなり時間的余裕が生まれました。utgwのえらすぎるオペレーションのおかげですね。
実装を見てみるとplayer_scoreは全行読まれるわけではない事がわかるので、行を減らすマイグレーションも行ってました。visitorも同様の削減も行なうことで、mysqlの初期ダンプがかなり小さくなりました。/initialize の実行時間の心配がなくなったのは安心でした。

Webからframe graphもslow logもtraceも見れること

nonyleneさんのパワーで、分析に必要なメトリクスがWebから見れるようになっていました。
ベンチマークのたびにコマンドを叩いてチャートを見るステップがなくなり、大幅に時間を有効活用できるようになりました。かなりおすすめです。

3台稼働できたこと

mysqlへの移行に成功したので、DBの機能分割が簡単でした。web、mysqlの他に、player_scoreだけを処理するmysqlを立ち上げました。

個人的に良かったこと

utgwの手を動かし続けることに成功したこと

残念ながら経験の差で、自分が実装するよりもutgwが実装するほうが早いです。そのため、私はutgwの手が空かないように、どの実装をするとコスパが良さそうかを洗い出しました。
優先度が高い実装をutgwに任せ、実装を後ろから見つつ、別の改善点を探していました。実装に必要な変更を洗い出したり、utgwの実装の取っ掛かりになるミニパッチを投げたりしました。

実装を読んだ感想と実際の悪さがおおよそ一致していたこと

分析なくては改善はなしですが、改善方法が明らかなものが沢山あるのがISUCONです。
メトリクスも参考にして、絶対に効果があるだろうと実装するものが、ちゃんと通ると時間的には嬉しいです。

個人的な反省点とやり残し

flockをsync.RWLockにしてスコアが下がったこと

flockをRWlockにするのは、実装を見て問題なさそうでした。トランザクションのないデータベース更新が走るときだけ、ブロックしたいという話に読めました。そのため、flockをgolangのsync.RWLock実装に置き換えました。
しかし、ベンチを走らせると、reductionでスコアが下がる結果になりました。負荷低減のために、player_scoreの更新に合わせてキャッシュを返せば、更に高スコアが狙えたと思います。
player_scoreをバッチ更新にしてアトミックにする作戦もやり残しました。

dispenseIDの乱数置換

dispenseIDが乱数だとベンチに怒られました。他の改善をしているうちにデータベースの手が空いて、ボトルネックではなくなっていたので、実装予定をキャンセルしました。

CSVのパースの高速化

最初の方にひらめきましたが、流石にボトルネックになるまでは迫れませんでした。やる必要がないと判断することも大事ですね。