ISUCON9予選に参加してよかった!
ベルトラでソフトウェアエンジニアをしているイワモトです。2019年9月7日から8日にかけて開かれたISUCON9オンライン予選に1名チームで参加しました。予選突破はできませんでしたが、得るところが多くあり、参加して本当によかったと思っています。
ISUCONとは
ISUCONは「お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル」です。2011年のISUCON1から毎年、年に1回開催されています。
ISUCON9のオンライン予選では約600チームが競い、最終ベンチマークスコアが高かった30チームが10月の本戦にコマを進めました。
1チーム2名から3名で参加するのが原則ですが、2018年のISUCON8から1名での参加枠が試験的に設置されています。
参加した意図
ぼくは2018年からベルトラのパフォーマンスチューニングに取り組んでいます。その知見が通用するのかどうか、腕を試してみたいと思ったのが参加のきっかけです。ISUCON8は都合で参加できなかったため、今回が初参加でした。
あえて1名で参加したのは、これまでの知見をそのまま試してみたかったからです。具体的には、ベルトラで取り組んでいるチューニングとできるだけ同じように進めようと、下記の方針を事前に定めました。
- PHPを選ぶ
- New RelicのAPMでボトルネックを特定する
- OSやミドルウェアのチューニングは後回しにする(業務ではほぼ触れていないため)
予選で進めたチューニング内容
以下、どんなチューニングを進めたのか、時系列でまとめてみます。参加者にしか通じない内容もあると思いますが、雰囲気だけでも感じていただければ幸いです。
10:00
マニュアルやレギュレーションを読んだり、インスタンスを立てたり。Alibaba Cloudは初めてで、RAMロールを付け忘れて焦る。後から付けた。
10:38
初めてベンチマークを回した。スコアは 1,410
。New RelicのAPMエージェントの設定がうまくいかず焦る。
10:44
他にできることはないかと、MySQLのクエリログを全部出すようにした。ベンチマークスコアが 1,310
に下がり、「やっぱりそういうものなんだなあ」と思った。
11:34
ようやくNew Relicにデータが飛ぶ。ベンチマークスコアは 1,010
。最終ベンチマークの前に、New Relicエージェントを必ず止めようと思った。
11:49
GitHubにプライベートリポジトリを作り、初期ソースコードをpush。
12:12
items
テーブルへの (`created_at` < ? OR (`created_at` <= ? AND `id` < ?))
クエリに違和感を覚え、(`created_at` < ? OR (`created_at` = ? AND `id` < ?))
に変更。スコアが 1,410
になった。
12:35
インデックスをいくつか追加してベンチマークを回すも、スコアが上がらない。ベンチマークのたびにスキーマが初期化されることにようやく気づく。初期化SQLにインデックスの記述を追加した。
13:21
そろそろ transactions
のボトルネックをなんとかしようと、外部APIのリクエストを非同期にした。Guzzle便利。スコアが 2,840
に上がった。
13:41
getCurrentUser
の結果を Service
インスタンスのプロパティにキャッシュするようにした。スコアは 2,930
。
14:42
getCategoryByID
の N+1 を解消しつつ、結果を同様にキャッシュ。スコアは 3,130
。
14:50
getUserSimpleByID
の結果を同様にキャッシュ。スコアは 3,340
。
15:06
キャンペーン機能の還元率の変更をそろそろ試そうと思い、0
から 2
に変えた。スコアが 5,710
に上がった。
ここからSQLやミドルウェアのチューニングをあれこれ試すが、スコアはあまり伸びなかった。
17:45
諦めて、MySQLのログ出力と、New Relicエージェントを止めた。スコアは 6,520
。これが最高スコアだった。
18:07
ポータルの問題により終了時間が10分伸びた。ダメモトでベンチマークを走らせたら、スコアが 6,220
に下がってしまった。これもISUCONあるあるなのかもしれない。
結果
本戦に進めたのは、最終スコアが 9,880
以上のチームでした。ぼくの最終スコアは時系列の通り 6,220
で、約600チーム中98位という結果に終わりました(実際には順位は付かないため参考値)。
参加して得られたもの
- 業務での知見が、まあまあ通用したという自信
- 「New Relic APMエージェントのインストールにはPHP CLIが必要」という知識
- OSやミドルウェアを含め、さらなるチューニング経験を積むモチベーション
反省点
- 業務要件を確認する余裕がなかった。外部APIを呼び出す必要がない部分があったらしく、そういうことに気づきたい
- Nginxで静的ファイルを配信するくらいはやりたかった。アプリケーションコードの変更で頭がいっぱいで、そういう発想が出なかった
- ボトルネックでない部分を色々いじりすぎた。SQLの「*」をカラム指定に変えるとか。スコアに影響せず、時間がもったいなかった
まとめ
というわけでISUCON9、予選だけでも得るところが多くありました。チューニングに少しでも興味のある方は、気軽に参加してみてはいかがでしょうか。ぼくも再挑戦してみるつもりです。
末筆ながら、これだけ参加者の多いコンテストを運営するのは、さぞ大変だろうと思います。運営者・関係者のみなさま、本当にありがとうございました!