ISUCONに負けた

ISUCON、見事に予選落ちしました。憂鬱な火曜日で出てました。言語はRubyを選択しました。

やったこ

nginxアクセスログ解析

kataribeを使ってアクセスログの解析を行った。 message、login、iconsあたりが遅いことが判明。 特にiconsがボトルネックになっていたので、icon取得部分を改善することにした。

icon取得部分の改善

  • 以下のSQLを実行するとユニークの画像件数が67件しかないことが判明
SELECT
 MIN(id),
 name,
 data
FROM
 image
GROUP BY
 name,
 data
  • とりあえず、重複行は全て削除
DELETE FROM
 image
WHERE
 id NOT IN
(
 SELECT i
 FROM (
  SELECT
   MIN(id) AS i,
   name,
   data
  FROM
   image
  GROUP BY
   name,
   data
 ) hoge
)
  • 続いて、Unique Indexを追加。
    • ridgepoleを使用していたので、Schemafileに以下を追加
add_index :image, :name, unique: true
  • アプリケーションについては以下のように修正
-      statement = db.prepare('INSERT INTO image (name, data) VALUES (?, ?)')
 -      statement.execute(avatar_name, avatar_data)
 -      statement.close
 +      begin
 +        statement = db.prepare('INSERT INTO image (name, data) VALUES (?, ?)')
 +        statement.execute(avatar_name, avatar_data)
 +        statement.close
 +      rescue => e
 +      end

/message actionのチューニング

  • n+1が発生したので、改善
  • Schemafileに以下を追加して、Index追加
add_index :message, %w[channel_id id]

ログインのパスワード認証をDB側で行うように修正

※これは効果なかったかもしれない

  • コードを以下のように修正
+    name = db.escape(params[:name])
+    password = db.escape(params[:password])
-    row = db.query("SELECT * FROM user WHERE name = '#{name}'").first
 -    if row.nil? || row['password'] != Digest::SHA1.hexdigest(row['salt'] + params[:password])
 +    # パスワード認証とユーザー取得を一括で行う
 +    row = db.query("SELECT id FROM user WHERE name = '#{name}' AND password = SHA1(CONCAT(salt, '#{password}')) LIMIT 1").first
 +    if row.nil?
  • Schemafileに以下を追加
add_index :user, [:name, :password]

fetch処理修正

fetchは加点対象じゃないと書かれていたが、改善することにした。

  • n+1の改善
  • sleep 1.0の削除

iconsの画像を静的コンテンツに変更

  • 画像ファイルが133種類しかないことがわかったので、全部書き出して、public/icons配下に置いて、nginxから配信することにした。

反省

  • 上記以外にも色々やったけど力及ばず。Cache-Controlを確認してなかったのがすごく痛かった。絶対nginxがおかしいんじゃないかという話をしていた。ちゃんとレギューレーション読めばよかった。
  • 台風だったので、当日帰れなくなったら困るからリモートにしようという話になった。一緒の場所でホワイトボード前で話すとかできなかったのも結構よくなかったなーって思ってる。

次に向けて

  • 次は予選突破ぐらいするぞ!(出場機会あれば)

最後に

  • 運営のみなさまありがとうございました。非常に勉強になりました。

f:id:suthio:20171023002040p:plain
すてぃたろう