なまえは まだ ない

思いついたことをアウトプットします

ISUCON13に出場しました

ISUCONに出たよ

11/25(土) に開催されたISUCON13に参加してきました。

isucon.net

チーム

会社の同僚3人で参加しました。内1名は期待の新卒社員です。

チーム名は 69E0773F-B436-4CC4-B998-B6B143A30EFB です。 つけたあとに気づいたのですが、チーム名を誰も読めない・覚えられないという致命的な欠点を抱えてました。

最終スコアは 14,108点、全体順位でいうと120位ぐらいです。

リポジトリ

すでに公開済みです。気になる方は見てみてください

github.com github.com

やったこと

3人でなんとなく作業分担をしました。

僕は最初に計測系の設定を仕込み、あとは他のメンバーと修正箇所を分けて取り組む、というスタイルでした。 以下、特徴的だったトピックをいくつか振り返ります。

条件付きリクエストの実装

とりあえずアイコン取得のAPIがめちゃくちゃ叩かれていて、そいつがレスポンスタイムの大部分を占めていることに気づきました。 アプリケーション仕様に条件付きリクエストに関する記述があったため、よーしやったるかということで修正を担当しました。

さっとチーム内で話し合い、以下の方針としました

  • 毎回画像のSHA256ハッシュを計算するのは無駄なので、別途 icon_hashes テーブルを用意する
  • 画像の登録時にハッシュ値を計算してしまい、 icon_hashes テーブルに格納しておく
  • アイコン取得APIで条件付きリクエストがきたら icon_hashes テーブルから情報取得し、レコードがあれば 304 を返す

ETag の実装は業務でも経験があったので、値がダブルクォート " で囲われているという罠(?)に対してもそこまで混乱せず対応できました。 最終的にアイコン取得APIは約 9,000 リクエスト中 7,000 リクエスト以上を 304 で返していたようなので、期待通りの効果を出せたと思います。

あとハッシュテーブルはユーザー情報を取得するような場面でも使い回せたため、ちょっとは効果あったかな?どうなんでしょ

NGワード登録時のSQLを軽くする

差分としてはこちら

スパム報告体験を改善 by furusax0621 · Pull Request #9 · furusax0621/isucon13-app · GitHub

NGワード登録のエンドポイントが上位に上がってきたので頑張って読み込んだところ、過去投稿を削除する部分でなんかすごい無駄なことやってんな?ということに気づきました。

  1. 該当ライブ配信NGワードをすべて取得
  2. NGワード単位のループ
    1. すべてのライブ配信のコメントを取得
    2. コメント単位のループ
      1. なんか難しいサブクエリで該当コメントがNGワードか判定し、削除

ざっくり書くとこんな感じ。

まずライブ配信のIDはすでにわかっていたので、すべての配信のコメントを取得するのはどう考えても無駄でした。なのでまずはコメント一覧取得をライブ配信IDで絞り、次にコメントもループの度に取る必要がないので外に出し、よーしこのサブクエリを理解するか〜としばらくにらめっこした結果

……これ、単なる文字列比較では?

と気付くことができました。 しかもDELETE文のWHERE句条件として書いてましたが、必要なNGワードもコメントもすでにそれ以前のSQLで取得済みです。 であればわざわざSQLで書かなくても、アプリ側で判定して削除対象IDの一覧を抽出し、それを DELETE ~ WHERE id IN ~ というSQLで一括削除すればOKです。比較も内容的にGoの strings.Contains() で置き換えることができました。

この実装によって該当APIの平均レスポンスタイムが1/10ぐらいになり、スコアも目に見える形で上がりました。やったぜ

できなかったこと

複数台による負荷分散

top の推移からして終始MySQLサーバーがボトルネックになっているのはわかっていたので、ここを早く分離すれば良かったなと思います。 特に今回はPowerDNSによるMySQLへの負荷がそれなりに大きかったっぽいので、アプリ用とPowerDNS用とでMySQLサーバーを分けられればもっとスコアが伸びた気がします。

PowerDNSは完全にわからんと思って目を逸らしていたので、全然検討できませんでした。ここは非常にもったいない

MySQLのさらなるチューニング

競技の途中でBinログを無効にするなどのいわゆる「鉄板」チューニングはしていました。が、メモリに全然余裕があったのでMax Connectionsを引き上げるなどのチューニングもできたなぁーと反省しています。

あと講評には「インデックスをうまく貼っていけばそれだけでスコア10,000点ほどになる」と書いてあってぶっ飛びました。まじかよ。。全然インデックス対策足りなかったんだな

感想

結果は及びませんでしたが、過去に参加したISUCONの中でも一番戦ってる実感を得られたなぁーと思います。本当に結果は及びませんでしたが。

一緒に参加してくれた新卒メンバーは、業務とはまた違った脳の使い方ができて楽しかったんではないでしょうか。今後の成長に期待。

というわけで来年もまた出るぞ!運営の皆様お疲れ様でした