公開日

ISUCON14の感想戦モードでRubyで六万点を獲得した

(image)ISUCON14の感想戦モードでRubyで六万点を獲得した

2024年末に ISUCON14 に参加した。競技終了後の感想戦モードでRubyで六万点を目指して無事獲得できたので記録を残しておく。

参加経緯

ISUCONは毎年都合が合えば出たいとは思っているが、近年は人気アイドルのチケット争奪戦かってくらいの人気イベントになっているので、しばらく参加できずにいた。

しかし今年は参加枠が大幅に増えたようで、なんとか参加枠が確保できたので参加。ただ一人チーム + 競技当日予定ありの中参加したので、本気で勝利を目指すためというより勉強目的の参加だ。

参加してみての Good/Bad

当日は予定があって途中離脱したこともあり、最終スコアは全然伸びなかったけど全体を通して振り返りを書いておく。

Good

  • 今年のお題は<タクシー配車アプリ>。個人的にタクシー配車アプリに興味を持っていたこともあり、そのような要件に触れられて嬉しかった
  • 当日マニュアルアプリケーションマニュアル を丁寧に読むように意識した。特にひっかかることなく実施 ・理解できたのはよかった
  • エディタはZed(+ VSCode)のRemote Development機能を使った
    • 一人参加だったのでコードベースの競合を気にしなくていいのは良かった
  • サーバーで gh コマンドをインストールして gh auth login して GitHub private repo と繋ぎ込んだ
  • アクセスログの解析は nginx ログを alp に食わせて解析するのが良かった
  • 令和時代のクエリ分析は pt-query-digest ではなく、 MySQL Performance Schema の活用が良さそう
  • SQLの書き換えやコードの部分的な置き換えはAIが活用できた
    • AIが現在進行系でできることがガンガン増えていて、今後その流れがものすごく加速しそうだと感じた

Bad(反省点)

  • 前回参加したときの反省として「サーバーの分散戦略の失敗」があったので、最初にアプリを分散させることにフォーカスしたが、これが結果的に良くなかった
    • 後述するエラーの発生要因になった
    • Aサーバーで行った変更をBサーバーに変更漏れしたり、「自分が今どのサーバーで作業をしているのか」を見失ったりして無駄に時間を浪費することになった
    • 今回ボトルネックは DB に比重が大きかったので、アプリケーションをいかに効率的に分散させるかは、初手に考えるべきではなかった
  • スコアを伸ばすにあたって下記のエラーにひたすら頭を悩まされた
    • 椅子がライドの完了通知を受け取る前に、別の新しいライドの通知を受け取りました

    • 椅子に想定していないライドの状態遷移の通知がありました

    • サーバーを初手で分散させたことが原因
  • カジュアルに使えるAPM SaaS として Sentry APM を使おうと思ったけど、役立たなかった
    • 上述した alp くらいのシンプルツールのほうが取り回しがよい

学習したこと

  • マッチングアルゴリズム
    • タクシー x 乗客のマッチングアルゴリズムとして Hungarian algorithm を利用しようと試みた
    • 実装してみたが、スコアが伸びなかった
    • 件数が多すぎるとマッチングに時間を要して、使い物にならず
      • 件数少ないときにHungarianを使うようにもしてみたが、結果的にスコアは伸びず…
  • jounalctrl コマンド
    • journalctl -f
    • jounalctrl --system
    • jounalctrl --user
    • journalctl -u nginx
    • 場所は /var/log/journal に保存されている
  • systemctl コマンド
    • systemctl {status,restart,enable,disable} nginx
    • 今回つかったやつ
      • sudo systemctl start isuride-ruby
      • sudo systemctl enable isuride-ruby
      • sudo systemctl restart isuride-ruby
      • sudo systemctl restart mysql
      • sudo systemctl restart isuride-matcher
  • mysql 設定の変更点
    • bind-address: 0.0.0.0
    • Increase key_buffer_size
    • Increase max_connections
    • slow_query_log 設定 (but, 使わなかった)
    • Added
      • disable_log_bin
      • wait_timeout
      • innodb_buffer_pool_size
  • 実際の設定ファイルは gist に残した

所感

  • シニアなスーパーエンジニア3人集めたチームがたくさんいる中、ソロ参加のtakonomuraさんが優勝 & 学生1位取っちゃうのすごすぎる
    • 競技形式だとこういう(良い意味での)化け物がはっきり可視化されるのがいいですね
  • 優勝者のリポジトリを見て思ったこと
    • 今回リポジトリには自分が選択した Ruby App だけコミットしたけど、まるっとwebappディレクトリごとコミットしたほうが楽だったかも
    • 秘伝のタレ scripts がめっちゃ作り込まれていてすごかった
  • Ruby で SSE はいけたチームはあるんか?
    • 早々にSSE実装のトライは諦めた(そしてそれは正解だったと思う)
    • このへんの実装をしやすい Go とかが改めて羨ましく思った
      • Goは処理の非同期化やキャッシュ化のしやすさがあったりと良い

さいごに

めっちゃ勉強になった。

次回開催もあるようなら、勉強目的で参加したいと思いました。

参考リンク