ISUCON11で初参加して予選敗退しました
ISUCON11の予選準備や当日のやったことをまとめたものになります
(ISUCONについてはISUCON公式Blogを御覧ください)
最終スコアは36878点で112位、予選敗退となりました😇
参加の経緯
自社の開発チームのインフラ担当から「みんな出場しようぜ!」という話になりました
存在自体は数年前から知っていましたが、いい機会だったの参加することに
(ちなみにISUCONは1~3人のチームなので5人の我々は年齢順でチーム分け)
メンバー
当日一緒に参加してくれたメンバー(全員初参加)です
ちなみに担当は何回か練習を重ねて各々がやってみたいジャンルから決めました
mm1338
- DB/App系担当
- 普段は開発チームのリーダーをしており何でもできる
sa9sha9
- DB/App系担当
- 専門はフロントで、ゴリゴリにNext.jsを書いている
rymiyamoto(自分)
- チームリーダー&infra系
- 普段はバックエンドでgoをいじってる
- リーダーになったのはその場のノリと年齢(私以外ふたりとも年下)
準備
運営さんからの手厚いサポート
運営さんの方で事前講習やハンズオン・またVTuberの方によるLiveなどが提供され、初参加ながらもかなり当日の動きややるべきことが見えてイメージがつけやすかったです
(運営に関わっていた方々には足を向けて寝れない)
練習
予選の1ヶ月前ぐらいから毎週休日のどれか1日に8時間確保して、もくもく会形式(オンラインで累計5回)で進めました
練習環境は予選がAWSだったのもありAWS上で構成しています
利用した参考実装の言語は業務でも使っているgoにしました
練習でやった内容としては以下
- 計測環境設定(new relicやらログ仕込み等)
- スロークエリ改善
- サーバーの役割分担
- ミドルフェア(NGINX/MYSQL)のパラメータ調整
事前講習等で学んだことをいざ手を動かしてやってみるとなかなかうまく行かず、結局ほぼ第9回予選の問題をやるだけで当日をむかえることとに...
この練習で溜まった知見はNotionにまとめて当日のTODOリストを作成しました
利用した過去問
当日
事前にオフラインでやるほうが進めやすいため、会社の会議室を使っていました
当日の問題
10:00~11:00
- 全員: 予選自体のマニュアルと問題のマニュアルが公開されたので読む
- Infra: マニュアルを読み次第、運営さんから配布されるテンプレートから環境構築
- App: 環境ができベンチ実行をして初期スコアをインスタンス数分実行
- Infra: サーバーのスペック確認
- App: アプリのgit管理
- App: ツール(
new relic
以外)導入
今回はEC2でインスタンスが c5.large
で3台提供されていたが、1台だけスコアが2.5倍弱違う現象が発生した(1台だけ3400点, 他は1300点ぐらい)
見たところ1台だけCPUが違っていたので、基本はそのインスタンを対象に改修することに
11:00~12:00
- Infra:
new relic
導入 - App: アプリ解析&ログ仕込み
- App: ローカル開発環境作成
12:00~13:00
- Infara: デプロイ環境の構築(スクリプトの作成)
- App: indexの追加
- App:
POST /api/condition/:jia_isu_uuid
のbulk insert対応
このときに作成したデプロイスクリプトが後の悲劇を生むことに...
追加したindex
INDEX idx_character (`character`),
INDEX idx_jia_user_id (`jia_user_id`),
INDEX idx_jia_user_id_jia_isu_uuid (`jia_user_id`, `jia_isu_uuid`)
INDEX idx_jia_isu_uuid (`jia_isu_uuid`),
INDEX idx_timestamp (`timestamp`),
INDEX idx_jia_isu_uuid_timestamp (`jia_isu_uuid`, `timestamp`)
INDEX idx_jia_user_id (`jia_user_id`)
この時点でのスコアが17076点
13:00~14:00
- App:
dropProbability
を0.8
に変更 - Infra: スクリプトがおかしいいので修正もろもろ
- App:
POST /api/condition/:jia_isu_uuid
の insertをgroutineにする - App: ↑効果なくrevert
- App: DB接続数を200に
このあたりから何をやってもスコアが伸びない...
13000~15000点あたりを漂う
14:00~15:00
- 全員: 利用していた会議室がエアコンをつけていたにもかかわらず暑すぎたので場所変更
ちなみにエアコンが効かなかったのは温度設定だけして満足して、起動していなかったことが原因と予選終了後に分かる😇
15:00~16:00
- App:
POST /api/condition/:jia_isu_uuid
の insertをオレオレキューワーカーでさばくようにする - App:
dropProbability
を0.7
に変更 - App: オレオレキューワーカーの最大数を10から200に
- Infra: DBの外部接続対応
ここでもスコアが前後するだけ
16:00~17:00
- Infra: サーバーの役割分担(nginx&app1台, app1台, db1台)
- App:
GET /api/trend
の修正
failしてスコアが0に...
アプリのログを見たところなぜかDBのhostが変わっていないことに気づく
そしてApp担当1人とInfra担当の私でログを仕込んだりして調査することに...
(もうひとりは引き続き改修)
17:00~17:30
ログを仕込んでも出力されず、永遠と悩み続けたところでバイナリが13時ぐらいから更新されていないことに気づく
→デプロイスクリプト内でgoのbuildがずっと実行できずに反映されていなかった(goコマンドのパスが死んでた)
13時以降のgoの改修はすべて反映されていないのである
この事実にこの時間に気づいたことでチーム内に絶望が漂うことになった...
そして17:30ごろにポータルの調子が悪くなり、閉鎖される
このとき競技時間の延長が示唆され、でかい改修のrevert準備を始めるようになった
18:00~18:45
18:10にポータルが開放され競技時間は18:45に延長される
- ちゃんとbuildし直してベンチを実行したがfailしたのでオレオレキューワーカーをrevert
- 再度ベンチで点数復活!(正確な数値は記録し忘れました...)
-
GET /api/trend
の修正を入れるもfailしたのでrevert -
new relic
の監視やログ出力を停止 -
dropProbability
を0.6
に変更 - 最後にベンチを実行して 35308点 でfnish!
- 再起動テストは時間的に無理だったので後は祈るのみ🙏
参加してみて
良かったこと
- 監視系の導入(
new relic
やログ仕込み等々)がスムーズだった - 上記もあり問題箇所の特定が早かった
POST /api/condition/:jia_isu_uuid
GET /api/trend
- 顔を合わせてやる分、相談や連絡がスムーズだった
悪かったこと
- 問題特定ができてものの改善があまりできなかった
- スコアがなかなか変わらないときの動作確認を怠っていた
- 作業が沼ったときの切り替えがなかかなできなかった
- 練習でやった内容を過信しすぎた
- 再起動テストしてない
最後に
自分のミスでトラブルが発生してしまったのでめちゃくちゃ悔しいです
ただ事前練習で実際に手を動かしていなかったらスコアが上がることはなかったと思います
練習は大事ですね
全体的に時間配分がよろしくなかったのもあるので、しっかり練習して来年こそはリベンジして本戦を目指したいと思います!
最後に運営に関わっていた方々に感謝です
「憶測するな計測せよ」が身に染みるISUCONでした!
Discussion