ISUCON7の予選を学生枠で通過しました
ISUCON7の予選に @brook_bach さん,@mayoko_ さんと「座るだけのコンテストってな〜んだ?」で参加しました。
@brook_bach さんの記事
@mayoko_ さんの記事
チーム結成の経緯
🙋
— しょラー (@shora_kujira16) 2017年9月4日
やりましょう!!🎉
— OKeiGo || brook (@brook_bach) 2017年9月4日
準備
3人とも別の大学ということもありミーティングはすべてSlackで行いました。
事前準備として以下のようなことをやりました。
お役立ち情報や秘伝のタレをGoogle Docsにまとめた
3人とも普段からWebプログラミングをやっているわけではないので,MySQLのログイン方法やsystemdの使い方などから復習してGoogle Docsにまとめました。MySQLのデータのバックアップとリストアは一度は練習しておかないと本番で詰む可能性があります。プロファイルのために使用するツールとして mysqldumpslow, dstat, kataribe, wsgi_lineprof を使用することも事前に決めておきました。nginx.conf
や my.cnf
は過去のISUCONの参加者のブログから設定項目を寄せ集めて作りました。設定ファイルの更新とミドルウェアの再起動を行うスクリプトも事前準備しておいたので非常に捗りました。
作業フローを整備した
去年のISUCON6に参加したときには本番サーバーでデバッグをしていて非常に効率が悪かったので,今年は改めようと思い,手元の開発環境でデバッグ → GitHubにpush → 本番サーバーでpullして sudo ./reload.sh
という作業フローにしました。
GitHubではプライベートリポジトリを用意しなければならないので普通は課金が必要になってしまいますが,学生特権でプライベートリポジトリが使い放題なので活用させていただきました。
サーバーからプライベートリポジトリにアクセスする方法は以下のページを参考にさせていただきました。
Pixiv ISUCONを使って練習した
注意:Pixiv ISUCONのネタバレがあります。将来的に解く予定がある人はスキップ推奨!
Pixiv ISUCON を解いて練習しました。本番ではPythonの実装を使用する予定だったので methaneさんのPython実装 を利用させていただきました。
このPixiv ISUCONの内容が今回のISUCON7と非常に深く関わっていて,ソースコードの流用などで非常に助けられました。
私はAWSのアカウントを持っていないしGCPはクレジットカードの登録をしたことがないインフラ弱者だったのですが @brook_bach さんがよろしくやってくれました。
Ansible playbookを準備した
@brook_bach さんが全てよろしくやってくれました。
本番開始直前まで
@brook_bach さんの勘が冴えまくりでした。正直なところ,私は「1台構成だったらAnsibleとか別に要らなくない〜?」と思っていたのですが,用意してくれていたので助けられました。
本番
13:00 〜 14:00
- サーバーが3台あるという事実が判明する
- ansibleでツールのインストールやデータのバックアップや公開鍵の登録などが動いている間にレギュレーションを読む
- アプリで遊んでみるとAjaxが動作しているっぽい雰囲気だったのでChrome DevToolsでネットワークの動きを見てみる
GET /fetch
でチャンネルごとの未読件数を取得して,未読があったらGET /message
にchannel_id
とlast_message_id
をパラメータにして問い合わせるとメッセージが取得できるという仕組みらしい
- 手元のPCの
~/.ssh/config
の設定を書いてssh app1
とかでアクセスできるようにする - 初期構成でベンチマーク → app1だけだと4232点,app1 + app2だと6187点
14:00 〜 15:00
git pull && sudo ./reload.sh
を3台に適用するのが面倒だという話になる → @brook_bach さんがtmuxのsynchronize-panesという機能で3台同時に操作できるようにしてくれる- MySQLの設定を @brook_bach さん,Nginxの設定を私が担当する
- 静的ファイルの配信の設定もこのとき行った
- 初期状態の
nginx.conf
のuser www-data;
を消すと/var/lib/nginx/proxy
にアクセスできないというエラーが出て,user www-data;
を付けると/home/isucon/isubata/webapp/public
にアクセスできないという問題が起こり,30分くらい時間を溶かす sudo gpasswd -a www-data isucon
で解決した/var/lib/nginx
の役割や,Nginxがどのユーザーで動いているのかについて復習が必要。真っ当な方法を誰か教えてください…
/icons
がとても遅く,Pixiv ISUCONと同様にMySQLに画像データが入っていたので,Pixiv ISUCONをやったときと同じ方針で解決を試みる- @brook_bach さんと @mayoko_ さんにはそれ以外の箇所の高速化をしてもらう
15:00 〜 17:00
/icons
の高速化に取り組む- @brook_bach さんと @mayoko_ さんが画像配信以外の箇所を高速化してくれる
- 私は全く見ていないのでよく分からないが,チャンネルの未読件数を(総数−最後に読んだときの総数)で計算できるようにしてくれたらしい
- いろいろトラブルがありながらもアプリの修正が完了して31067点になる。この時点では学生2位
17:00 〜 19:30
- 若干マシにはなったが
/icons
がまだ遅い - 画像ファイルを捏造して軽いファイルを返してみたり,JavaScriptを書き換えて画像をLocal Storageに保存してみようとしてみる → 静的ファイルの書き換えはベンチマークで弾かれました
- とりあえず帯域を稼ぐためにDBサーバーでもNginxを動かしてみる → 34882点(なぜスコアが上がらないのかよく考えるべきだった)
- 画像以外の箇所でN+1を消したりしていたら52186点が得られた
- "nginx image cache" でググると Cache-Control "public" を付けろという記事 が出てきたので付けてみる → スコア変わらず
19:30 〜 21:00
- Gunicornやカーネルパラメータの設定をする
- 再起動テストをする → サービスが立ち上がるまでにアクセスすると502が返る以外には特に問題なかった
- ガチャを引きまくって終了。ベストスコアの55931点は再現しなかった
#isucon のハイライト pic.twitter.com/jm0soj20yc
— OKeiGo || brook (@brook_bach) 2017年10月22日
敗因と反省
Cache-Control "public"
を付けて,かつファイルのタイムスタンプを合わせる(レスポンスヘッダのLast-Modifiedを合わせる)とCDNがキャッシュしてくれて304で返せるという環境を想定したベンチマークだったそうですCache-Control "public"
についての情報に行き当たった時に,もう少し詳細に調査をしていれば気づいたかもしれません- 一般枠と比べるとかなり低いスコアでの学生枠通過ですが,CDNの設定経験がある学生なんて普通いないので大目に見てくださいw
- とはいえ,Conditional RequestsはRFCで標準化されている範囲だと言われると何も言い返せません…
感想
- 学生枠で参加できる最後の年だったので予選を通過できて嬉しいです
- アプリの実装が凝っていて(Pythonでさえ400行くらい)準備がすごく大変だったと思います。運営チームの皆様ありがとうございました
GitHub リポジトリ
ほしいものリスト
以下のURLから私たちのチームに書籍を購入していただけると私たちのチームを支援することができます。