この記事は クラウドワークスグループ Advent Calendar 2024 シリーズ1 の 23日目の記事です。
エンジニアをしている @sunakan です。
2024年12月8日(日)にISUCON14がありました。
会社の同僚と2人チームで、ISUCONに初参加しました。
この記事はISUCON初参加の振り返り・反省・感想になります。
ISUCONとは
当日お題となるアプリケーションを高速化してスコアを競う大会です。
スコアはISUCON用のベンチマーカーが用意されており、どこのボトルネックがスコアに繋がるかは毎年変わりそうです。
また、他の項目としては以下のようになっています
項目 | 内容 |
---|---|
賞金 | 100万円※ |
時間 | 10:00~18:00(8h) |
人数 | 1~3人で1チーム |
言語 | 当日いくつか用意されている(例:Go,Ruby,...etc) |
参加方法 | 2ヶ月前くらいに参加登録イベントがあるので、チームの代表がそれに登録する(メンバーは後で調整可能) |
※3位までは賞金が出たり、企業賞や言語賞もあったりなかったりします。詳細は isucon14の受賞チームおよび全チームスコア をご覧ください
素振り・学習方法
主に学習方法として以下の方法を取りました。
- 過去問の他の方の回答コードを読んで真似る
- 達人が教えるWebパフォーマンスチューニングの勉強会へ参加
結果:追試によりFAILでした(スコア:2,333)
終了してからしばらくは540位くらいだったのですが、追試で落ちていました。
競技に利用したリポジトリ
競技中の戦略やツール等
インメモリキャッシュを積極的に利用
過去問の他の方の回答で勉強していると、「インメモリキャッシュ強すぎない?」というお気持ちになり、ガンガン使っていこうということにしました。
しかし、追試でFAILになっていました。
原因は「6.データ保持NG : 追試における負荷走行により作成されたデータが、再起動後に取得できませんでした」 とのこと。ちゃんとDBにもINSERT/UPDATEをしていたつもりですが、もしかしたら ON UPDATE CURRENT_TIMESTAMP(6)
でインメモリキャッシュがうまくいかなかったかもしれません。(細かい原因は特定できずじまいです)
Go言語を採用
近年のISUCONではGo言語の利用率が高く、テクニックなどはGo言語を前提に説明されている記事が多く、素振りもGo言語で行っていたためです。
そのため、本番もGo言語で対応しました。
モニタリングツールは利用無し
NewRelicなどは、メトリクスの取得間隔が大きいのでやめました。
Prometheus等を利用してCPU使用率の取得などを検討していましたが、準備不足でやめました。
ログやスロークエリを分析するのに alp
と pt-query-digest
を利用
達人が教えるWebパフォーマンスチューニング でも紹介されていた2つのツールを使いました。
理由としては勉強時も同ツールを使っており、慣れていたためです。
各種ツールに関しては、説明を省きます。
振り返り・反省
1時間で目標の1回目のベンチマークを回せた
最初はお決まりのことをするので準備がしやすく、最初の目標である11:00までに1回目のベンチマークを回せたのは良かったです。
もっと自動化を駆使して30分くらいで1回目のベンチマークを回せるようにしたいです。
モブ形式ですると尚良かったかもしれない
戦略的にインメモリキャッシュを多用するつもりでしたので、最初から分業でやっていました。(結局はそれが原因で、追試にFAILしていましたが)
インメモリキャッシュのプログラミングで夢中になってしまい、もったいなかったです。
せっかくのチーム戦で初参加でしたので、1手1手丁寧に確認しながらできると良かったなと振り返って思います。
インメモリキャッシュ用のコードのデバッグに時間をかけすぎた
DBに都度クエリを発行せずに済むように、メモリにデータを保存しておくインメモリキャッシュは最初から戦略に入れていたものの、ベンチマーク前のデータの整合性がおかしかったりして、printデバッグで時間を溶かしてしまいました。
次はもっと練度を上げて臨みたいです。
最後の仕上げとしてログをOFFするのを忘れていた
スロークエリログなど、チューニング用にログ類を有効化したままでした。
0点は回避したかったので、残り20分くらいは確実に点数が残るようにしたのはいいものの、ログを無効化するくらいはできたかなと思います。
DBのindexが効いてないことに気づいたのは終了30分前位で、原因は競技中はわからなかった
17:30頃(終了30分前)にpt-query-digestのスロークエリをEXPLAINしてみると、index貼ったはずなのに効いてないことに気づきました。
ローカルからリモートに対してindexを貼っていたのですが、DBに入って直接index貼った後ベンチマークを回すとindexがなくなっていることに気づきました。
原因は競技中わからずじまいでした。
競技終了後に DROP TABLE
がベンチマーク前の初期化時に行われていたことに気づきました。
indexはDBに直接貼るのではなく、マイグレーション用のSQLに貼るべきでした。
感想
難しかった & 疲れましたが、それ以上に楽しかったです。
オンライン参加でしたが、LIVE中継による参加者の熱量はとても刺激になりました。
次があることを願って、来年は入賞できるよう素振りをたくさんしたいです。