猿に文明を与えるな

個人的な勝手なまとめ。

ISUCON2遊び -1-

時間がかかる or 負荷が高いアクセスを探す

nginx (RP)

log_formatを変更

before
log_format     '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';
after
log_format     '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent $request_time "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';
結果

access.logを見ると次の2つが明らかに遅い

  • POST /buy (5-10sec)
  • GET /ticket/{id} (1-5sec)

forever (AP)

ログを見ると GET /ticket/{id} のレスポンスサイズが大きい

416.06kbなんてのがある。

MySQL(DB)

slow log出力設定を追加して確認
slow_query_log = ON
slow_query_log_file = /tmp/mysql-slow.log
long_query_time = 1

その後、mysqldumpslow -s t /tmp/mysql-slow.log を実行した結果が以下((a) , (b) は今後の記述のため加筆)。

(a)
Count: 297  Time=1.45s (430s)  Lock=0.02s (6s)  Rows=5.0 (1474), isucon2app[isucon2app]@2hosts
  SELECT stock.seat_id, variation.name AS v_name, ticket.name AS t_name, artist.name AS a_name FROM stock  JOIN variation ON stock.variation_id = variation.id  JOIN ticket ON variation.ticket_id = ticket.id  JOIN artist ON ticket.artist_id = artist.id  WHERE order_id IS NOT NULL ORDER BY order_id DESC LIMIT N

(b)
Count: 2  Time=1.11s (2s)  Lock=0.00s (0s)  Rows=1.0 (2), isucon2app[isucon2app]@[172.30.0.94]
  SELECT COUNT(*) AS count FROM variation INNER JOIN stock ON stock.variation_id = variation.id WHERE variation.ticket_id = N AND stock.order_id IS NULL

方針

MySQL

(a)のクエリ対策
  • キャッシュヒット調査
  • クエリプラン調査

forever

(a)のクエリ対策
  • キャッシュ組み込み
レスポンスサイズ減少させる
  • 画像等をnginxに移し、アプリからのレスポンスサイズを減らす

nginx

  • foreverから移した画像をここで返すように変更