開発^3

Web開発、宇宙開発、ゲーム開発の3種類についてつらつらと

ISUCON12予選の振り返り

TLDR

初期スコア (Python): 1717
最高スコア: 6500ぐらい(1台構成)

やりたいことはいっぱい思いつくけど、全然時間が足りないという感じでした。orz
計測 → 改善の1ループがかなり大きくなってしまったのが反省点。

振り返り

マルチテナント構成ということで最初からシャーディングを目指していたものの、やりきれなかったのが悔やまれるところ。
シャーディング通って3倍スコア……は間に合わなかったわけで、捕らぬ狸のなんとやらですね。

以前の予選で改善点が後の修正で不要になるケースに当たっていたので、シャーディングやってから色々やろうと思ったんですが、結局それに追われて他に手が出せなかったです。
定番のN+1やらインデックスやらがあまり出来なかったのがなぁ。

やれたこと

billing_reportテーブル作成

テナント毎のシャーディングをする上で、請求書だけはテナント横断で取らないといけなかったので対応。
ただ、関連テーブルが多くてこれだけでも割と時間がかかってしまった。
実際は先に以下のコミットを入れています。

SQLiteinitial_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シリアライズの問題もあって時間切れ。

やりたかったこと

インメモリキャッシュ

テナント毎のシャーディングが出来ればインメモリ戦略も取りやすくなるのでやりたかった。

SQLiteMySQLへの移行

DB性能や計測手段(pt-query-digest)を考えると初手で思いついたが、データが大きかったので前述の履歴系テーブルを消してからやろうと思っていた。
……ら、消すところまでで時間切れ。ぐぬぬ

JWTの鍵キャッシュ

細かい所だけど毎回ファイル読んでたので。

雑感

今回も8時間があっという間にすぎる、とても楽しいイベントでした!
(途中であきらめて)終了直前でもコード書いていたので最終コードはFailしていると思いますが、初期スコアよりは良くなったのでISUCON11のだめっぷりよりはマシでしたね。

ちょっと気になったのは、1つの問題を解決する際に、既存データと新規データ両方に手を入れないといけない所でしょうか。
1人チーム対策なのかもしれませんが、問題の根や解決方法はわかっているのに2回やらないといけないのが時間を奪いますね。