ISUCON12 参加記

Sun Jul 24 2022

7/23 (土) に開催された ISUCON12@nakata_k2, @zaburo_ch と参加しました。結果は12,286点で68位でした。 普段特に web サービスをいじっているわけではないのですが、最近バックエンドの知識を身につけたい機運が高まっていたのと何より楽しそうということで会社の人を誘って参加することにしました。一緒に出てくれたみなさんに感謝です。 この1ヶ月は ISUCON 周りの勉強をすることが多く慣れない分野で大変疲れましたが、非常に勉強になりました。 来年リベンジするときにこの1ヶ月間でやったことを思い出せるようにするため、今回の ISUCON に向けてやってきたこと&当日やったことをここにまとめておきます。 特に ISUCON12 についてはネタバレが含まれているのでご注意ください。リンクを貼っている各種メモもネタバレ豊富です。

当日まで

1ヶ月前

とりあえず知識を詰め込むため、 ISUCON 本 を読みました。 読んだときのメモは こちら

この本のおかげで ISUCON で何をすればいいかの全体像を理解できました。これから ISUCON 始める人にはとてもおすすめです。

3週間前

ISUCON 本でも取り上げられていた private-isu を一人でやってみました。 取り組んでいたときのメモは こちら

極力 ISUCON 本を見ないでどん詰りしてしまったときだけ ISUCON 本の付録を見るという形式でやりました。1週間かけてじっくりやっています。実際に手を動かすことで改善サイクルを回すノウハウみたいなのが体に染み付きました。 デプロイとかは極力自動化するようにしていました。本番も使えるように、という意図だったのですが、後にチームの人が最強のデプロイスクリプトを作ってくれたので本番はそっちを使いました。

あとは golang の勉強になりました。普段使っているのは python、たまに typescript という感じなので golang は慣れていません。 webapp の golang 実装を眺めつついろいろ調べることで書き方に慣れていきました。

最終的には223,607点で終了しましたが、本では320,000点ぐらい出ており、何が足りていないか最後まで不明でした… golang の template が遅そうな気配を感じています (本は ruby 実装なので)。

2週間前

チームの人で集まって ISUCON11 をやろうとしました。 最初は こちらの記事 を参考に、さくらの環境でやろうとしたのですが、ベンチを回しているうちに「アプリケーション互換性チェックに失敗しました」というエラーが出始めてしまいました。あれこれ試しましたが解決することはなく、不毛な時間が続いたので諦めました。 とはいえ練習のために集まっているので何かやりたいということで今度は ISUCON10 をやろうとしました。これも こちらのレポジトリ を参考にさくらの環境でやろうとしたのですが、必要なファイルが適切に展開されておらず正しく動かないような挙動をしていました。何のファイルが足りてないか探し出して直そうとしたのですが、これも不毛な時間になってしまったため諦めました。 最終的に こちらのレポジトリ にある AMI を使ってAWS 環境で動かしたところ上手くいきました。しかしここまででかなり時間を使ってしまったので1週間後にまたやりましょうということで解散しました。

その後個人では ISUCON11 を練習しました。 取り組んでいたときのメモは こちら

はじめのうちはベンチと webapp サーバーを分けてインスタンスを建てることが上手くできず、共存している形でやっていました… ですが途中で CloudFormation を使えば3台+ベンチ構成が簡単にできるという話をチームの人から聞き、移行しました (これ を使いました)。 数日かけたところ690,427点まで伸び、これは予選5位相当です。このあたりで、3人で上手く作業分担し改善サイクルを手早く回せられれば予選突破狙えるなと感じてきました。

1週間前

チームの人で集まって ISUCON10 をやりました。作業メモはありません。 数時間延長はしましたが、最終スコアは6,010点で予選2位相当です。

あとはいかに実装を早くすればいいかというフェーズに入ってきたと思い、 SQL や golang を書く練習をしていました。

前日

そわそわが止まらなかったので スニペット的なもの を書いてました。当日は全然使わなかったです…

