チーム「ウー馬場ーイー2」でISUCON11予選に参加し総合8位で本選進出しました #isucon

今年も例年通り @matsuu@ishikawa84g と参加しました。

去年のチーム名は「ウー馬場ーイーツ」。今年は「ウー馬場ーイー2」。 とにかく申し込み競争が熾烈だったので、申し込みの時にさっと命名したところ、そのまま進捗いたしました。

結果は総合8位で本選進出!
ISUCON11 オンライン予選 予選結果と本選出場者決定のお知らせ : ISUCON公式Blog

役割分担はこれまたいつも通りこんな感じ。

  • @matsuu バリバリ実装する前衛
  • @ishikawa84g サイトやレギュレーションやコードやログやDiscordを見る情報官
  • @netmarkjp 司令塔

作業環境

各自自宅で。

音声はDiscordでつなぎ、画面共有はそれぞれVOD NinjaでPrivate配信してました。

わたしはディスプレイ4枚体制。

  • M1 MacBook Air本体ディスプレイ:チームメンバーに共有
    • 外付け27inch:調べ物などもろもろ(メインディスプレイ)
    • iPad Pro 12.9(Sidecar):Discord
  • ThinkPad T495s:メンバーのディスプレイを見る用

特に問題なく快適に作業できました。

最終構成

アプリはgo実装(1.17に変更)で、競技時間終了時点のスコアは388,657。

最終スコア(運営側で計測)は38,9509でした。
ISUCON11 オンライン予選 全てのチームのスコア(参考値) : ISUCON公式Blog

ソースコードはGitHubに都度pushしてます。

matsuu/isucon11q

最終構成はサーバ3台体制でした。

  • 01: nginx・varnish・app
  • 02: MariaDB
  • 03: app(iconやinitializeに関わらないエンドポイント用)

振り返り

今回もとっても良問でした。

基本のワークフローが気持ちよく回せて、とても楽しかったです!

  1. kataribe・pt-query-digest・top・dstatを使ってボトルネックを探す
  2. ボトルネックに対処する
  3. スコアがあがる

今回はGitHubにスコアつきcommit historyがあるので振り返るのがらくちん。

Commits · matsuu/isucon11q

※とはいえ記憶違いで事実と異なることを書いてるかもしれません

ISUCON初回から参加してる勝手知ったるチームメンバーなので、さすがに役割分担で戸惑うことはありません。

とはいえどうしても目についたもの、気になるところ、できるところ、仕掛ったところに時間を割きがちなので、司令塔としては都度声をかけて「 いま なにをやるべきか」を確認し行動した/行動を促せたのがポイントでした。

序盤

まずはとにかくしっかりレギュレーションを読む。 @ishikawa84gが重要なところに線を引いてGoogle Driveに置いてくれました。

go実装の初期スコアは2,974。

序盤はCPUネック(MariaDB)だったので、pt-query-digestの結果を見つつインデックスを追加。 その他にgoとDBの接続まわりを調整してスコアは16,664。

(見返したら、このとき張ったインデックスは一部カラムを間違えてた)

MariaDBの負荷軽減のために POST /api/condition/:jia_isu_uuid のINSERTをbulk insertに変更したり、 appの負荷を下げるためにassetsをnginxからの配信に変更したり。

引き続きMariaDBの負荷軽減のためにクエリ負荷削減を狙って、不要な列や行を取得しないにように変更して取り組んでスコアは20,127。

その後、クエリ発行数自体を減らそうとvarnishを導入。 そうこうしているうちにインデックスの貼り間違えに気づき、修正したところでスコアは37,019。

改めてvarnishをきちんと設定し GET /api/trend を0.8秒キャッシュしたところでスコアは44,034。

ここで12:00ちょい過ぎになり、お昼ごはん。

中盤

相変わらずCPUネック。

pt-query-digestの結果を改めて見直してインデックスを追加。 go - MariaDBのconnection設定も見直してスコアは47,807。

ここで少し行き詰まっていたので改めて仕様を確認。 トップチームのスコアがぶち抜いていたので、いまのアプローチの先にそのスコアがあるか考えて、変化球を繰り出すことにしました。

IoTテーマだし、データ欠損上等な仕様と判断して POST /api/condition/:jia_isu_uuid でPOSTされたデータのうち 最後の1件だけをINSERT するようにしてみました。 これがぷちブレイクスルー。

(とはいえ本当はデータをたくさん取り込んだほうがスコアがバシバシ上がるって認識していたんだけど、うまく対策できず)

同時にdropProbabilityを0.9から0.6に下げてリクエストをたくさん回すように変更してスコアは72,178。

さらにMariaDBの書き込み設定まわりを変更して79,819。

その後にiconをnginxからserveするよう変更してみたもののスコアが伸びず、少し早いけど14:30に構成変更を開始。

後半

web-dbの2台構成に変更したことでスコアは146,710。

余計なログ出力を減らしたりnginxでexpiresを設定したりで182,239。

さらにnginxを調整して208,386。

ここでまた構成変更。最終構成と同じつくりにしてスコアが269,411。

  • 01: nginx・varnish・app
  • 02: MariaDB
  • 03: app(iconやinitializeに関わらないエンドポイント用)

スコアWorstを積み重ねる作戦で逃げ切れるか怪しい雰囲気が出てきていたのでBadくらいまで引き上げられないかと、 POST /api/condition/:jia_isu_uuid のデータ取り込みを最後の1件から最後の6件に変えてみたりしたものの不発。

これで16:52。

終盤

ラスト1時間なので大きな変更はせず、最終確認と調整を開始。

3台構成の状態でエンドポイントごとに1,3に振るか1だけに振るかを調整。 さらにdropProbabilityをいろいろ試して0.6→0.9にしたらスコアが伸びて、これでスコアは379,417。 この時点で17:03。

ここまでくると、あとは細かい調整をしながら再起動試験をして終わり。 というわけで、Ansibleで同時に再起動かけるという話のようだったので、 tmuxのsynchronized-paneを使って3台同時に再起動するテストを重ねて時間切れを迎え、、、

と思っていたらまさかの時間延長+0:45。 さらに18:00を少し過ぎたところで@matsuuにエスカレーション。

延長分は有効に使えず、最終計測は18:39の388,657でした。

18:00に終わってくれていれば!!!って思ったよね。

まとめ

@matsuuも書いてくれたのでご参照ください

ISUCON11予選でチーム ウー馬場ーイー2 として参加し、本選進出を決めました - Gマイナー志向

齟齬がある場合、たぶん@matsuuのほうが正しい。

さて。本選がんばるぞ!

Event 

See also