肉汁爆弾

いろいろメモっていきます

社内でISUCON予選の問題を解く会に参加しました

社内でISUCON8の予選問題を解く会に参加してきました。

isucon.net

6チームの参加の中、2位という結果を残すことができましたが、スコア自体は8000点台(最高スコアは9000点台)であり、予選通過スコアからは大きく離れていたこと、そもそも実際の予選と違って4人で臨んでいたことから考えても、もうちょっと点数取りたかったなあという気持ちです。

リアル脱出ゲームのような感覚で役割分担と情報共有を行い、ボトルネックを発見して改善していくという体験は非常に楽しかったです。サービスとしてもある程度リアリティのあるものだったように思え、どういう手法で最適化するのかを全方面から問われていたような印象です。そう考えると自分の引き出しの少なさを痛感させられました。

ここ2年ほどはクライアントでC#を書くことを生業としてきた節はあれども、その前までは一生懸命perlを書くサーバエンジニアだったことを思い出すと、やはり悔しい気持ちになりますね。きっとこの悔しさは来年の予選で晴らすのでしょう。

ここからは当日までの流れを振り返っておきます。

当日まで

社内ISUCONに出るということが決まり、golangでやろうというところまでを決めました。予習がいろいろできるという話は聞きつつも、ほぼ たつまっく先生が前日に予習をした情報のみを参考にして本番に望みました。

当日の動き

とりあえず始めたことは

* プロダクトコードのgit管理

* アクセスログの収集

* slow_query_logの収集

* deployコマンドの生成

* 手元PC/golandでのビルド準備

あたりでした。

たつまっく先生の準備によって、ログ収集系のものはそれほどハマらずに入れられたものの、golangの開発環境が整っていなかったこと、僕自信はライセンスが切れていて30分ごとに強制終了されていたことなど、土俵に立つ以前の問題が山積されており、解析結果を確認できるまで2時間程度を消費してしまったように思います。

blog.yuuk.io

上記のブログを参考にしつつ、slow_query_logを吐くように設定した上でpt-query-digestで解析して重いqueryがわかり、同時に重いエンドポイントがアクセスログ解析によってわかっていたため、get_eventのN+1問題にまずは着手し始めました。

これ自体は1時間程度で修正を完了し、開始3時間程度で8000点ほどの点数を出すことがすでに出来るようになっていたものの、安定はしていませんでした。

この後は以下の部分についての修正に取り組んだものの、golangの構文が怪しかったり、ベンチマークが満たすべき内容になっていなかったりと、いろいろハマった割にスコアが伸びず、ぐぬぬ...という結果になりました。

やったこと

 * mariaDBで実行していた rand() を golangのappレイヤーで実現する

 * mariaDBで実行していたSHA2 を golangのappレイヤーで実現する

 * get_eventsのN+1問題の解消

 * DBサーバーの分離

振り返り

よかったところ

様々な計測手法を真っ先に入れたこと、deploy用のスクリプトを最初に用意できたことだと思います。

そこそこの複雑性のあるアプリケーションなので、あのコードすべてを読んで回収箇所を調べるのはあまり現実的ではなさそうだと思うなか、レスポンスの遅いエンドポイントやクエリがわかることは大きな指針となりました。

また、deployスクリプトは初期はそれほど力を発揮しなかったものの、終盤何度もdeployする際にはかなり成果を発揮していました。

わるかったところ

デバッグ手法はもっと早く確立すべきでした。アプリケーションコードがサーバで動いている状態で意図通りの結果を返していないことの確認が、基本的にベンチを動かすことでしかできていなかったため、並列開発での効率が上がりきらなかった印象があります。

複数台のサーバを使用しきれていなかったのも問題に思えており、一旦1台で限界を探るにしろ、とりあえず1人1台という感じで変更してテストして...という流れに早く設定できていると良かったのかなと思います。

役割分担と情報共有についても今ひとつ噛み合っている感じがしなかったように思います。時々刻々と状況が変わっていくとはいえ、全体観を把握する、方針を立てる、実装してベンチを回す...という流れがもっときれいにできていればよかったなと思います。

冒頭に書いていたように「パフォーマンスをもっと上げるための引き出しの少なさ」を感じてしまっていましたが、それにしてももうちょっとアプリケーションコードを読んだりして問題点を洗うフェーズの時間を取り、改修候補の箇所を挙げきってから実装するべきだったかなと思いました。

しかしまあ、何よりも悪かったのは下準備不足だったと思います。言語自体への習熟度の低さ、webアプリケーションでよくあるような構成の準備への臨機応変な適応ができなかったことなどは予習をしっかりしておけばある程度想定できていたことと思います。perlにすればよかったか...

終わりに

悔しいので来年は実際の予選に参加したいなという気持ちです。がんばるぞ。

追記

ISUCON忘年会に参加したら「暗号化をアプリレイヤーで?いやそもそも平文でDBにいれときゃええやろ」って感じの知見をもらって、確かにパフォチュー的にはそうですやん、っていう気持ちになりました。精進します。