はらへり日記

腹に弾丸

ISUCON7に出た #isucon

ISUCON7に参加しました

今年は前職の先輩と現職の先輩と組んで参加しました。

isucon.net

結果

f:id:sota1235:20171023011636p:plain

予選突破の20万台には遠く及ばず…

点数のブレが大きすぎてどの対策が効いたか全然わからなかったけど時系列でやったこととかやりたかったけど諦めたことをメモる。

タイムライン

私の担当はアプリケーションだった。

  • INDEX追加
    • (user.name)
    • (message.id, message.channel_id)
    • (haveread.user_id, haveread.channel_id)
  • SELECT *の撲滅
  • get_channel_list_infoの置き換え
    • 最終的に一箇所しか残らなかった
  • DBアクセスする前に結果返せるところは返す
    • DBアクセスした後にリクエストパラメータの有無チェックしてるようなロジックがちょいちょいあった
  • COUNT(*)ã‚’COUNT(1)に
  • チャンネルごとのメッセージ数カウントを専用テーブル用意して置き換え
    • 毎回COUNTせずにSELECTするだけでよくなった
    • 最初の段階で2番めに遅いクエリだったので手をつけた
  • php-fpmのチューニング
    • TCPやめてunix socketにしたり
    • 子プロセスを増やしたり
  • 使わないPHP extensionの削除
    • xdebug.so, お前のことやで
  • N+1をいくつか潰す

他のお二人には

とか諸々やってもらった。感謝…

やりたかったけどできなかった

  • /register, /loginページを静的コンテンツに
    • ロジック見ると分かるけどこの2つはPHPに捌かせる必要がない
    • HTMLの配置は一瞬だったけど優先度低かったので後回しにしたのと、nginxの設定でハマってやれなかった
  • キャッシュミドルウェアの追加
    • ログイン判定の度にselect * from userしてるのとか
    • 今回は削除更新が無かったので整合性の担保も難しくなかったはず…
  • メッセージ取得ロジック改善
  • 未読数カウントロジック修正
  • LIMIT, OFFSET殺す
  • php-fpmのさらなる調整
    • 時間無くてかなり雑に調整した
  • PHPとMySQLのコネクション最適化

他にも色々アイディアはあって

  • DBサーバにもアプリを立てる
  • キャッシュ用サーバとアプリを分ける

なんて案もあったけどとにもかくにもボトルネックが/iconsから他に移らなくて死んだ。

所感

とにもかくにも/iconsのリクエストを捌けて無くてしんどかった。

一番最初はDBが完全にサチっててその壁は一瞬で越えられたけどその後すぐに画像が死んでることが分かってなるほどという感じだった。

画像の脱DB化をしてもそこまでスループットが上がらず、なかなか苦しかった。

今回はそこを抜けたチームが10万の壁を越えていったのではという推測。

スギャブロエックスチームと同じ会場で解いてたので効いたところCache-Controlヘッダあたりをいじって2回目以降リクエストさせないようにしてたらしい。ぐぬぬ…

一昨年、昨年参加して今年3回目だけど計測してボトルネック特定して確実に芽をつぶしていく力はついていると感じてて、それゆえに結構悔しい。

あとはぱっと直したコードにバグがあることが多くて結構時間を取られた。

今回はほぼ何も準備できなかったけど来年は手元で簡単にアプリが動かせるような環境を作る秘伝のタレを用意してそこでデバッグしたい。

とにかくですね

来年こそ100万円使って温泉行きたいです。