初参加のISUCON14で入賞したMIXIチームのやったこと
はじめに
本記事は 2024/12/8(日)に開催された ISUCON14 に対する MIXI チームでの挑戦の記録です。
大会に向けた準備や当日の取り組み、振り返りをまとめています。
記事の構成は ISUCON13 優勝者のチーム NaruseJun 所属のとーふとふ さんの記事を参考にさせていただきました。記事の構成のみならず素振り期間から当日まで大変参考になりました。
チーム
チーム名と由来
ISUCON14 のスポンサーとして MIXI が協賛することになり、スポンサー枠として 1 チームの競技参加枠をいただいたことで募集があったので応募して集まりました。
チーム名は iXiです。
由来は「MIXI
の ixi を使って M っぽいものを作っている」
メンバー
メンバーは社内の @riddle_tec さん、 @tsuba3 さん、 そして私 で出場しました。
全員、ISUCON 自体は未経験でしたが、全員がバックエンドエンジニアとしてのキャリアを持っていました。また、@riddle_tec さんと @tsuba3 さん はインフラエンジニアとしての業務経験もあり、とても頼もしいメンバーでした。
リーダーシップを取ったのは @riddle_tec さんで、チーム集めや戦略、スケジュールなどを組んでいただき、全体の進行を巻いていただきました。
結果
Go 言語で参戦し、最終スコアは 24,766点
で、834 組中 28 位でした!TOP30 位に入賞することができました!
スコアの推移は以下のとおりです。
全チームのスコアはこちらから確認できます → ISUCON14 受賞チームおよび全チームスコア
12 時~16 時はスコアが伸び悩む苦しい時間帯でした。
事前準備
事前準備として大会当日までに行った取り組みについて紹介します。
チームでの意識の統一
スポンサー枠で参加したため、各自のモチベーションやポテンシャルに差がある可能性がありました。
そこで最初に各自の得意分野の共有や、今回どこまでを目指すのか?を話しました。
得意分野・経験のすり合わせ
ISUCON に関わりのありそうな領域に対して、5 段階の習得レベルでそれぞれの得意領域をすり合わせました
↓ 実際に使ったテンプレートは以下です。
- 1: 知らない
- 2: ちょっと知ってる
- 3: 触ったことある
- 4: 少し得意
- 5: 得意
isucon 参加有無、歴 ない ない ない 今やってること ゲームサーバー Rails Go, Flutter Linux 3 3 2 Linux ネットワーク 3 3 2 ネットワーク、TCP/IP 4 3 2 Web サーバー(Apache/ Nginx) 3 3 3 DB (RDBMS) 2 4 3 DB (RDBMS)のチューニング 1 3 3 DB (NoSQL) 1 3 3 DB (NoSQL)のチューニング 1 1 3 Redis / Memcached 3 3 3 CI / CD (GitHub Actions) 5 4 3 AWS 4 4 3 DNS 3 3 3 Ansible 5 1 1 パフォーマンスチューニング 3 4 3 Go 5 5 5 Go pprof 3 4 3 Go trace 3 3 3
目指すところのすり合わせ
次に、目標をどこに設定するかについても話し合いました。
「やるからには上を目指す」、「エンジョイ」「とりあえず参加」の選択肢の中から、「やるからには上を目指す」という結論に達しました。
スケジュールの調整
目標を決めた後、本番に向けてどのようなスケジュールで調整していくか?またそれまでの役割分担について擦り合わせました。
- 共通の課題図書として『達人が教える Web パフォーマンスチューニング 〜ISUCON から学ぶ高速化の実践』を選定
- 複数回チームで ISUCON をやってみる
- 使えそうなツール探し、実際の準備
- スケジュールの調整や会場の手配
- ISUCON 環境の準備 などなど
以下は実際にやった打ち合わせや練習です。
日付 | やったこと | 時間 | 備考 |
---|---|---|---|
10/31 | キックオフ | 1 時間 | 自己紹介、目指すところ、コミュニケーション方法、今後の予定について確認 |
11/12 | private-isu に挑戦 ① | 3 時間 | とりあえずやってみる会 |
11/26 | private-isu に挑戦 ② | 5 時間 | ansible の環境などを整えて再挑戦 |
12/03 | 作戦会議 | 1 時間 | 当日の役割分担、持ち物や場所、作業環境などの打ち合わせ |
12/04 | ISUCON9 に挑戦 | 5 時間 | 役割分担をしながら着手 |
12/06 | ISUCON13 に挑戦 | 8 時間 | 本番と同じ設定で 10 時から 18 時まで模擬大会 |
大事にしていたのはやった後の 「振り返り」 です。事前準備から初動、中盤、終盤に至るまで毎度 1 時間程度かけてしっかりと問題点を明らかにし、次回までに解決することを決めていました。
例:N+1 対応に追われたが思ったよりスコア伸びなかったので、次回はキャッシュを多用しよう。そして、そのために共通的に使えるキャッシュの snippet を用意しよう。
といった感じです。
当日までの準備
- 当日の会場の手配
- モニター、ホワイトボード、空調などが揃っており、集中できる場所であること
- ターミナルに何を表示するか
- 大きなスクリーンに常時メトリクスを表示していましたが、そこで何を表示するか決めていました。各メトリクスを遡れるように dstat で CPU / Memory / Disk / NW IO をみておき、TOP 側でボトルネックとなるプロセスをみれるようにしていました
1 台目の dstat 1 台目の top 2 台目の dstat 2 台目の top 3 台目の dstat 3 台目の top
- 大きなスクリーンに常時メトリクスを表示していましたが、そこで何を表示するか決めていました。各メトリクスを遡れるように dstat で CPU / Memory / Disk / NW IO をみておき、TOP 側でボトルネックとなるプロセスをみれるようにしていました
- 持ち物
- 昼ごはん
- 表示用のパソコン準備
- キーボード
- GoPro (記録用)
- 当日用の Notion のテンプレート
- お互いにやることがわかるようにテンプレートを用意
- お互いにやることがわかるようにテンプレートを用意
実際に使ったツールの紹介
- リポジトリ
- いろんな設定類を GitHub Template として作成
- プロビジョニング / デプロイ
- Ansible
- ボトルネック測定
- Datadog (metrics / APM)
- alp
- pt-query-digest
- pprof
- 情報まとめ
- Notion
オンサイトで行ったため基本的にコミュニケーションは対面で行いました。
当日のタイムライン
9:00~10:00 (準備)
無事起床!
- トイレ
- 飲食物の用意
- モニターの接続や配信の準備
- デスクトップの整理
- 記録用の GoPro の設置
- やることの再確認
10:00~11:00 (初動) → 2086
-
環境構築
-
情報を Notion に集約
-
ドキュメント読み
-
初回ベンチ
-
サービスの UI をスクリーンショットで取る
-
Datadog を有効にする
-
キャッシュの対応
-
Nginx の秘伝のタレを仕込む
-
go-json に置き換え
-
スロークエリの結果を ChatGPT に投げて Index 文を作ってもらって貼る
Datadog の結果も参考にしながらボトルネックを特定していきました。
初回ベンチマーク後の Datadog 画面
11:00~12:00 → 3850
- appPostRides, appGetRides の N+1 解消
- secureRandomStr のロジックを修正
- access token のキャッシュ
- owner ID のキャッシュ
- MySQL を別サーバー へ移動
12:00~13:00 → 7157
- PaymentToken のキャッシュ
- Idempotency-Key の生成と設定を追加
- 外部決済 API:リトライ処理を指数バックオフに
- matching ループを並行処理に修正
13:00~14:00 → 7630
- 昼食を取る
- appGetNotification SSE 対応
14:00~15:00 → 7169
- chairPostCoordinate
- nearby N+1 修正
- chairPostCordinate の N+1 修正
15:00~16:00 → 8855
- matching アルゴリズムで苦戦
- chair notification の SSE 対応で苦戦
修正がうまくハマらず0点のベンチマークが続きました。
16:00~17:00 → 16425
- matching アルゴリズムで苦戦
- chair notification の SSE 対応で苦戦
- total distance をキャッシュ →16744 点
17:00~18:00 → 24766
- カーネルパラメータを追加 → 18000 点
- ネットワーク周りで TCP TIME WAIT が多かったのでそこを中心に調整
- MySQL のコネクション数を調整 → 22358 点
- 17:30 - 17:45 お掃除 →23900 点
- Trace, Logger などの不要なミドルウェア削除
- Datadog の設定削除
- pgo の追加
- キャッシュデータを読み込むように修正
- 17:45 - 17:52 コードフリーズ&ベンチガチャ →24766 点
終盤の Datadog のスクリーンショット
18:00 ~ 結果発表
予約していた焼肉屋へ行き打ち上げを行いました。フルフルで集中していた分、疲れ果てていましたががんばったあとの焼肉は最高でした 👍。
ダッシュボードが隠れる前の雰囲気では 30 位に入れるかどうかとても微妙なラインで、再起動試験が成功するかどうかの緊張感もありつつ結果発表を待っていました。
結果 28 位、ギリギリ入れて良かった!!
振り返り
準備から当日の振る舞いまでの一連の振り返りをしました。
チームとして共通して上がった部分を一部共有します。
よかったこと
- Datadog 用のコード準備、よく使うクエリやコードを用意できた
- チートシートの準備
- 作業手順の確立
- 自分のタスクに集中、重そうなところから改善できた
- コミュニケーションを取りながら作業できた
反省点
- タスクに時間をかけすぎた(SSE/マッチングアルゴリズム)
- 設定群をあまり吟味せずにとりあえず導入していた
- チーム内での情報共有ができていない部分があった
- ChatGPT 依存の改善で意味がわからなくなることがあった
- ChatGPT や他の AI ツールのチューニングについてもう少し工夫ができた
- 部屋の気温調整と太陽光対策
- 大会レギュレーションの把握と共有
- slow query やベンチマーク結果の自動管理準
また、1 位になった takonomura さんのISUCON14 ポジトリのコミットログを参考にしながら、1 位になるための動きがどういったものか非常に参考になりました。
むやみな改善をしていない点、自分たちが苦戦していた部分への対応方法、ドメインのロジックを理解していなければできないようなスマートな修正、および改善スピードなど、多くの発見がありました。
チームとしても個人としてもまだまだ練度が足りないことを痛感しました。
次回の抱負
1 位目指します!!!
いまのところ課題はたくさんありますが、狙っていきます!
筆者の感想
今回代表して記事を書かせていただきましたが、この結果はチームメンバーに大きく支えられた結果でした。
チームとして入賞できたのはとてもうれしいことですが、個人としては他のメンバーと比べて実力不足でやりきれなかった部分がありとても悔しいです。
さらにスキルを磨き次回の ISUCON ではより良い成果を出せるよう努力していきます!
おわりに
スポンサー枠として参加させてくださった弊社 MIXI、大会運営の皆様、様々な大会の共有記事を書いてくださった皆様、ありがとうございました。
そして、最後まで共に走り抜いてくださったチームメンバーの @riddle_tec さん、 @tsuba3 さん、本当にありがとうございました。
MIXI に興味を持っていただけた方、ただいま積極採用中です!ぜひ採用ページもチェックしてみてください ✨
Discussion