はじめに
ポート株式会社 サービス開発部 Advent Calendar 2023 7日目の記事です。
ポート株式会社 サービス開発部でバックエンド〜インフラ周りの開発をしている井上です。
11月25日に開催された ISUCON13 に会社の同期と初めて参加したのでその体験談をまとめようと思います!
メンバーは会社の同期との2人チームで「西新宿电子厂厂姐妹花」というチーム名で参加しました。
結果は、最終スコアが 9,804点
で、順位は 258位/661チーム
でした!
参加した動機
ISUCON の目的はパフォーマンスチューニングで Web サービスを高速化することですが、私が今回参加した目的はインフラ周りの理解を深めることでした。
ISUCON ではバックエンド, インフラなどの幅広い知識が必要になるのでとてもいい機会でした。
準備したこと
申し込み
まず、参加するには申し込みが必要ですね。
ISUCON13 の申し込み期間は下記のように3回に分かれていたのですが、私が参加したいと思った時にはすでに第一期の募集が終わっていたので第二期で申し込みました。
- 8月30日(水)10:00〜 第一期 220枠参加者募集
- 9月4日(月)20:00〜 第二期 200枠参加者募集
- 9月9日(土)10:00〜 第三期 200枠参加者募集
- 9月下旬以降 キャンセル分の追加募集
次に、達人が教えるWebパフォーマンスチューニング〜ISUCONから学ぶ高速化の実践 という本が有名なので購入しました。
ここから ISUCON に向けた勉強を開始したので勉強期間は3ヶ月弱といったところですかね。
勉強内容
約3ヶ月という短い期間の中で業務片手間で勉強をしなければならなかったので以下の2点を意識して勉強しました。
- 本を全て読み切る時間はないので重要だと思えるポイントに絞って読む
- 過去の出場チームの結果を見ると失格やスコア0のチームが一定数(割と多い)いたので、チューニング以前のインフラ周りの設定や環境構築でつまずかないようにする
結果的に本番までにやったことは以下の通りです
- 本の必要な部分を読み、手を動かしながら理解する
- 必要な情報をググる
- AWS で VPC やインスタンスを作成して本番の環境を再現する
- デプロイ, ベンチマーク実行, 計測 & 解析の自動化のためにシェルスクリプトを作成しておく
- 同チームのメンバーに本番の流れやノウハウを共有するために Notion にまとめておく(いわゆる秘伝のタレ)
勉強方法
とくに重要なのは「手を動かす」ということだと思います。
購入した本は全300ページ以上あるのですが、しっかり理解して読み終えたのは半分くらいでした。
この本は 第1章〜第9章 で理論的な説明があり、付録A で実際に Web サービスを改善するという構成でした。通常、このような構成の本の場合は、第1章から順番に読み進め、最後に付録Aに挑戦するという流れになると思います。
しかし、できるだけ早い段階で付録Aに取り掛かり、全体の流れやチューニングのイメージを作っておいた方がいいです。その後、実践を進めていく中でわからない点が出てきたら、その都度前の章に戻って理解を深めるという方法が効率的だと思います。
本番でやったこと
9:00〜
レギュレーション(ルール)を把握
9:30〜
ライブ中継視聴、出題動画で問題設定を把握↓
10:00〜(開始後)
ここからが競技スタートです!作業は以下の流れで行いました。
初期準備
- マニュアルに目を通す
- 運営側が用意した CloudFormation テンプレートをアップロードし、競技環境を構築
- VPC やサブネットは自動で構築され、競技用の EC2 インスタンスは合計3つ起動しました
- SSH 設定
- 初回ベンチマーク実行
- スコア
4,135点
- スコア
ソースコード管理
ソースコードの管理対象はサービスのロジックに関わる部分(/webapp 配下)です。
ただ、/webapp 外のディレクトリに配置されている nginx や MySQL の設定ファイル等にも変更を加える必要があるので、当初は設定ファイルをコピーしたものをリポジトリに含め、元のファイルにはシンボリックリンクを置く方法を試みました。
しかし、この方法だと設定内容が反映されなかったので、/webapp 配下は GitHub で管理しそれ以外はインスタンスに SSH で入り直接変更するという力技で乗り切ることにしました。
ここで行った作業は以下の通りです。
- プライベートリポジトリを作成
- 渡されたインスタンスのうちの1つに SSH で入り /webapp 配下をリポジトリに push
- これ以降この1つのインスタンスに対してのみ変更を加えていき、残り2つは完全に放置しました😇
※ リポジトリをパブリックで作成すると他のチームが閲覧できてしまうので失格になるらしい。。
開発言語の切り替え
初期実装が Go だったので Ruby に切り替え
11:00〜
シェルスクリプトの設定
- ベンチ実行
- スコア
3,687点
- スコア
- デプロイ, 計測 & 解析の自動化のために事前に用意していたシェルスクリプトを GitHub に push
- ベンチ実行
- スコア
4,142点
- スコア
スロークエリの出力設定
- スロークエリを解析できるようにするため、MySQL がログを出力するように設定
- ベンチ実行
- スコア
3,811点
- スコア
計測ツールの設定, インストール
- アクセスログの出力設定
- アクセスログ解析のため alp をインストール
- スロークエリ解析のため pt-query-digest をインストール
- ベンチ実行 & topコマンドで観測
- スコア
3,800点
- スコア
12:00〜
インデックス追加
これ以降は以下の作業を繰り返しました。
- pt-query-digest でスロークエリ解析
- ボトルネックとなっていそうなテーブルにインデックスを張る
- ベンチ実行
- スコアが上がってなければインデックスを削除して元に戻す、上がっていれば 1 に戻り次のスロークエリを探す
ちなみに初回のインデックス追加でスコアは 5,809点
まで上がりました🎉
13:30〜
お昼休憩, マックを食べる
お昼休憩はちゃんと取りましょう🍙
ちょうどこのころ運営側で障害が発生しベンチマークが使えなくなってました。たまたまですが、この時間を休憩時間に当たられたのは良かったです。
今後もこのような事象が発生したときは休憩に入ってしまうのがいいと思います。
14:00〜
引き続きインデックスが張れそうな箇所を探して改善していきます。
15:00〜
N+1 解消
後半はインデックスが張れそうな箇所が減ってきたので N+1 の解消にも着手しました。
初回の N+1 解消でスコアは 7,736点
まで上がりました!
17:00〜
段々と打てる手数が少なくなっていき、ラスト1時間は設定類を元に戻すことくらいしかできませんでした。
スロークエリ出力設定を元に戻す
スロークエリの出力で MySQL の負荷が多少上がるらしいので、設定を元に戻しました
- スコア
9,281点
アクセスログの出力を元に戻す
同様にアクセスログの出力も元に戻しました
- スコア
9,804点
スコアの推移
長すぎて少し見切れている部分がありますが、最終スコア 9,804点
まで改善することができました!
感想
練習の段階では CloudFormation を自作して学習環境を整えたり、シェルスクリプトを作成してデプロイ, ベンチマークの実行, 計測 & 解析を自動化できたのでインフラの理解がかなり深まりました。
ただ、本番では用意された CloudFormation をアップロードするだけでよく、ベンチマークの実行も GUI 操作だったためここまで準備する必要はなかったかもしれません。
ISUCON 前夜は文化祭のようなワクワク感があり、社会人になってもこんな経験ができるんだと感心しました。また、当日は幅広い技術力とチームワークなどエンジニアとしての総力が試されているような感じで、とても貴重な経験ができました。
来年も参加しようと思います!