ISUCONに初参加した

初めてISUCONというものに参加した。

業務ではOSS系を全く触っていないし、一緒に興味を持って参加出来るような人が社内にいないし…とずっと参加できずにいたISUCON。 前々から興味があったので、試しに今回はどんなにぐだぐだでも揉めたりしない社外の友達を誘って2人で参加した。

参加した後の素直な感想

今まで参加しなかったのが悔やまれるほど得られるものが多く、何よりもチャレンジできるのが楽しかった。 仮説を立てて変更をかけ、どう変わったのか試していくことがとても新鮮だった。 手を動かすのは楽しい!

結果的にスコアは最初の6000くらいから11000と大きな改善は出来なかった。

しかし改善に向けての一歩を実現することが出来て良かった。 参加したことで、他の方のISUCON記事であー!ってなりとても勉強になる。 来年もあれば次は力をつけて是非参加したい。

当日何をしたか

やったことを覚えている範囲で記載。

  • レギュレーションの読み合わせ
  • sshでのログイン確認
  • ベンチマークの実行
  • 動いているサービスの確認
  • 構成図を手書き
  • gitによる変更対象の管理(bitbucketへの登録)
  • kataribe導入
  • netdata導入
  • 気付いたことをアウトプット

当日の振り返り

イントロ

自分がインフラ担当・友人がアプリ担当として動くという方針で始まった。

まずは互いに当日のレギュレーションを読み合わせをし、各サーバへのsshログインを済ませた。 サポートチャットではログインできない!とか6台あります!とか交わされるのを横目に見ながらベンチマークに移る。

app1~app3まで3台構成であることを知る。 app1とapp2に対し、同時にベンチマークをかけたあと1台ずつかけていった。

ベンチマークを2台で実施した方がスコアが下がったため何これ?となった。 1台ずつかけた時も、app1が6000、app2は3000くらいと差があったため、スペックや設定が違う?何これ?? となった。

後々ログインして確認したところ、サーバ毎にスペックの差異はなかった。おそらくベンチマークのブレっぽい。 netstatやpsでサービスを確認し、Webはnginx、DBはmysqlミドルウェアを確認した。

gitの管理については友人に任せ、自分は構成図を書いて得られた情報を整理。

お互いのタスクが終わったところで認識と今後の方針を決める。

app1とapp2のベンチマーク差はわからなかったので、とりあえずシンプルにWebは1台でやって行こうということに。

アプリケーションについては友人に任せ、自分はapp3のDBをチューニングすることにした。

DB周りの調査

mysqlなら、まずはバッファプール!と聞いていたのでとりあえず積んでみようと思ったものの、サーバのメモリが1GBだったのでいきなり躓く。 slow-queryの設定とテーブル情報、件数、Indexの有無をまとめて一旦終了。

ベンチマークをかけながらslow-queryのログを眺めると大量に/imageの画像が出ていたので気づきとして挙げた。 DBに画像が入っているとこの時点で気付くものの、どうやって外に出すのかわからずmemcachedとかredisを調べてみたが理解が追い付かずお手上げ。

chromeの開発者ツールでもfetchが大量にリクエストされていることも気付きとして挙げた。

kataribe,netdataの導入

気付きは何点か出てきたが、細かくいじっても改善しないどころか悪化などして焦る。 誰かが言っていたボトルネックになっているところを解消しないとパフォーマンスは改善されないということを痛感。

思い付きで実行することに手詰まり感が出てきたため、まずはリソースを見える化してボトルネックを探そうということになった。

nginxのログ出力を変更してkataribeを導入してnginxのログを分析しやすくした。 netdataを導入し、サーバリソース、ネットワークリソースを可視化した。

netdataが素晴らしかった。

導入した状態でベンチマークを実行して各サーバを眺めるとWeb-DB間のNWが500Mbpsと枯渇していることに気付けた。

気付きからアクションを決めて対応。

アクションの実行

DBのimageテーブルの中に画像が入っていることが悪いことがnetdataのトラフィックを見て確信に変わったので、少なくともユーザ登録のアプリ箇所をDBに書き込まないようにアプリケーションを修正。

するとスコアが6000から9000ほどに上昇。DBへのIOが減ったためと思われる。

その後DBのインデックスを張ったり、my.cnfをconnection手さぐりで修正したところ、最高で15000を記録。脳汁が出た。 設定変更のcommitを忘れていて何をいじったのかわからなくなってしまったので反省。

その後は有効なアクションが打てずアプリケーションを眺めて終了。

反省点

  • 初回必ず実行するものはスクリプト化しちゃったほうが良い
  • kataribeとnetdataの導入
  • ベンチ前にログローテのスクリプト
  • 画像をキャッシュする実装方法
  • 設定変更は後から何を変更したか追えるようにcommitする
  • indexを効果的に張るようにする

振り返り

netdataを入れてからボトルネックがわかり、効果的なアクションが立てられるようになった。 他の方々の記事を見ても着眼点は間違っていなかったことは自信になった。 力不足で実現方法がわからず、何も出来なかったのが心残り。

今回のISUCONの復習を行うのと、ISUCONの過去問も遊んでみようと思う。