nakarioのほぼISUCONブログ

ISUCON出るたびブログ書く

ISUCON13、久々の現地参加してきました(百万円ドリブン:11位)

今年もISUCONがやってきた!

こんいすー。チーム「百万円ドリブン」のnakarioです。今年もISUCONの季節になり、我々にとっては7回目の参戦を果たしてきました。ほぼISUCONについてしか書いていない本ブログの読者はISUCON関係者しかいないと思うので、ISUCONとはなんぞやみたいなのは飛ばしてさっそく感想から書いていきたいと思います。

久々の現地参加

コロナ禍の影響で長らくオンラインのみの開催となっていたISUCONですが、今年はLINEヤフーのオフィス現地参加抽選枠があり、ありがたいことに我々はその枠で現地参加してきました。オンライン開催のときにはチームメンバーで自宅に集まって参加していましたが、やはり他のチームと同じ場所で参加すると緊張感や高揚感、イベントに参加しているという実感が段違いですね!

LINEヤフーオフィスにやってきた!

最後の現地参加はミライナタワーのLINEオフィスでしたが、それからオフィスが移転したり、ヤフーと統合したりと前回とはガラッと変わった環境ですが、競技者視点ではモニターの貸与があったのでこちらの方が良かったですね。新宿駅ダンジョンよりも分かりやすい場所にありますし(チームメンバーの@Muratamは迷って3つぐらい別のビルに入ったりしてたみたいですが……)。

競技終了後にお酒と料理を楽しみながら感想を言い合ったり、941さんの配信を生視聴したり、二次会で他チームと合流してISUCONトークで盛り上がったりも含めて最高の一日でした!!

成績と反省点、問題に対する感想

今回は11位という成績で終えることができ、チームとしては予選敗退だった前回はもちろん、他の決勝進出回と比べてもなかなか良い成績を出せました。スポンサー企業様より「いい生活賞」も頂けたのでいい事づくしです。ですがチーム名にもある通り狙うは1位100万円なので、まだまだ修行が足りていないですね。

ISUCON本戦では各々の開発力はもちろんですが、本番ゆえの緊張からくる判断ミスや過集中の影響が無視できないというのが僕のこれまでの参戦歴からの学びでした。その点、今回は初動から優勝チームであるNaruseJunがぶっ飛ばしていたのもあり、自分でできることを着実にやろうと冷静になれていたのではないかと思います。例えば、後述しますが序盤のボトルネックの改善でしょうもない見逃しをしていたせいで大きくタイムロスしたのですが、その際も別の方法で解決することができないか考え直したり、メンバーに協力を要請したりなど、目の前のタスクにとらわれずにやるべきことをやる、ができていたと思います。後半も、実装は間に合いませんでしたが取るべき方針は間違ってなかったと考えています。ということで今回は、純粋に技術力・実装力で負けたと、認め難いですがそういうことになるという認識です。悔しい!我々のチームは毎年本番前に丸4日ほど使って過去回をおさらいしているので、定番パターンのN+1問題やDBのインデックスなどを解決する方法は理解しています。しかし、定番ゆえに手癖で解いてしまうことがあり、複数の解決方法を検討した上で最も効率の良い方法を選択する、ということを事前練習の段階で行っていませんでした。ゆえに本番でも愚直に手を動かす以外の手札がなく、最適な選択を行おうという意識があるにも関わらず実質的に取れる選択肢が一つだけ、という状況だったのかなと振り返って思います。今回は事前練習ではツールの整備などに時間を多めに割いていました。それは間違いではありませんでしたが、それだけでは足りないということが改めて思い知らされたといったところです。次回はN+1を解くにしても10個くらい手札を用意して参戦したいですね。

ISUCON13の問題の感想ですが、題材としてはどこかで見たようなライブ配信アプリだったので取っ掛かりやすさは大きかったです。独自のゲームなどが題材だとそのゲームを理解するところから始めないといけませんが、今回はすんなりアプリの概要を理解して競技に集中することができました。ベンチマーカーの待ち時間が大きかったところは気になりましたが、スコアは大きなブレもなく、改善を入れれば素直に点が上がっていったので気持ちよく取り組むことができました。こういったところを作っていくのも面白そうなので、早く我々も優勝して出題側にまわりたいです。

やったこと

  • 10:30 3268点: 問題の理解や環境構築
  • 11:00 各種ログやpprofの設定
    • POST /initializeを叩くと同時にpprofを計測する仕組みを我々も用意していますが、ログの集計時にMySQLのrestartでアプリも再起動することに気付かず、自動集計の仕組みがうまく動かなかったので少し手間取りました
  • 11:20 3,614点: DBの2台目への移動
  • 11:40 9,257点: インデックスの作成、InterpolateParamsの有効化、DBコネクション数の調整
  • 12:00 11,908点: 更にインデックスの作成、PDNSのTTL=120
  • 12:40 20,100点: N+1の解消、DNS用のインデックスの作成
  • 13:30 26,892点: icon_hashのキャッシュと304
    • 前述の序盤のミスです。11時半ば頃から取り組み始めてここまでかかってしまいました。
    • icon_hashのキャッシュ自体は割とすぐに実装できたのですが、ETagをレスポンスに含めているにも関わらずベンチマーカーがIf-None-Matchヘッダーを付けてリクエストを送信してくれず、ブラウザでの検証でも同様で、どこが間違っているのかわからない状態でした。
    • 原因はETagの値をダブルクオートで囲まずにヘッダーに入れていたことでした。とほほ……。
  • 13:45 27,168点: ライブコメントの走査対象を限定
  • 15:00 34,025点: N+1、インデックス
  • 15:30 43,924点: N+1
  • 15:40 57,294点: slotの範囲検索をid検索に変換
  • 15:50 69,737点: N+1
  • 16:00 80,976点: livestream_tagsのキャッシュ
  • 16:30 84,773点: tagsのキャッシュ、インデックス
  • 16:40 104,645点: インデックス
  • 17:30 111,401点: JSONのインデントをなくす
  • 17:50 127,149点: 各種ログのオフ

16時くらいからDBの水平分割をメンバーに取り組んでもらっていましたが、あと一歩届かず3台目のサーバを丸々未使用のまま終了しました。DNSのDBを分けるなどすればもしかしたら5位くらいにはなっていたかもしれませんが、狙うは1位なので無駄なことをしないという選択をした結果です。僕がETagで手間取らなければ+1時間くらいあったはずなので、そこが一番の悔いですね……。手書きせずにライブラリを使ってもうまく行かなかったのですが、これはブラウザで検証した際の方法が良くなかったのかも。ChatGPTに質問しても見当違いの返事しかしてくれなかったので、やはり普段からサーバを書いて経験を積んでおくことが肝なのかなと思いました。あるいはCopilotに書かせるのも良いかもしれません。

最後に

今回のISUCONも大変楽しかったです。主催のLINEヤフー株式会社様、出題のさくらインターネット株式会社様、株式会社いい生活様はじめスポンサー企業の皆様、ISUCONの運営やコミュニティを支えてくださっている皆様、どうもありがとうございました!(あれば)次回もぜひ参加したいです!