見出し画像

Web開発初心者がPythonでISUCON11予選に出てみた (4304点)

前回以下の記事で書いたように、ISUCON11 の予選に出場しました。

初めての ISUCON でしたが、とても楽しい8時間ちょっとでした。結果は4304点で598組中376位。チームメンバー3人とも Web の経験がほぼなかったため、何か少しでも改良することが目標だったので、満足のいく結果となりました。今回アプリケーションの仕様を考慮した高速化はできませんでしたが、初心者でもできることはあり、少しずつスコアが上がっていくのは楽しいよということでログを残しておきます。

やったこと

10:00-10:45 AWS 環境立ち上げ、初ベンチマーカー実行
マニュアルを読み込む前に環境を立ち上げを行った。AWSを立ち上げてそこにチームメンバー全員でログインしてそこで作業をする形式で進めたが、SSH鍵でログインを練習したときの手順を忘れ、全員がログインできた時点で10:30になっていた。その後、10:38に最初のベンチマーカーを実行した。

10:45-11:30 マニュアル読み込み
予選当日マニュアルおよびアプリケーションマニュアルの読み込みを行った。チームの実力的にアプリケーションの詳細な仕様を把握した上での改良は難しいと分かっていたので、適宜読み飛ばした。

11:30 アプリケーションを Python に切り替え
最初から起動している Go のアプリケーションを Python に切り替えた。Go で2977だったベンチマークが2657に低下した。

11:30-12:50 MySQL (MariaDB) サーバーを別インスタンスに移動
初期状態では Python のプロセスと MySQL のプロセスで CPU を食い潰していたため、 MySQL を別のインスタンスに移すことからやることにした。詳細は忘れたが、エラーをググりながら1時間以上かかってできた。ただしこの時点では DB の初期化処理が正しく動いていなかった。この部分は練習でやっていなかったため時間がかかってしまった。

12:50-13:30 昼休憩

13:30-14:10 DB 初期化処理を追加

DB の初期化を加えてベンチマーカーが正しく動くようになり、スコアは3122に上がった。
なお別チーム (oretamaB2) で出ていたあらBさんたちとは、連絡を取り合いながら事前練習をしていたため本番の戦略も非常に似ていた。

oretamaB2 では Go を使っていて、MySQL のインスタンスを分けた時点で8400点になっていたとのこと。今から思えば、この部分は使用言語にほぼ依存しないため、Go と Python で効果を比較するなどしても良かったかもしれない。

14:10-16:07 SQL にインデックス追加
練習での手はず通り、 SQL のスロークエリを調べ、インデックス追加などを行った。
まず jia_isu_uuid や jia_user_id にはインデックスがなかったので追加した。さらに上記の2つの ID を AND で呼び出しているところがあったため、これらをつなげたカラム (isu_user_id) を作りこれにもインデックスを追加した。

ALTER TABLE isucondition.isu ADD isu_user_id varchar(400) NOT NULL;
ALTER TABLE isucondition.isu ADD INDEX index_isu_user(isu_user_id);
UPDATE isucondition.isu SET isu_user_id=CONCAT(jia_isu_uuid, jia_user_id);

前者2個のインデックス追加後のスコアは3398、isu_user_id 追加後は 3678 となった。
また、 Python のタプルで1個しか要素がない場合、 ("aaa", ) のようにカンマが必要なことを忘れてけっこうな時間を無駄にした。

16:15 Python 用インスタンスの mysql を停止
ここで Python サーバーが動いているインスタンスで MySQL サービスを止めていなかったので止めると、スコアは 4015 となった。

16:15-18:00 nginx まわり

nginx の gzip 圧縮を圧縮率を変えたり、対象とするファイルを変えたりして試したが、特に効果はなかったか、むしろ遅くなったため使用しなかった。ISUCON10予選の問題で行われたbot避けについても、 (ユーザーエージェントは調べず) フィルタを使い回して試したが効果はなかった。
また、これまで使用していなかった3台目のインスタンスを使用してそれぞれのインスタンスを nginx, Python, MySQL と分けてみたが、nginx ではほとんど CPU を使用しておらず、高速化しなかったので戻した。

17:00 再起動試験
終了1時間前の時点で、インスタンスを再起動後にちゃんと動作するかの試験を行った。無事に起動し、0点になることはなさそうだと安心した。

18:16 bulk insert
DB へのデータ追加を連続で行っている箇所があり、その部分を一気に追加するように変更して高速化しないか試したが、特に変わらなかった。遅くもなっていなかったようなのでこれはそのまま有効にした。

トラブルによるベンチマーカー再開後に動作を確認し、残りの作業時間でできそうなことはもうなかったので作業を終了した。

反省

分担
練習でやったことを本番でもでき、何か改良するという目標は達成できたものの、作業に時間がかかり、アプリケーションの仕様を考慮した修正は何もできなかった。今回上記の作業はメンバー3人で画面を共有しながら行ったが、次回からは1人でできるはずなので2人は別の作業ができるのではないかと思われる (同じメンバーで出た場合)。

Python は不利だった?
参考実装のスコアが言語によってけっこう変わることを身を以て体感した。利用言語比率を見ると Python 予選通過をしている人は例年ほぼいないので、今後は Go か Rust あたりを使用することを検討したい (別に予選通過したいわけではないけど、スコアは高い方がうれしいし達成感がある)。

スコア分布など
スコアはリクエストをさばいた数に比例するので、パフォーマンスを線形に反映していると思っているのだが、以下の図のように上位チームと下位チームではスコアが指数関数的に異なり衝撃的だった。

また、チームのスコア履歴はこんな感じだった。

ISUCON11q_-_Google_スプレッドシート


おわりに

初めての ISUCON はめっちゃ楽しかったのでまたぜひ出たいと思います。運営の皆様は本当にお疲れ様でした。このような素晴らしい機会を与えて下さってありがとうございました。

この記事が気に入ったらサポートをしてみませんか?