isucon7予選参加して惨敗しました

isucon7予選参加して惨敗しました

10/21(土)のisucon7予選にチームokinawa.rb(@saboyutaka, @_simanman, @tompng)で参加して惨敗しました。

nginxがなぜかタイムアウトしたり(帯域制限に引っかかってた)
mysql接続が切れて500頻発したり(statement.close忘れ)
最後までその原因を特定できずにズルズルと時間が過ぎて絶望のまま終わってしまいました。

最終的には再起動試験にもfailしてて完全敗北です。

一応気合い入れて準備してきたしapp側は結構がっつりチューニングできたつもりだからダメだったなりに何やったかまとめとこうと思って...
突破エントリ書きたかった...

コードはこちら https://github.com/siman-man/isucon7-qualify/blob/master/ruby/ (感想戦として終了後もいくつかcommitしてます)

構成(途中でappを減らしたり増やしたり)

  • 1台目: nginx app
  • 2台目: nginx app
  • 3台目: nginx app db

オンメモリキャッシュする時のためにappサーバ同士をTCPSocketで直結(するために事前準備でgem作ったり)
(redis使うくらいなら直接他のappサーバにデータ渡せばいいじゃん、って発想)

やったこと一覧(だいたい時系列)

15:00~16:40 画像のファイル書き出し

  • 画像をDBに入れてたので初期データをファイルに書き出し(git add)
  • プロフィール変更で追加される画像は即座に3台にコピー(app2に/icons/aaa.jpgが追加されたよ通知を他のappサーバにbroadcastして)

この変更を本番に入れるもなぜかスコア変わらず(原因は参照実装pythonのままベンチ走らせてたから?)
そのあとでバグ取りとかして2万点くらいになって、画像は解決したつもりになっていた。
last_modified合わせるとか必要だったらしいけどそんなこと知らない。

15:00~15:15くらいにだいたいのコードは書いたけど最終的にバグ潰せたのが16:40くらいで、時間かけすぎた

15:45 /fetchのlong polling化

新着メッセージが来たら即座に返すようにしてみたけどあんまり効果なかったので保留

18:40 オンメモリキャッシュして/fetchのN+1を消す

  • channel
  • channelごとのmessage_idの配列(Array#bsearch_indexを使っての既読数計算に利用)
  • channel_id, user_id毎の既読メッセージ数(メッセージ数から引けば未読数になる)

を全部メモリに載せた。
これで/fetchは3クエリだけで返せるように(新しいchannel, message, 更新されたhavereadをそれぞれ読み込むSQL)
あとは /fetch が速くなったからsleep時間を色々と調整してみたり

19:00 /message /history のN+1を消すために、userをオンメモリに

オンメモリにしたあとでuserのupdate対策できてないことに気づいたけど、他の問題がでかくて直すどころじゃなかった
(オンメモリやめてjoinに直すか、updateされたら全appサーバに通知するべき 10行くらいの追加で直るからやっておけばよかった)

19:00〜 先延ばしにしてたnginxとmysql試行錯誤

途中から悩まされてたnginxのタイムアウト(画像の帯域制限)とmysqlの接続切れの対処をそろそろやらなきゃと、この頃から意味のない変更加えて試行錯誤してた。
def dbをThread.current使うように書き換えたせいかなと元のダメそうな実装に戻したりetc
再起動チェックは終了2時間前くらいにやる予定だったけど、nginxとmysqlの問題解決を優先してスキップ
終了1時間前くらいからはひたすら絶望してて、結局最後までどうにもならず、(post /loginですら出る)500エラーとタイムアウトエラーまみれ
スコアは2万台~4万台の間を上下するだけのまま終了(再起動試験fail 参考値34,580)

nginx知らない... CDN知らない... 速度勝負の土俵に上がりたかった...

まとめ

isuconは冷静になれる心の余裕が必要だなって思った。nginxとかCDNあたりは知らなかったとして、mysqlはなんでclose忘れ疑わなかったんだろう
最初のうちは楽しかったけど途中からは絶望で苦しかった。 終わった後もしばらくもやもやしてたけど、練習段階からやりたかったほぼ全部オンメモリキャッシュも後日書いてみたし、最後にこの記事で僕のisucon7は一区切りついたかなー
それでスコアどこまで行くのか、ちょっと気になるけど、検証も大変だし、終わり。