当日

さて本題です。

9:30-10:00 (競技開始前)

起床成功です。ライブを見てました。

10:00-11:00 (約2,600点)

CloudFormation でインスタンスを建てる、ログを仕込む、デプロイ自動化スクリプトを ISUCON12 用に書き換える、あたりをやってました。11:00頃にはボトルネックがエンドポイントごとに特定できて、

  • GET /api/admin/tenants/billing
  • GET /api/player/competition/:competition_id/ranking
  • GET /api/player/player/:player_id

あたりが遅いことがわかりました。 ベンチを何回か走らせたところ、体感2,600点+-200点ぐらいでした。それぐらいは誤差がありそう。

11:00-12:00 (約3,200点)

このあたりの時間はまだマニュアル的な動きをしていました。

  • mysql を別マシンに移行
  • デプロイスクリプトの完成
  • pprof を仕込む

スコアに効いたのは mysql 移行ぐらいだと思います。

sqlite のせいで webapp サーバーを複数台に分けられない、 pt-query-digest が使えない、 EXPLAIN の見方がよくわからないといった問題点を感じ始め、 sqlite -> mysql への移行を考えたがぱっとできなそうということで一旦断念しました。

12:00-13:00 (5,084点)

  • GET /api/admin/tenants/billing を速くするため、 visit_history table に tenant_id, competition_id の index を貼る (約3,400点)
  • dispenseID 関数で DB を使うのではなく UUID を返すようにする (5,084点)

あたりをやりました。

13:00-14:00 (5,630点)

  • visit_history table から oldest な情報のみ持つ oldest_visit table を作り、それを billingReportByCompetition で使うように変更

この時間にスコア改善につながったのはこれだけですが、ここで予選突破圏内まで順位が浮上しテンションが高まったのを覚えています。 このあたりから sqlite -> mysql への移行をやっていこうという話になりはじめました。地獄の始まりです。

14:00-16:00 (変化なし)

sqlite -> mysql をずっとやっていました… sqlite のデータを mysql へ移行することがようやくできそうとなったあたりで「initialize どうするの?時間内に終わらなくない?」という話が出てきて、大変そうとなって諦めました。もっと早く気づくべきだった。あと2時間…

16:00-18:00 (約11,000点)

  • POST /api/organizer/competition/:competition_id/score の INSERT を bulk insert にする (7,537点)
  • いろいろと memcache (あまり把握できていません) (7,860点)
  • GET /api/player/player/:player_idrow_num の最大値を取ってくる部分を JOIN を使い N+1 を回避 (10,825点)
    • IN 句の扱いを golang 側でバグらせてどん詰まってました :dogeza:

といった感じで点数が伸びていきました。最後再起動試験を行ったところ約11,000点でした (最後の10分とかでやったので記録が残っていない)。 あと最後の最後で echo が debug モードで動いているのを直しましたが、これはベンチ回すのが間に合わず点数がどれだけ伸びたかは不明です。

感想

  • とにかく悔しい
    • 1週間は引きずると思います
    • 来年がんばります
  • 来年に向けて何を勉強すればいいんだろう
    • 今回みたいに慣れない問題環境 (例: sqlite) のときに適切なムーブを取れるようにしたいが、あまりいいアイディアが思いつかない
      • 経験が物を言いそう
    • 今回は予選の過去問のみ取り組んだが決勝のも取り組むとか
  • CTF と同じく競技時間24時間欲しい
    • 現状の8時間だと、初手で沼にはまらずぬるぬる動けた人が有利すぎる気がする?
    • 限界までチューニングするとしたらどういう技があるのかもっと知りたい
    • 運営が大変そうなので非現実的かもしれないですが
  • 当日のライブで流れていた isuports の紹介動画、結構好み
    • リアル脱出ゲームの OP にありそうな映像だった
  • AWS のインスタンスはこまめに切ろうね
    • ISUCON 関係で合計1万円ぐらい課金してしまった…