💺

ISUCON14に参加しました

2024/12/01に公開

これは、LAPRAS Advent Calendar 2024の10日目の記事です

https://qiita.com/advent-calendar/2024/lapras


この度、12/8(日)に開催されたISUCON14に参加しましたので、備忘録を残したいと思います💺

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

結果

Go実装にて最終スコア8319 、順位は210/831位でした

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


最終スコア


点数の推移

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

チーム編成

毎回同じメンバー(新卒で入ったSIerの先輩・後輩)で出ており、今年は通算4回目の参加でした

過去大会ではそれぞれがアプリ担当・インフラ担当などとある程度役割を固定して作業していたのですが、
今回の大会ではすべてのメンバーがアプリの修正に取り組むなど、今までよりもチャレンジができたような気がします
(私自身も、本番でベンチマークを回すのを久々にやりました)

https://zenn.dev/yktakaha4/articles/postmortem_isucon11

https://zenn.dev/yktakaha4/articles/postmortem_isucon13

準備

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

合同で練習

継ぎ足しで使っているデプロイスクリプトの改善と過去問題を解く合同練習会をリモートにて数回行いました

毎年、前年にうまくできなかったことの振り返りをして臨んでいるのですが、今年は以下のような課題が出ていました

  • 推測より計測
    • 前回はpprofの導入をおこなったもののほとんど活用できなかった
  • 定形手順をちゃんとやる
    • 競技時間終了間近に再起動試験をやっていないことに気づくなど、確実にやるべき手順に抜け漏れがあった
  • 各自ができることを増やす
    • アプリの修正が自分頼みになりやすい状況があり、メンバーのkangaechumatchasongらが課題に感じていたようでした
    • 自分としてもデプロイやベンチ実行を毎回matchasongにお願いしていて悪い気持ちがあったので、自分でも手順を覚えてやれるようにしたいと考えていました

個人でやったこと

当日使えるスニペットをまとめたリポジトリのGoのバージョンアップや、サンプルの追加をおこないました

https://github.com/isushintaro/isunippets

上位勢の方の参加記録を見ていて、nginxなどとの接続にUNIXドメインソケットを使うというプラクティスがあったため、今回サンプルを作ってみました
本リポジトリは長く使っていけるように自動テストを書いた上でコードをコミットするようにしているのですが、nginxをdockerで立ち上げて繋ぎこんでテストするといった、込み入ったテストを書きました
例年、新しく思いついたことは大体その年には(時間が足らず)組み入れられないというジンクスがあり今回も対応できなかったのですが、来年参加できればぜひ挑戦したいと思います

https://github.com/isushintaro/isunippets/blob/6b46a2dec5685745fe790e225d812ff33be81eca/network_test.go#L17-L73

なお、Dockerやnginxを組み合わせた状態でテストを流すという発想は、以下ブログの内容に着想を得ました
余談ですが、実務でもnginxの設定ファイルは満足にテストできていない状態なので、このような方法で検証できるとよいな~と思います

https://blog.cybozu.io/entry/2020/04/16/080000

当日

今年はmatchasongの家に集まってやりました


競技前の様子

家のほど近くにナポリの窯(宅配ピザ)があり思わず注文しそうになったのですが、昼に思いっきり食べるとパフォーマンスが落ちそうという理由から思いとどまり、各自適当に食べることになりました
血糖値の上昇が抑えられ、結果としては正解だったと思います🍕

スコア推移

どんなことがあったか、箇条書きで簡単に思い出していきます


点数の推移

  • いつもはkangaechuがサーバー構築とGit管理を先行しておこない、matchasongが初期ベンチの実行、私はマニュアルの読み込みと分担を決めていたが、おいくつかのトラブル(後述)にて最初の数時間はスコアを十分に上げられなかった
  • トラブル解消後、お昼すぎにインデックス追加とDBサーバー分割が立て続けに入ってスコア上昇
  • その後、チェアとライドのマッチングや通知エンドポイントといった問題のコアっぽいところに改善を入れようとするがエラーを頻発させてしまい点数上昇が滞る
    • 軽微な改善自体は積み重ねていたため少しずつスコア自体は上昇したものの、点数のボトルネックがどこかいまひとつ判然とせず
  • 3人で分担してアプリ改善に取り組むもタイムリミットが近づき、再起動試験とログ停止をして15分ほど余裕を持たせて終わった

個人的な感想

スコアはベロシティ

今回個人的に目標にしていたこととして、実務でできているプラクティスを競技中に再現できるようにするという点がありました

私は普段SREをしているのですが、実務においてはプロセスを通じて結果を改善するという意識が重要になると考えています
例えば、アジャイル開発におけるベロシティは、あくまでチームの状況を理解するための計測器の1つにすぎず、その値を高くすることに執心するのは望ましくないと言われています

https://www.publickey1.jp/blog/24/_deep_dive_1.html

ISUCONにおける私たちの練度だと、コード修正自体はできてベンチは通ったものの、それがスコア向上に寄与しなかったためRevertするか悩むことがよくありました
スコアは最終的な順位を決めるものであり非常に重要ですが、システムのボトルネックに対して改善を加え、その結果ボトルネックが改善・移動し、結果スコアが上昇するというサイクルを競技時間中多く回すことを意識していました

