11/25(土)、ISUCON13に参加してきました。ISUCON初参加でした。 チーム名はtokiwaで3人体制、言語はGo、最終スコアは32,269でした。 その記録など書きます。
きっかけ
はじまりは2023夏ごろ。
当時はISUCONという名前だけは聞いたことあったものの、どんなものかはよくわからずでした。
普段業務で扱うWebアプリでそこまでパフォーマンス気にかけることが要件としてもあまりなく、このまま何も考えないままだとパフォーマンス・チューニングに関してのスキルは伸びないだろうなぁと漠然としていて。 業務外でもよいから向き合う場が欲しいと感じていたところでした。
メンバーの1人(nekootoko3)が社内Slackで参加しようかと呟いていたので、こちらから声かけて参加することに。もう1人(daisaru11)もその場で勧誘→即OKでメンバーが決まりました。
チームとしてもちろん初参加、メンバーはnekootoko3が1度経験あり、daisaru11・abekohは初参加になります。
準備
当日までにやってきたこと(自分以外がやったことも含む)を洗い出すと
- ISUCON 夏祭り 2023に参加・ハンズオン受講
- 参加登録
- 事前準備(Discord設定・AWS環境チェック)
- 達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践 読む
- 個人練
- デプロイ・計装のスクリプト・チートシート作成
- チーム打ち合わせ・練習
- 3回程度。初動の役割決め・過去問実際にやってみるなど
- メンバー紹介スライド作成
などなど。
練習環境はハンズオンでもおすすめされていた、
- private_isu
- ISUCON13予選
- ISUCON9本線
を利用しました。
チーム紹介スライド
10分くらいで作成。
意気込みはChatGPTで作成→それをすべて絵文字化して作ってもらいました。
https://chat.openai.com/share/5c198b4d-7413-4b66-8504-2f1ffcfdcc53
ツール
デプロイ・計装・チートシート関連はほとんど自分のほうで作成しました。 その時に利用したツールは以下の通り。
- Ansible
- デプロイなり計装なりなんでも。複数サーバに対してまとめて実行できるPlaybookを事前準備
- ほぼほぼChatGPTに書いてもらう→ちょっと修正、という流れで対応
- New Relic
- もろもろの計測。DBスロークエリ・遅いエンドポイントの確認など
- 業務で使ってるDatadog使いたかったけど個人で支払うには高すぎた。ISUCON支援プログラムがあったのでありがたく利用させていただきました
- Cloud Profiler
- Google Cloudの無料で使えるProfiler収集ツール。New relicだとGoのフレームグラフを見れないようだったのでこちらを利用。無料でシンプルで素晴らしい。
- tbls
- DBスキーマの構造を確認できるように。Goのシングルバイナリで1コマンドでMarkdownに落とせるので便利
- zerolog
- 慣れた構造化ログライブラリ
- エラーをNew Relicで確認できるように、New RelicのIntegrationと組み合わせて利用
- 若干ラグがあったし結局直接サーバ確認のほうが早かったかもしれない
- alp
- ISUCON定番ツール。New relicで見にくかったnginxのログ集計のために利用
もうひとつの定番ツールのpt-query-digestは用意していませんでした。 特定DBに依存した形にしない形で、かつNew Relicで見るもので十分じゃないかなーと考えたためです。今回みたく別プロセスでMySQL利用していたケースを拾えなかったので用意しておくとまた違ったかもとは思いました。
当日
当日やってきたことはざっくり、
- 3人で以下の作業分担
- nekootoko3: マニュアル・コード読んで理解・まとめ
- daisaru11: バックアップ・デプロイ準備・インフラ計装仕込み→内容キャッチアップ
- abekoh: Goの計装仕込み・DBスキーマアップロード→内容キャッチアップ
- 最適化(効いたもののみ)
- N+1潰し
- MySQLインデックス追加
- アイコン画像配信を最適化
- MySQL設定値変更
- MySQLの
isupipe
データベースを別サーバに - MySQLプリペアドステートメント無効化
- 計装外し・ログの無効化
といった感じです。 地道に1つずつ数千スコアが伸びていっており、最後の計装外しで+1万上乗せできました。
N+1潰しは最初自分も取り組んでいたのですが、Copilotよろしく一気に修正したあげく整合性通らない・1時間くらい詰まる、という失態を犯しました…一番の反省点。結局N+1はnekootoko3に移譲、自分は画像配信のところをやりました。
MySQLの移行などあれこれは全部daisaru11にやっていただきました。DNSの本質的な対応はできていないものの、サーバ移行したことで結果的にCPU負荷を分散させることでいい感じになったように見えてます。
途中、ベンチマーカーの不具合でベンチマークがすぐに動かない問題が発生して、整合性チェックがまわせず待っている間ひたすら目でデバッグするしかないみたいなことがありました。例年はこんなことは発生しない?当日の雰囲気はやはり参加してみないとわからないところですね。
感想
結果は、追試failしたチームを除き最終スコア上から61位、661チーム中・初参加チームと考えると上々の出来かもです。
とはいえ反省点だらけ。 N+1対応で詰まった問題は、ひとつは大きすぎる変更をしようとしたところ。ちょっとずつ動く状態を維持しながら、点数が変わらなくても変更をいれていく正攻法でいくべきだと感じました。あとはCopilotを信用しすぎないこと。
そのためにも整合性チェックを何度も回せる状態にしてTDD的に開発したいところ。整合性チェックだけ回したいという同じ意見が散見されたので来年はそれだけ動かす仕組みが入るかも? 入らないとすれば、GoReplyのようなツールでトラフィックをキャプチャ・自前でリクエストしなおす仕組みを用意できるとよいかも?
あとN+1潰しを何パターンも練習しておくのも大事だけど、楽に対応できる手順・ツールがあると良いかも。dataloaderのようにLazyLoading・キャッシュの仕組みを手順化できるアイディアが浮かんでいるので試したし。
スコアUPへの貢献はnekootoko3, daisaru11がほとんどだったので2人に感謝。冷静にどう対処すればよいか見極めて対応していく様が頼もしかったです。自分は当日はダメダメだったが、もろもろ準備頑張った点を自分で褒めておきたいところ。
ISUCON1回でも出てみれば満足かな、とは思ってましたが、悔やまれる点が多い・勝手がわかったので次はもっといける自信がある、といった感情があり次回も都合合えば参加したいですね。nekootoko3,daisaru11も同じような感想?のようなので来年もtokiwaとして参加できたらと思います。