ISUCON 7 予選敗退しました
ISUCON 5 のときと同じチーム「へしこず」で、2年ぶりの本戦出場を狙いましたが、本戦出場ラインには倍ぐらい届かず敗退しました。また来年会いましょう。
今回の主な装備
- vim
- kataribe
- pt-query-digest (percona-toolkit), mysqldumpslow
- beer (alcohol free)
KENZEN #isucon pic.twitter.com/kJpWD5ZQyM
— こっしー@みいつけた! (@macoshita) 2017年10月22日
序盤
予習で golang も検討したんですが、これまでの ISUCON で慣れてた ruby でやることにしました。
bundle install
できないぞってことで sudo apt-get install -y ruby-bundler
とか適当に叩いたのがアダ。 ~/xbuild
眺めたりして気づいたんですが ~/local/ruby/bin/bundle
を使うのが正解だったようです。
まず POST /login
のクエリがイケてない感じだったので、LIMIT 1
つけたり * を必要なものだけに書き換えたりして 10007 点になりました。その後何回か微調整してベンチマークして 15191 点あたりまで伸びました。このあたりはとりあえず API 1台だけでベンチマーク走らせてました。
この時点で2時45分ごろ。開始から2時間弱といったところでした。
中盤:icons をどうにかする
どうみても GET /icons/*.png
なんとかしないとだめだよね。ってことで、なんとかすることに。画像を mysql から取り出して redis に入れる班と、nginx の設定いじってキャッシュさせる班のふた手に分かれて行動しました。俺たちを苦しめた icons の一部。
アイコン画像が数百KBとか、仕事だったらありえないサイズだよねとか話してました。nginx 側は
location ~ /(css|js|fonts|icons)/ { proxy_set_header Host $http_host; proxy_pass http://puma_app; proxy_ignore_headers Cache-Control; proxy_cache zone1; proxy_cache_valid any 1m; expires 1m; etag on; add_header Cache-Control "public"; }
と書いてみたり、ruby 側では
configure do # 略 set :static_cache_control, [:public, :max_age => 90] end
とか
get '/icons/:file_name' do # 略 etag file_name # 略 end
とか書いて、kataribe で見た icons の状況はこのようになりました。
Top 20 Sort By Total Count Total Mean Stddev Min P50.0 P90.0 P95.0 P99.0 Max 2xx 3xx 4xx 5xx Request 3097 6351.049 2.050710 3.120888 0.000 0.007 7.722 10.000 10.001 10.007 1646 1451 0 0 icons
100Mbps 使い切ってたネットワーク帯域にも少し余裕が出てきました。
あとは GET /fetch
での SELECT COUNT(*) as cnt FROM message ...
のコストが高いと考えて、件数を redis に入れるなどしました。
18:43 時点で 45124 点。他のチームが数十万点を出してて、だいぶ焦りが出てきました。
終盤:積み重ねでフィニッシュ
- nginx → ruby (puma) をソケット経由にする
/etc/systemd/system/isubata.ruby.service
でExecStart = /home/isucon/local/ruby/bin/bundle exec puma -b unix:///tmp/puma.sock
/etc/nginx/sites-enabled/nginx.conf
でupstream puma_app { server unix:/tmp/puma.sock; }
,proxy_pass http://puma_app;
- puma のプロセス数、スレッド数を増やす
/etc/systemd/system/isubata.ruby.service
でExecStart = /home/isucon/local/ruby/bin/bundle exec puma -w 2 -t 25 -b unix:///tmp/puma.sock
- 既読メッセージIDを redis で管理する。
- mysqld の max_connection を 1024 に。
などといった工夫を重ねて、終了直前には 125550 点まで伸ばせました。
感想
開始時間が遅れはしましたが、ベンチマークとダッシュボードは ISUCON 5 からの中で(自分が参加した中で)一番良かったと思います。
- ベンチマークキューが詰まる気配がなかった
- 「負荷レベルが上昇しました。」がエキサイティング!
レスポンスが遅いため負荷レベルを上げられませんでした。/message?channel_id=7466&last_message_id=0
やエラーが発生したため負荷レベルを上げられませんでした。2017-10-22 20:57:58.647006618 +0900 JST m=+31.152077525 リクエストがタイムアウトしました (POST /profile )
といった具体的なアドバイス
問題についても、icons をクリアしたら、さらに次の課題が出てくるような形で、なかなかのスルメゲーでした。これまでの ruby 実装とは違って unicorn ではなく puma、mysql2-cs-bind
ではなく mysql2
だったので、調べ物に少し時間がかかってしまいました。
また、参加者連絡が discord になったわけですが、蓋を開けてみれば isubata ってのもクスリと来ました。
運営、出題の方々、ありがとうございました。残念ながら予選落ちしてしまいましたが、来年も参加したいです。いや、参加します。
反省会 #isucon pic.twitter.com/B5W42nPhHB
— りちゃ (@rch850) 2017年10月22日