12 月 8 日(日)に行われた LINEヤフー社が主催するパフォーマンスチューニングコンテスト、ISUCON 14 にチーム「// TODO: あとでちゃんとしたチーム名になおす」として @pinkumohikan, @msm____2)と一緒に参加しました。
最近はずっと参考実装の PHP 移植を担当していたため、選手としての参加は ISUCON10 以来 4 年ぶりでした。
そして、結果は 3 位入賞でした!やったー!
やったーーーーーーーーー!!! #ISUCON pic.twitter.com/4La0neiP6T
— おかしょい (@okashoi) 2024年12月8日
一方で個人としては大きく反省点の残る ISUCON でもありました。
関連:チームメンバーのブログポスト
事前練習
チームとして ISUCON への熱意が総じて高かったため、6 月からほぼ月一ペースで練習をしてきました。
- GitHub - okashoi/isucon12-practice-20240601
- GitHub - okashoi/isucon12-practice-20240601
- GitHub - okashoi/isucon13-practice-20240629
- GitHub - okashoi/isucon12-practice-20240720
- GitHub - okashoi/isucon11q-practice-20241005
- GitHub - okashoi/isucon13-practice-20241102
- GitHub - okashoi/isucon13-practice-20241124
これらの練習の中で
- 競技開始後の初動
- 役割分担
- コミュニケーションの取り方や意思決定に関する取り決め
をブラッシュアップさせていきました。
私はアプリケーションの改修と、レギュレーションや各種マニュアルを読み込みのふたつの役割担当に。
前者は N+1 の解消をはじめとする、アプリケーション改修がからむ改善をエンドポイント単位でやっつけていくお仕事、後者は各種ドキュメントから重要そうなポイントを把握しておき、チーム内に共有したり議論のときに提示するというお仕事です。
練習にあたっては、過去問の環境構築に private-isu や ISUNARABE に大いにお世話になりました。本当にありがとうございます!
当日やったこと
チームメンバーとは地理的に離れていることもあり、常時 Discord で通話をしながらのオンライン参加でした。
作業ログなどが見れる GitHub リポジトリ(issue)はこちらです。
issue を見るとわかりますが、実は最終成果物には私が書いたコードはほぼ反映されていません。
初動
競技開始後に各自練習どおりの初動をしたあと、私は各種ドキュメントを読み込んだ内容を以下のように issue の形でまとめました。
通知を受け取るための polling 間隔を調整
初期状態での kataribe の結果で GET /api/app/notification
, GET /api/chair/notification
の通知系エンドポイントが Sort By Total のトップに来ていました。
ドキュメントから得た知識をもとに「いきなりアプリケーションを改修する前に、ほぼノータイムで試せる polling 間隔を伸ばすのをやっちゃえばいいか?」と考え、デフォルトの 30 ms から 500 ms に変えたところ(他メンバーが進めていた index チューニングやサーバ分離と合わせて)スコアが 8,500 点近くまで伸び暫定 1 位に躍り出ました。
通知を SSE(Server Sent Event)に載せ替え(着手後すぐに中断)
引き続き通知系エンドポイントが Sort By Total のトップに来ていたため、そのまま通知系エンドポイントのアプリケーションの改修に乗り出しました。
マニュアルによれば通知は SSE(Server Sent Event)に置き換えてよいとされているため載せ替えを試みます。
これまで SSE の実装をしたことはないため ChatGPT の力を借りつつ雑に載せ替えてみましたが、初手ではベンチは通らず。
後述の通り、深追いはせずこの載せ替えは中断します。
椅子の総移動距離を保持しておく(失敗)
私が SSE への載せ替えをしている間、pinkumohikan によるマッチングアルゴリズム改善がヒットしてチームのスコアが 35,000 点を超えていました。
このタイミングでお昼ごはんタイムを兼ねながらチーム内で状況確認と議論。
私は前述の SSE への載せ替えを劣後させて、slow query トップに来ていた GET /api/owner/chairs
エンドポイント内のクエリを改善する方針へ転換しました。
しかしここでも大いに苦戦し
- ベンチが通らなかったり
- 別の施策とコンフリクトしてその解消をしたり
- ベンチが通ってもエラーが多発してスコアが下がったり
といったことをやっている間に競技終了時間を迎えてしまうのでした。
反省など
まず、3 位という結果を達成できたこと、これはチームメンバー 2 人の力によるところが大きく、純粋にすごいなという称賛と感謝の意を伝えたい。ありがとう。
そして 3 位入賞自体は嬉しかったものの、個人としては施策を満足に反映できなかったため反省が大きく残る ISUCON だったな、とも感じています。
「ドキュメントを読み込んでチームメンバーに適宜アイデア出しや指摘をする」という動きはしていた(つもりである)ものの、やはり技術力という意味ではチームメンバー 2 人の力によって成されたものだと認識しています。
自身の課題としては
- Go 言語を書く筋力が足りていなかった(まだ調べながら書くケースがしばしば)
- MySQL の Window 関数について理解が不足していた
- 自分の施策に集中してチーム内の他の施策を負いきれていなかった
などが挙げられます。
こういった反省が浮き彫りになることもまた ISUCON 参加の意義だなあ、と 4 年越しに感じるのでした。
感想
今回の問題はやることがたくさんあって「次何やればいいかわからない」という状態にならなかった、解いていて楽しい良問でした。
また、ベンチマーカーもエンキューから実行まで待つことがなく快適でした。
運営のみなさま、作問の NaruseJun チームのみなさまありがとうござました!