isucon8本戦で惨敗したからせめて良いブログを書く

ISUCON8の本戦に、メルカリで一緒だった@zaq1tomo@inatonixzin-gonicというチーム名で出場しました。
結果は学生9位、全体で19位だったので、やったこととかまとめます。
予選エントリはこちらです↓

やったこと

チューニング対象は、isucoinという取引所アプリでした。
言語は予選と同じGoです。

nakabonne/isucon8-final - GitHub

担当も予選と同じです。

@nakabonne: インフラ担当
@zaq1tomo: アプリ担当
@inatonix: アプリ担当

序盤

@nakabonne

序盤は主にプロファイリングの準備です。

今回はdockerでデーモン化されていたため、パフォーマンスが少し気になる上にプロファイリングが少し面倒でした。
当初はdockerを剥がしてsystemdに乗せ換えようとしましたが、工数に対するインパクトが見込めず一旦後回しにしました。
また、nginxの公式イメージを見ると標準出力をdocker logsに流しており、アクセスログがうまく拾えず若干詰まりました。

@inatonix, @zaq1tomo

方針決め

各プロファイリング結果毎に見ていきます。

リソース

実行時にCPU使用率は100%に張り付き、半分以上はmysqlが食っていました。
メモリもギリギリで、こちらも同じく大半はmysqlのキャッシュによるものでした。
この時点で早いうちにDBを外に切り出すことは決めました。

スロークエリ

全tradeをソートしてから取得するクエリがまず第一関門っぽかったので、初動は決まりました。
二つ目もクエリ数減らせないか調査の必要がありそうだと話した気がします。

アクセスログ

POST /orders GET /info から見ていく必要があるのは一目瞭然で、エンドポイントが少ないことから一筋縄ではいかない匂いがプンプンでした。

中盤

@nakabonne

mysqlを切り出し、サーバー1をapp+nginxのみの構成にしたためCPUに半分くらい空きが出来ました。
CPUがボトルになるまではしばらくappは一台で動かそうとなりました。

@inatonix, @zaq1tomo

この@zaq1tomoの修正で500点→3200点に伸びました。

つかの間の1位

この修正で5136点まで伸びました。そしてこの瞬間、我々zin-gonicは1位に躍り出ました。
ただ、この時を最後に我々が笑顔になることはありませんでした。。

終盤

@nakabonne

CPUに余裕が出来たところで、リソースを使い切りたいと思っていたところ、@inatonixが怪しいものを見つけました。

// TODO: trueにするとシェアボタンが有効になるが、アクセスが増えてヤバイので一旦falseにしておく
res["enable_share"] = false

どうやらシェアボタンを有効にすると取引成立時にシェアされてユーザーが流れ込み、一気に負荷があがるそうで、これだ!と有効にしました。
が、GET /info でタイムアウトが頻発。
DBサーバーを見てみるとCPUが使い切られていたので、ロックされてるのかな?と思いつつとりあえずこれはまだ早いと判断して、そっとブランチを切り替えました。
講評を聞く限りここで負荷を上げても耐えられるようにすることが鍵だったらしいです。

このブランチ量を見れば悪あがきをしていたことが分かります。
もちろん何も意味をなしていません。

@inatonix, @zaq1tomo

oh…

感想

問題作成していただいたDeNAさん、カヤックさん、主催のLINEさん、サーバー提供していただいたConoHaさん、本当にありがとうございました。
今回の優勝者は学生であり、それを讃えている皆さんを見て、改めて最高の業界に来てしまったと感じました。
もしisucon9があるならば、来年も学生枠使えるので(もはやそんな枠があるかは不明)出場したいと思います。