ISUCON9本戦で10万点を取るにはひたすらハードコーディングとN+1をすればよい

ISUCON9本戦の感想戦をやっていきました。最終スコアは105417点です。

github.com

最終的な avaiabledays は100。DB1台,Webアプリ1台。

f:id:CHY72:20191029072331p:plain

過去のISUCONは傾向としてトランザクションが本質になりがちな傾向がありましたが、 今回のISUCONの本質はハードコーディングとN+1でした。

TLDR;

  • ひたすらハードコーディングとN+1消しをすれば点数がどんどん上がる。複雑なトランザクションも必要ない。
  • このブログにはN+1以外のことも書いてあるが、それはあんまりネックではない。本質はN+1。
  • ただひたすらにハードコーディング作業とN+1消去作業をしましょう。

やったことまとめ

10000点くらいまでの過程は省略。

N+1

  • 各席毎にDBに問い合わせるのをやめて、対象車の予約を一括で取ってきてアプリ側で席を管理することでN+1を消す。
  • getAvailableSeatsの対象となる列車リスト(およそ10車)を予め取得してから問い合わせることでN+1を消す。
  • あいまい検索で前から順に16車両分回すN+1も消す。
  • 他にも細々としたN+1を消す。

train_masterのハードコーディング

  • そのままでは流石にハードコーディングできないので、本質的なデータだけ(Departureの時分/{東京京都大阪名古屋}のペア(6通り),TrainClass)をハードコーディングする。

train_timetable_masterのメモ化

  • 数百万通りの可能性があるのでオンメモリにはできないが、実際にアクセスされるのはそれより遥かに少ないのでメモ化する。

キャンセル処理

  • bulkする。

ログイン・サインアップ・getUser

  • 本質ではない。下記をするとほのかにスコアがあがる。
  • Cookieのuser_idのデコードに時間がかかるので、同じユーザーのクッキーのデコードはキャッシュする。
  • Userデータを https://github.com/Muratam/go-syncmapserver で管理する。
  • SHA256のハッシュの回数を10回から1回に減らす。規定はないので。

ほか

  • あいまい検索時に二重にvalidationしているのをやめる。
  • インデックスは貼った方がお得なのでちゃんと貼る。

残りできること

  • getAvailableSeatsは理論的には消せるので消す。
  • そろそろ接続が増えすぎてコネクションが辛くなってくるのでDocker外しをしたりNginxやMySQLのそういうパラメータをチューニングする
  • 外部サービスへの接続のTLSハンドシェイクが下手くそなのでプーリングする。
  • reservations/ seat_reservations もhttps://github.com/Muratam/go-syncmapserver で管理する。
  • 複数台構成をする。
  • これは予想ですが多分上記をやってavaiabledaysを366にすると 200000点くらいは出ると思います。

やらなかったこと

  • 席予約アルゴリズムの変更。やる必要がなかった。
  • ベンチがHTTP2になってくれたらもっと点数出るのになー。