去年に引き続き id:arata3da4 id:jp_taku2 と ISUCON に出場した。
今年の最終スコアは 26,772 点で、決勝進出することはできなかった。
しかし昨年の最終スコア 0 点と比較すると +Infinity 倍のスコアを記録できたことになる。
圧倒的成長!!!
(昨年の人権を失っていた頃の様子)
開始時間の遅延
気合い入れて7時に起床して8時半には準備完了して集中力を高めていたら、まさかの開始時間が3時間もの遅延。
時間が空いたからといって何か作業をするべきではない。
競技中の8時間にすべての集中力を注ぎ込むことが重要であり、今はリラックスして集中力を温存することが勝利への鍵であることは間違いない。
カバンから Nintendo Switch が取り出されたのはもはや必然であったと言える。
事前にやったこと
- 使用言語を決める
- 今年は PHP でやることにした
- プロファイリングの素振り
- アクセスログ: alp
- アプリケーションコード: Blackfire
- スロークエリ: pt-query-digest
- 当日使うリポジトリなどの準備
- 開始直後にやる作業の整理・スクリプトを書いて自動化
特に変わったことはしていない。
当日にやったこと
開始直後
- ルールを把握する
- 当日マニュアルを読む
- アプリケーションを動かす
- 構成を把握する
- 作業環境を整える
- アプリケーションをバージョン管理する
- 言語実装を切り替える
- 各種プロファイラを入れる
ここまでで1時間。
もっと早く出来たような気がしなくもない。
戦略を立てる
- とりあえず
/icons/*
をなんとかしないと話にならない /fetch
は扱いが特殊っぽいので試行錯誤- Nginx, MySQL のパラメータチューニング
- スロークエリを潰していく
あたりをやっていくことに。
/icons/*
を倒しきれず死亡
/icons/*
を倒す戦略としては主に以下の3つを試みた。
- データを返さない
- 画像がデカいのでそもそも毎回データを返したくない
- 304 Not Modified を返してよろしくやりたい
- この時点で
Cache-Control
を思いつかなかったのが悔しい
- Varnish を立ててキャッシュする
- 画像リクエストは Nginx と php-fpm の間に Varnish を挟む
- サーバ再起動時にキャッシュデータを配置してから Varnish を起動する
- MySQL のリードレプリカを作って負荷分散させる
- Master DB サーバ以外の2台を Slave サーバにした
- 画像はすべて Slave から読むようにアプリケーションを修正
結果的には Varnish のキャッシュしか効果がなかった。
304 を返すのは、クライアントから If-Modified-Since
ヘッダが送られてきてなかったので不可。
MySQL のリードレプリカは、ベンチマークのアクセス速度に対してレプリケーションが追いつかずに fail 連発してボツ。
Varnish + その他チューニング色々積み重ね で 20,000 点を超えたあたりで時間切れで終了。
まとめ
決勝行ったチームを見ていると「/icons/*
を倒したあとに見えてくるボトルネックをどう倒すか」で争っているようなので /icons/*
を倒せなかった時点で決勝進出争いの土俵にも上がれなかった模様。
キャッシュまわりの知見が足りなさすぎたのが敗因と言える。
ぐぬぬ・・・。
圧倒的感謝
今年も良い問題でした運営の皆さんありがとうございます 🙏 🙏 🙏
おまけ
終了1時間前から「スプラトゥーン2で残り1分になったときのBGM」を流していたけど、だいぶ焦燥感があってよかった。 オススメ。