ISUCON 7 本選で負けてきました

毎年恒例の ISUCON 7 本選に参加して、惨敗してきました。

競技中の最終スコアが 19600 程度、これが再現できていれば7位だったのですが、実際の結果は fail で 0 点、過去7大会の予選と本選で一度も経験したことがないスコアなしでの終戦でした。

今回の問題はインフラ、ミドルウェア的にいじるところはほぼなく、nginx の設定は初期状態からいじらず (APIで返す websocket の endpoint を Go の TCP 5000 にしたので)、MySQL で最低限の設定をしたのみでした。チームメイトの @acidlemon, @handlename のコード修正を見守るばかりで、もっと能動的に動けたらなあ、という後悔もあり。

やったこと

  • m_items をメモリに持つ (handlename)
  • getStatusをtickerのときのみキャッシュする (acidlemon)
  • getCurrentTime のタイムスタンプをメモリにのせる (acidlemon)
  • roomごとに接続先ホストを round robin で決定 (handlename)
  • adding ON DUPLICATE KEY UPDATE をやめる (acidlemon, fujiwara)
    • pkey を auto increment で別に作成し、同一 time での INSERT をロックなしに可能にする
  • GetPriceとGetPowerをキャッシュする (handlename)

15時ぐらいに一時 24000 程度で暫定1位を取ったものの、ここからたまに通るけどたまに事後検証で fail する、というのが解消しきれず。

途中、math/big.Int の計算がとにかくボトルネックなのはプロファイリングで把握していたので、正確な計算を諦めて DB には float で持つ (そうすると SELECT sum(isu) で大量に転送しないでも合計の概算が得られる) というブランチは自分が並行で実装していて、これも 24000 程度。ただしこれも稀に fail するので最終的には採用せず。

acidlemon が確定値を cache することで adding の SELECT を減らす、というコードを1時間ほど書いていったものの、これの微妙なバグが全員で最後まで取り切れなかったので(取り切れていたらスコアももう少し伸びて至ろうなという雰囲気)、その後あれこれ細かいところを詰めたもののブレイクスルーはなく、終戦、という感じでした。

最後はスコア 0 で終わりたくないので直前に3回連続で通過していたコードで最終提出したのですが、結果的には fail でした。過去すべての大会でスコアを残せていた自分としてはそれがとにかく残念ですが、まあ仕方ないですね。

出場チームの皆様、ありがとうございました。優勝したチーム MSA (会社の同僚チーム) 、おめでとうございます!