ISUCON13にでました (チームひろし)
成績
得点は35,904点で、694チーム中の47位でした。
初参戦で上位10%に入れたことは嬉しいですが、もっと高い順位を目指していたので悔しくもあります。
メンバー
どんな問題だったか
isupipeという動画配信サイトの負荷を解消する問題でした。
YouTubeにあるような、ライブ配信やコメント、投げ銭の機能があり、これらの性能を改善していくことでベンチマーク結果が上がっていきます。
例年にはない新しい要素として、DNSのボトルネック解消がありました。
ランダムに生成されたサブドメインの名前解決リクエストが大量に飛んでくる「水責め攻撃」への対処するというものでした。
あとは例年と同様に、DBのテーブルにインデックスがはられていなかったり、N+1なクエリがあったりしました。
全配信者のランキングや各種情報の集計をリクエスト時に都度都度計算していたりと、処理が重くなるような稚拙な実装があえて用意されていました。
どの問題にどう取り組んだか
自分はインフラ周りの初期設定や、DNSや配信者のランキングや集計処理のボトルネックの解消に主に取り組みました。
nginxのアクセスログ、goアプリケーションのpprof、MySQLのスロークエリログを見てボトルネックを特定し、改善にあたりました。
- DNSのボトルネック
- PowerDNSが使っているテーブルのスロークエリが存在していた
- AレコードのTTLが0秒になっていたので、ゾーンファイルのTTLをデフォルトの3600秒に変更しクライアント側でのキャッシュを試みた
- 整合性チェックは通ったが、ベンチマーク結果が変わらず、とりあえずマージはせずにおいた
- 最終的には当該テーブルにインデックスをはることで改善した
- AレコードのTTLが0秒になっていたので、ゾーンファイルのTTLをデフォルトの3600秒に変更しクライアント側でのキャッシュを試みた
- 水責め攻撃
- 当日マニュアルに攻撃が行われることが記載されていた
- 対処の調査に時間がかかりそうだったのと、この時点ではボトルネックにはなっていなさそうだったので対応は一旦保留にした
- PowerDNSが使っているテーブルのスロークエリが存在していた
- アプリケーションのボトルネック
- ユーザーのランキングや各種情報を集計している処理のスロークエリログがでていた
- スロークエリの中で処理時間の合計が最大だった
- ユーザーのランキングや各種情報の集計はリクエストのたびに毎回計算されていたのでこれをどうにかキャッシュできないかと考えた
- ランキングや集計にはライブ配信のコメント数や投げ銭の額などが使われており、キャッシュの鮮度が問題になりそうだった
- 終了したライブ配信であれば投げ銭やコメント数が変化しないであろうからキャッシュできるのではないかと踏む
- 色々試したが整合性チェックが通らずに諦めた。多くに時間をここで使ってしまった。
- ユーザーのランキングや各種情報を集計している処理のスロークエリログがでていた
よかったところと反省点
DNSについては水責め攻撃を深追いせずに、ひとまずインデックスをはるにとどめて、その時点でのボトルネックを解消することができてよかったです。
水責め攻撃については後々問題になるだろうとは思っていましたが、調査や対応に時間がかかりそうだったので、他のボトルネックを解消することを優先して、少しでもベンチマークのスコアの伸ばすことに務めました。
反省点としてはランキングや集計処理の対応に時間を取られたことです。
色々試したあげく、うまくいかずにマージはできませんでした。
終了したライブ配信のコメントなどは更新されないであろうと踏んでキャッシュしましたが、
もう少しちゃんと仕様を確認すべきだったなと反省しています(仕様はあっていたが、単純に実装がバグっていただけの可能性もありますが)。
感想
ISUCONは楽しいし勉強にもなって一石二鳥だなと思います。
また来年も参加したいです。
isupipeという名前は、並び替えると「パイプ椅子」になって、面白いなと思いました。
pipeはYouTubeのtubeからきているのだと思います。
今後も今回のISUCON13の問題をやりこんでカリカリにチューニングしたいと思います。
来年はもっと順位をあげるぞ!
付録
大会で使ったリポジトリ(のフォーク)です。
これからは練習で使う予定です。
株式会社SODAの開発組織がお届けするZenn Publicationです。 是非Entrance Bookもご覧ください! → recruit.soda-inc.jp/engineer
Discussion