初参加でも大丈夫。 ISUCON14体験談
この記事は、ニフティグループ Advent Calendar 2024 25日目の記事です。
はじめに
みなさん、こんにちは。私は普段、ニフティライフスタイルで不動産サービスの開発をしています。先日初めてISUCON14というテックコンテストに参加してきました。
そもそもテックコンテストが人生初だったのでかなり不安でしたが、準備と練習を重ねた結果、なんとか上位50%にランクインすることができました。本記事では、ISUCON初心者がどのように準備を進め、どんなポイントに気をつければよいか、私の実体験を交えてお話します。
目次
ISUCONとは
“Iikanjini Speed Up Contest” の略で、お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトルです。
短時間でボトルネックを見つけ、改善し、スコアを競う形式で、インフラからアプリケーション、データベースまで幅広い知識が試されます。詳しくは公式サイトをご覧ください。
参加したきっかけ
「ISUCONやってみない?」と先輩に誘われたのがきっかけです。このとき、ISUCONについては全く知らず、実務でパフォーマンス改善を行った経験もほとんどありませんでした。しかし、Webサービスのパフォーマンス改善を実践的に学べる機会だと思い、即決で参加を決めました。
ISUCON参加前の私のスキル感は、JavaやKotlin + Springを用いたWebアプリの開発経験があり、簡単なシェル操作やSQLの作成ができる程度でした。
準備
チームを組もう
ISUCONは基本的に3人1組で参加します。私たちのチームは、私(バックエンドエンジニア)、先輩(インフラエンジニア)、先輩(バックエンドエンジニア)の構成でした。
特にインフラに詳しいメンバーがいると、環境構築やサーバー設定がスムーズになり、非常に心強いです。逆に、全員がインフラ未経験者だと、準備が大変かもしれません。
スケジュールを立てよう
当初は業務時間外でISUCONに参加する予定でしたが、通常業務と並行しながらチーム全員で学習時間を確保することは現実的ではありませんでした。
そこで上司に相談したところ、「パフォーマンスチューニングの知見を既存のプロダクトに適用する」という具体的な目標を設定することを条件に、業務時間内での参加が認められました。
本番2か月前から週3時間のオンライン勉強会を開始。全員が同じペースで学習を進め、疑問点はその場で解消するようにしました。これは本番を想定したコミュニケーションの練習にもなり、結果として本番での円滑な連携に大きく貢献しました。
インプットを始めよう
まず手に取ったのが、通称「黒本」と呼ばれる「達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践」です。最初はその分厚さに圧倒されましたが、基礎から実践的なテクニックまで網羅されていて、本当に参考になりました。
また、ISUCONではGoがデフォルトの実装言語として用意されています。触れたことがない言語だったため、基本文法の学習に時間を割きました。
ちなみに、Go以外にもphpやRubyが用意されていますが、いずれも未経験の言語だったためデフォルト言語のGoを選択しました。
過去問に挑戦しよう
インプットと並行して、ISUCON11の過去問に取り組みました。最初は何から手をつければ良いのか全く分かりませんでしたが、以下のポイントを意識した結果、効率よく取り組むことができました。
- レギュレーションを理解する(ISUCON11の公式ドキュメントを確認)
- アプリケーションを理解する(READMEをしっかり読む)
- ベンチマークの基準を把握する
- モニタリング結果を基にチューニングを行う
- 頻出コマンドを事前にまとめておく
- ソースコードをGitHubで管理する
特に重要だったのが、モニタリングを活用することです。私たちは「top」コマンドでベンチマーク中のサーバ負荷を監視し、「alp」コマンドを使い、負荷のかかっているエンドポイントを特定しました。
黒本にも書いてある名言「推測するな、計測せよ」は本当にその通りで、闇雲にコードやサーバの設定を変更すると、かえってスコアが下がる場合があります。そのため「モニタリングでボトルネックを見つける」「仮説を立てる」「検証する」というサイクルを回しながら改善を進めていくことが非常に重要です。
本番
目標
まずは「レギュレーション違反による失格を避けること」を心がけました。そのうえで、事前学習など、準備してきたことの成果を発揮し、できれば上位50%に入ることを目指しました。
実際にやったこと
- 当日のレギュレーションを確認
- 特に注意を払った項目は「競技終了後の再起動試験」です。どれだけスコアを積み上げても、インスタンスを再起動した際にアプリケーションが正常に動作しなければ失格となってしまいます。そのため、競技中盤と終了直前の2回、実際に再起動を行い、動作に問題がないことを確認しました。
- データベースのインデックスを貼る
- 過去問練習で何度も試した手法を適用し、特定のクエリの速度を大幅に改善しました。この調整でスコアが2000点上がりました。
- バックエンドへのポーリング間隔を調整
- あるAPIが30ms間隔という超頻度でバックエンドにリクエストを送る設計になっていたため、負荷を軽減するために1000ms間隔に変更しました。この調整でもスコアが2000点ほど向上しました。
- N+1問題の解決に挑戦
- 複数回クエリを実行していたAPIの改善を試みました。JOINを用いたクエリ統合を検討しましたが、動作に問題が発生し、完全な解決には至りませんでした。時間制約により途中で断念しましたが、原因の特定や改善アプローチの理解が深まり、大きな学びとなりました。
結果
結果は831チーム中344位。最高スコアは5,654点でした。目標としていた上位50%にも到達し、初参加でここまでの結果が出せるとは思っていなかったため、チーム全員で喜びました。
感想
学んだこと
- チームワークの重要性
個人の技術力も大切ですが、チーム全体での戦略や役割分担が結果に直結することを実感しました。 - モニタリングの有用性
モニタリングツールを駆使して、ボトルネックを特定し改善に繋げるプロセスが非常に効果的でした。 - 準備の大切さ
過去問や事前の学習が本番での冷静な対応を可能にしました。
反省点
- SQLチューニングの課題
特にN+1問題の解決に手間取りました。次回までにさらに理解を深めたいです。
- Go言語の習熟不足
基本文法の理解が不足していたため、初見のコードに時間を取られる場面がありました。
まとめ
8時間は長いようで、本当にあっという間でした。過去問に取り組んでいた時は挫折しそうになりましたが、本番では不思議と冷静に対応できました。やはり事前の準備が大切だと実感しました。
そして何より、自分たちの改善がスコアという形で見える化されたのが、とても面白かったです。今回の反省点をしっかり克服し、次回はさらなる高みを目指したいと思います。
ISUCONに興味がある方は、ぜひチャレンジしてみてください。初心者でも、しっかり準備すれば結果を出せる大会です。
最後に、今回一緒に挑戦したチームの先輩方、そして理解を示し、サポートしてくれた上司に心より感謝したいと思います。
掲載内容は、記事執筆時点の情報をもとにしています。