その点において、今回はpprofの使い方をチームメンバーの全員で理解し、競技中も活用しながら修正を進められたのは大きな前進だったと思います
前回大会では導入だけしたもののほとんど使えていなかったのですが、今回はベンチを回すごとに結果をファイル出力しておくようにし、過去の結果と状態を比較できるようにしました

結果、ある関数を修正した結果スコアが思ったように伸びなくても、フレームグラフ上で改善が見られていればokとし、次の改善へ臨むようにしていました
今まではソースコードを読んで手が付けられそうな箇所に費用対効果を無視して片っ端から突進して時間切れになるということが少なくなかったのですが、これによってどこから対応していくかという優先度が付けられるようになったと思います
また、他のメンバーと取り組むタスクする際も納得感をもって優先度をつけられました

納得感や実際に負荷があるからと言ってスコア上昇に直結するわけではないところがISUCONの難しいところではありますが、再現性を高めるという点では重要なのでないかと思い、引き続き意識していきたいところです


pprofのファイル出力結果


pprofのファイル出力結果

pprofのflamegraphなどの各画面は単一のhtml内に表示のための情報が含まれているため、以下のようにwget等で保存してS3等でホスティングすると便利です

wget -LO /tmp/flamegraph2.htm http://localhost:3104/ui/flamegraph2

道具箱を充実させる

今回チームで新しく取り組んだこととして、Netdataを用いたサーバーメトリクスの取得をおこないました
インストールスクリプトを実行するだけで導入でき、ISUCONで利用する規模間では費用もかからずオススメです

https://www.netdata.cloud/

競技中は午後にスコアが伸びなかったことに焦ってしまい個人的にはあまり活用できなかったのですが、使用サーバーの分割などのインフラレイヤの改善をおこなった際にCPU負荷がどのように変化したかや、インメモリキャッシュを使った結果どの程度メモリ使用が上昇したかといった、アプリケーションより下のレイヤに対しても一定計測をしながら進められるようになったと思います

以下の図は練習中に使ったISUCON13の負荷なのですが、今回は初期ベンチの時点から負荷走行中にCPUが大きく跳ねている箇所がいくつもあり、非常に気になったもののアプリケーションの読み込みを優先したため原因がわからないまま終了時刻を迎えてしまいました

実務においても、手なりで対応を進めた結果十分な結果が得られなかったり手戻りになるといったことは非常に覚えがあることなので、 推測より計測 という価値観を念頭において、計測の解像度を上げていきたいと思います


練習におけるNetdataの活用

現在はアクセスログ解析をalpでおこなっているのですが、競技後にXを眺めていたいたところEvidenceというOSSを知ったので、ぜひ次の素振りに使ってみたいと思いました

https://x.com/matsuu/status/1865693280056508919

https://evidence.dev/

また、ブランチ戦略についても見直した方がよいように思いました
現在はCIでビルドできたmainブランチのソースのみ環境に適用可能なのですが、複数人でアプリ開発を担当するようになると衝突やRevertの影響が大きくなるため、任意のブランチを適用したり、フィーチャーフラグのような機能を使って対応を切り戻せると並列して作業しやすいように思っています

https://gofeatureflag.org/

また、今までできていなかったのですが、スコア上位の方の修正方法を写経するのもやってみたいです
優勝された方がリポジトリを公開されていて、自分が当日苦戦していた箇所をいくつか見てみたのですが、スキーマへの変更量など、もっと練習できるところがあるな~と感じました

https://x.com/takonomura/status/1865731305851547851

冷静になる

今回印象的だったこととして、競技開始直後にkangaechuが競技用サーバーにsshできず焦ってしまうということがありました
気づけば30分くらい格闘していることに気づいたため話しかけてペアで取り組んだところ、無事解消することができました

開始直後は3人ともある程度やりたいことがあったため、ついリソース効率を優先した動きをとってしまっていたのですが、
今後の作業を考えたときにkangaechuが戦力外になってしまったり、復旧できたとしても大きく時間を取ってしまうとその後の精神的なコンディションにも影響するため、フロー効率を優先して取り組めたのはよかったと思います

https://www.slideshare.net/slideshow/xpjug/79824686

実務においても、各人が自立して常に効率的に動き続けることを期待するのは、私たちのような一般的な開発者には荷が重いように思います
まず、ミスや焦りがあっても相互に注意を向けていてリカバリしあえるようなチーミングをした上で、プロセスの改善を通じてスコアや順位をあげていけるようにしたいです

おわりに

次こそは100位以内に入りたい という話を毎回しながらなかなか結果が出せていない状況で悔しいですが、今までで一番実感の持てる順位だったように感じました
毎年開催に向けて尽力されている運営の皆さんに感謝しつつ、来年ももし機会があればぜひ参加したいと思います🐤


明日のアドベントカレンダーはPdMのnagasakoがランニングについて書くようです
私も最近めっきり走っていないので、また再開したいです…🏃

https://qiita.com/advent-calendar/2024/lapras

LAPRAS Inc.

Discussion