ISUCON12予選の振り返り
TLDR
初期スコア (Python): 1717
最高スコア: 6500ぐらい(1台構成)
やりたいことはいっぱい思いつくけど、全然時間が足りないという感じでした。orz
計測 → 改善の1ループがかなり大きくなってしまったのが反省点。
振り返り
マルチテナント構成ということで最初からシャーディングを目指していたものの、やりきれなかったのが悔やまれるところ。
シャーディング通って3倍スコア……は間に合わなかったわけで、捕らぬ狸のなんとやらですね。
以前の予選で改善点が後の修正で不要になるケースに当たっていたので、シャーディングやってから色々やろうと思ったんですが、結局それに追われて他に手が出せなかったです。
定番のN+1やらインデックスやらがあまり出来なかったのがなぁ。
やれたこと
billing_report
テーブル作成
テナント毎のシャーディングをする上で、請求書だけはテナント横断で取らないといけなかったので対応。
ただ、関連テーブルが多くてこれだけでも割と時間がかかってしまった。
実際は先に以下のコミットを入れています。
SQLiteのinitial_data
を更新
上記のbilling_report対応の必要もあって、履歴系テーブルを集計してテーブル作成。
- admin側の
visitor_history
を集計して、tenant側のvisitor_history
を作成 player_score
を集計して、tenant側のplayer_score_summary
を作成
どちらも行数が多いので効くのは間違いないんですが、行数が多いだけに変換が長い長い。
1.dbが重いのもあって変換するのに10分以上かかっていた気がします。
変換終わればinitial_data
更新できるんですが、変換ミスで4回ぐらいやってしまいました。orz
やりかけで終わったこと
Host
ヘッダを見て3台を分散
Nginxで$host
を使ったifを書いて対応。分散はできたけど正常動作するところまではたどり着けず。
^[a-h]
, ^[i-q]
, ^[r-z]
で3分割しました。
ざっとエラー内容を見た感じでは /ranking
のTimeoutで減点されているだけだったのでプログラムはOKで、下記のキャッシュが効けば行けたんじゃないかと。
redisキャッシュ
コードは書いたものの、この時点でだいぶ時間が無かった。
JSONシリアライズの問題もあって時間切れ。
やりたかったこと
インメモリキャッシュ
テナント毎のシャーディングが出来ればインメモリ戦略も取りやすくなるのでやりたかった。
SQLite → MySQLへの移行
DB性能や計測手段(pt-query-digest)を考えると初手で思いついたが、データが大きかったので前述の履歴系テーブルを消してからやろうと思っていた。
……ら、消すところまでで時間切れ。ぐぬぬ。
JWTの鍵キャッシュ
細かい所だけど毎回ファイル読んでたので。
雑感
今回も8時間があっという間にすぎる、とても楽しいイベントでした!
(途中であきらめて)終了直前でもコード書いていたので最終コードはFailしていると思いますが、初期スコアよりは良くなったのでISUCON11のだめっぷりよりはマシでしたね。
ちょっと気になったのは、1つの問題を解決する際に、既存データと新規データ両方に手を入れないといけない所でしょうか。
1人チーム対策なのかもしれませんが、問題の根や解決方法はわかっているのに2回やらないといけないのが時間を奪いますね。