ISUCON13に1人チームで参加して14位になった

ISUCON13に参加してきた。
ISUCONは8からほぼ毎年参加しており、去年は参加できなかったので5回目の出場。
初出場の頃はスコアを出すこともできなかったものの、今年はついに例年の予選通過ラインを超えれてよかった。

やったこと

リポジトリこちら

githubのコミットを読ませてChatGPTに記事を書いてもらった。

こんにちは、ISUCON13に1人チームで挑戦し、なんと14位になることができました!このブログでは、私がどのようにしてこの成果を達成したのか、具体的な実装の詳細について共有したいと思います。
コンテストの概要
ISUCONは、日本で開催されるプログラミングコンテストで、参加者は与えられたアプリケーションのパフォーマンスを最大限に引き出すことが目標です。通常、チームで参加するのが一般的ですが、今回は1人での挑戦となりました。
実装のアプローチ
私の戦略は、アプリケーションのボトルネックを特定し、それを効率的に解消することに集中することでした。以下は、GitHubのコミット履歴を参考に、私が行った主な改善点です。
1. ロギングの無効化
* コミット: [107004] app log off
* コミット: nginx access log off
アプリケーションとnginxのアクセスログを無効にしました。これにより、ディスクI/Oの負荷を軽減し、全体のレスポンスタイムを改善することができました。
2. インデックスの追加
* コミット: [96150] add indexes
データベースのクエリパフォーマンスを向上させるために、いくつかのテーブルにインデックスを追加しました。これにより、特に読み込みが多いクエリのレスポンスタイムが大幅に改善されました。
3. キャッシングの利用
* コミット: [30078] use cache for tips !!!
頻繁にアクセスされるデータに対してキャッシングを導入しました。これにより、データベースへのアクセス回数を減らし、レスポンスタイムを短縮することができました。
4. メモリ内でのデータ処理
* コミット: [77099] use in memory icons for not found
一部のデータをメモリ内で処理することで、データベースへのアクセスを減らしました。これは、特にアイコンのような小さなデータに対して効果的でした。
結果と学び
これらの改善を通じて、アプリケーションのパフォーマンスは大幅に向上し、最終的に14位という結果を得ることができました。1人チームでの参加は大変でしたが、パフォーマンスチューニングの重要性と、効果的な戦略の選択の重要性を学ぶことができました。
ISUCONは、技術的なスキルだけでなく、戦略的な思考も要求されるコンテストです。今回の経験を活かし、次回のコンテストではさらに上位を目指したいと思います!

このブログは、ISUCON13に参加した経験を基に書かれています。実際のコミット履歴は、GitHubのリポジトリで確認することができます。プログラミングやパフォーマンスチューニングに興味がある方にとって、参考になれば幸いです。

大体合ってる。 コミット履歴を参考にしているので、最後に行ったものから反映されているけど。

もう少しやったことを補足すると

  • 環境構築 & いつものおまじない
    • 計測系ツール(alp, pt-query-digest, pprof, net-data)の導入
    • Cursor (VSCode) Remote Explorer 
1人チームなので、サーバーにCursor入れて直接ソースコード修正
    • ビルドスクリプト作成
    • 再起動試験対策・too many open files 対策

ここまででちょうと1時間くらい。
だいぶ早くはなったけど、上位のチームは30分くらいで終わってるだろうからまだまだ改善の余地はあるはず

  • If-None-Match対策
    alpでiconがボトルネックだったので、マニュアルに書いてある通りに対応
    Cursorでiconのコード選択して「以下の仕様に沿って修正してください。」とアプリケーションマニュアルのIf-None-Matchの説明部分を送りつけたらGPTが実装してくれた。(手修正する必要なかった)
    https://github.com/yyamada12/isucon13-main/commit/2cbd810adf8101be654c6043ed7786e6819ab089

  • インメモリキャッシュ
    db内のデータを片っ端からメモリ上に乗せていった。 iconに関してはsha256が重かったので、hash結果もキャッシュ。

  • ADMIN PREPARE 対策
    slow query で ADMIN PREPAREが増えてきたので、いつもの設定を追加
    https://github.com/yyamada12/isucon13-main/commit/c01c806966363e8d18a67705d10078c898991bd5

  • MySQLへのINDEX追加
    適宜重くなってきた(slow query 上位に来た)タイミングで対応 DNSへの対応は、このMySQLへのINDEX追加くらい

  • 複数台構成
    本来は1台でなるべくチューニングし切った上でリソースを見てサーバー分割したいところだが、チューニングのペースが芳しくなかった(前半にバグにハマって1~2時間溶かした)ので15時くらいの時点で焦って複数台構成に。
    DNS周りがよくわからないので、DNS + Nginx を3号機のまま、1号機をapp, 2号機を MySQL (for app), 3号機を DNS, MySQL(for DNS), Nginx という構成にした。
    初手では、/api/register が PowerDNSのCLIを直叩きしていたので、 /api/register のみ3号機に残していたが(本来は/api/initilaizeも必要だった)、PowerDNS関連だけで良いよねということで、 /api/initialize_dns/api/register_dns を新規追加して、1号機のappから呼ぶように修正した (initialize, register)

  • 後片付け
    ng_words がボトルネックになった頃に残り時間がなくなったので最後に計測ツールを消して、go application のlog出力も止めて、最高スコアが110461

感想

前半に手間取って1~2時間足踏みしていたのが痛かった。 それもあり、うまくいけば10位以内はいけるのかもと思えたが、3位以内は1人チームのままだと絶望的だなと感じた。 特に1位は強すぎる、、

何はともあれめちゃくちゃ楽しませてもらった。運営の方々はありがとうございました。