💺

ISUCON11に初参加したらおもろかった

2021/08/22に公開1

この度、ISUCONにはじめて参加しました💺
ブログを書くまでがISUCONとのことで、忘れないうちに振り返りを残しておきます
具体的なスコア改善方法よりも、未経験から参加した時にやってよかったなと感じたことをまとめました

結果

Go実装にて最終スコア33750 、順位は130/529位で予選敗退でした
初期スコアから伸ばせれば御の字くらいに思ってたので、思っていたよりも健闘できてよかったです

https://isucon.net/archives/56021246.html

以下、試合終了までにあったことをメモっていきます

チーム編成

全員初参加でした
当初はkangaechuと2人の予定でしたが、共通の勉強会に参加していたmatchasongを締切直前に巻き込み3人となりました

  • yktakaha4
    • アプリとDB(インデックスとか)担当
    • 普段はPythonでWebアプリ開発
  • kangaechu
    • インフラ担当
  • matchasong
    • 初期環境設定とデプロイ・ベンチマーク実行担当

準備

以下のことをおこないました

合同で練習

Discordにリモートで数回集まって、過去の予選問題を解くことにチャレンジしました
GitHubでPrivateなOrganizationを作成し、当日のコードも含めここで共有する運用にしていました

https://github.com/isucon/isucon9-qualify

とは言っても全員ノウハウがあるわけではないので、分担して以下のようなことをやりました

  • kangaechu, matchasong
    • リポジトリの内容から3台構成のEC2環境を構築
    • 修正のデプロイやベンチ実行後のパフォーマンス計測用のシェルスクリプトを作成
    • DBサーバの分離や、MySQL・nginxの設定変更
  • yktakaha4
    • ローカルにてdockerで起動できる環境を構築
    • ひたすらアプリの修正

加えて、当日のイメージを掴むために、公式サイトのまとめから参加規約・予選レギュレーションの読み合わせなどもおこないました
https://isucon.net/archives/54704557.html

個人で勉強

まずWebサービスチューニングコンテスト ISUCONのススメという本を読みました
具体的な修正方法もそうですが、全体の大まかな流れや、どのような観点で性能改善に取り組めばよいかわかりやすくまとめられており、ありがたかったです
パフォーマンス計測のツール類も、コストをかけずに手元でも導入しやすいものが色々紹介されているので、そうした知識を効率的に入手するのにもよいとおもいました

次にISUCON9と10の過去問で、N+1の解消やインメモリキャッシュの導入などのアプリで完結できる高速化について色々挑戦しました
予選当日は、その時のリポジトリの内容をコピペして適用…という方法で進めたのですが、調べる時間を減らせて効率的でした

エディタはGoLandを使いました
普段PyCharmで仕事してるので慣れてるというのもありますが、データベースへの接続設定をしておくとSQL文字列に勝手にスキーマを充ててくれるのがめっちゃ助かりました
SSHポートフォワード経由でのアクセスも設定可能なので、本番でも環境構築を待たずにコード調査に入れるのが地味に便利と思います

Goは趣味レベルのツールやLambdaを幾つか作ったぐらいで初心者だったのですが、
静的型の恩恵を受けつつキビキビ動いてくれるので、書いててメッチャたのしかったです
また、過去問をやってると各種フレームワークやライブラリについてWebアプリとしての実装を見ることができ、それもよかったです

インデックスについては、USE THE INDEX LUKEを読んで勉強しました
はるか昔に一度テキストとして流し読みした時はあまり頭に入らず終わってしまってたのですが、
今回はISUCONの過去問で色々試しながら読んでいけたので前よりも納得してEXPLAINを読めるようになった気がします

その他、本戦出場者の方々のブログを読むなどしました
https://isucon.net/archives/55007694.html

当日

時勢的に若干はばかられましたが、拙宅に集合し適当に換気しながらやりました

お昼は近所の回転寿司のテイクアウトを頼んでおいて食べました🍣
本番中は買い出しにいくような精神的余裕は無かったので、よい選択だったと思います

また、終わった後は家の近いメンバーと軽く宅飲みしました🍺
ちょうどFUJI ROCKが配信されてたので、聴きながらお互いどんなことをやってたか説明しあっておもろかったです

同期でやったこと

最初の1時間は、3人で同期で以下を実施しました

  • 提供されたCloudFormationによるEC2の起動
  • 当日マニュアルの読み合わせ
    • わからないところはガンガン飛ばしました
  • Webブラウザからアプリを適当に叩いてみる
    • 開発者ツールもあげておき、どこでどのエンドポイントに通信が発生しているかを眺めました
  • サーバに置いてあるコード一式をGitHubに格納

上位勢の方々は全体感がわかっていると思うのでもっと効率的にできると思うのですが、
自分たちはメンバーごとに理解・認識のずれが起きないように、前提知識を揃える意味でやりました
結果的に、作業中に忘れてしまったことを適当に投げたら誰かが覚えててくれてるなど、認識の冗長化に役立っていたと思います

自分がやったこと

その後は、サーバ作業は2人におまかせして、自分はまずコードを上から読み、以下をやりました

  • アプリ観点で修正できそうと感じた箇所にTODOコメント
  • SQLを稼働環境のDBに投げて、スキーマ状態を確認 & EXPLAIN実行し、貼るとよさそうなインデックスをメモ

ベンチが取れるようになったところで、初期スコアの計測 -> インデックスを適用したコードでスコアを計測し、この後分担して作業が進めていけそうか確認しました
今回の問題の特徴として、インデックスを貼っただけでスコアが数倍伸びるポイントがあり、最初にそこを直すことができたので士気があがってよかったです

その後は、ベンチ実行後のログと採点基準を見合わせつつ、先ほど書いたTODO毎に修正PRを作っては確認…を繰り返していきました
コードを読んでいくと、わかりやすいN+1やイケてないスキーマ設計などが随所に配置されているのですが、
それらを適切に直した時にどのくらい点数が伸びるかはスコア計算のルールによるので、加点対象にならなさそうなところやリクエスト量や専有時間が少ないところは後回しにし、点数計算に直結するエンドポイントや、全体に共通してパフォーマンスに影響していそうな部分を優先することを心がけました

また、今回はアプリケーションコードを修正しているのは自分だけでしたが、kangaechuがインフラをいじったりDBやWebサーバの設定(これもGit管理していた)をいじっている場合があったので、
matchasongに計測依頼を投げて順次マージしてもらう運用にしました

全員初心者のため、誰かが何か作業している時に期待しない変更をしてしまい場が混乱する危険があったのでこの運用としていましたが、
自分としてはローカルのGoLand上でほとんどの作業を完結できたので、コンテキストスイッチが減らせて助かりました
また、点数を報告してもらうことでチームで一喜一憂でき、そうした意味でもよかったと思います

おわりに

来年もがんばるぞ!
https://twitter.com/yktakaha4/status/1429033580013899779?s=20

Discussion