おそらくはそれさえも平凡な日々

ISUCON8は6位と惨敗

ISUCON8だめだった。「死闘の果てに」チームで @najeira さんと @bluerabbit777jp さんと組んで6位でした。順位的には悪くないのかもしれないけど、そもそも優勝できない時点でダメ。しかも結構僕が勝てる問題内容だったし、優勝と3位が学生チームということで、なんというか、色々ショッキングであるとともに脱帽です。

しかし、すごく良い問題かつ運営だった。楽しい時間を過ごさせてもらい、運営の皆様には感謝申し上げます。これまでのISUCONの集大成とも言えるような問題だったと思います。

チームメンバーにも恵まれただけに、優勝できなかったのはなおさら残念。まあ、冷静さを欠いたところと、純粋に実力が足りなかったというところが敗因でしょう。良い経験になりました。

当日の朝

najeiraさんと、bluerabbit777jp さんがやる気で、ディスプレイ持参。そして「一番良い席を取ろう」ということで、受付開始前から集合することにした。結果として、狙い通りに一番乗りで入場し、狙い通りの席に設営をすることができた。

チームメンバーが前のめりでモチベーションが高かったのは、今回結構引っ張ってもらえたな、と感じている。

今回はオンライントレード

今回は、外部APIが絡むオンライントレードということで、まあとにかくボリュームが大きかった。ファイルもいつものISUCONのシングルファイルではなくて、modelやcontrollerに分割されていた。ドキュメントやレギュレーションもめちゃくちゃ書き込んであって、これには正直面食らった。

これで、結構焦ってしまって、レギュレーションやドキュメントを読み込むのを怠ってしまったのが結局敗因になった。

言語はGoを選択。というかメンバー的にそれしか考えてなかった。

序盤の戦い

最新のトレードを取得するところが豪快に全件取得しているところを、単に SQLに LIMIT 1 を足すだけでスコアが大幅に改善した。多分これは全チームの中でうちのチームが一番早く見つけたと思う。このあたりは、 bluerabbit777jp さんと najeira さんが見つけていたけど、今回は bluerabbit777jp さんのSQL周りのボトルネックをすばやく見つけるところに関しては全般的に頼りになった。

で、予選と同じく、 github.com/najeira/measure を仕込んで、時間のかかっている処理を探して、細かいところを潰し終わった後は、najeiraさんがlogのAPI送信部分の非同期化を担当して、僕はRunTradeの最適化をする感じで役割分担をすることにした。

序盤の落とし穴

このあたりで暫定トップに立ち、良い感じに戦えているつもりだったけど、実葉逆で、一旦冷静になるタイミングを設けるべきだった。特にこのくらいの段階でレギュレーションの読み合わせ読み直しをするべきだったなーと思っている。結果として、logのAPI送信部分をbulk送信できる仕様を読み落とすという今回一番の痛恨のミスをすることとなった。

あとは、今回は僕はインフラは他のメンバーにお任せで、僕はアプリケーションコードを書くことに集中するつもりだった。しかし、他のメンバーがDockerの設定が不慣れであったこともあったので、ここもこのあたりで役割分担を見直す作戦会議をしておけばよかった。結果として僕も役割分担が不明確なまま中途半端にインフラをいじったり助言することになってしまい、終わった後に後悔した。

他には、MySQLにパーティションが切られていることはパーティションスキーとして当然最初に気づいていたが、これを素直に外すことを勘ぐってしまって、手を出さなかったことは悔やまやれる。

楽しいRunTrade最適化問題

僕が担当したトレードの処理を実行するRunTradeの部分は、今回僕にとって一番楽しく難しくやりがいのある部分だった。これが「今回の問題の急所の一つだな」とすばやく気づくことができたのは、今回の手応えの一つ。

まず、無駄に再帰処理になっている部分を外し、関数の実行時間の統計を取りやすく修正した。その後に、この処理がユーザーが取引を追加する毎に無駄に重複して呼び出されていることも見抜いたので、これをロックを取りながら高々一つの処理しか動かないように修正をおこなった。

このへんで一旦マージしようとしたら、僕のしょぼいミスでシングルトンの初期化にミスっていて動かなかったり(ここはnajeiraさんにレビューしてもらって解決した)、najeiraさんの変更と盛大にコンフリクトしてここの解消に時間がかかってしまった。

この後の処理として、アプリケーションサーバー1台でしかRunTradeの処理を動かないようにしたり、そもそもRunTrade自身の処理を見直すところまでやりたかったので、そこが結局手を入れられなかったのは悔いが残る。

特に、RunTrade自体の処理を最適化するところは、今回の問題の一番面白いところだったと思うのでそこまでいけなかったのは非常に残念。初期実装だと、売り注文か買い注文のどちらかを一つに固定して、それに適合する買い注文なり売り注文なりを探す素朴な処理になっていたのだけど、ここは売り注文と買い注文をそれぞれ複数にもできるということを懇親会のときに運営の人から聞いて「やっぱりそうだったかー」という気持ちになりました。

最後の一手

何をやっても点数が伸びず、インフラ構成も、DB1台、アプリケーション1台からも脱却できずこまっていたのだが、 bluerabbit777jp さんが、トレードの集計情報を集計テーブルに持たせる処理を入れて、これが結構効果があった。

後は、負荷を上げるために、ソーシャル拡散機能を確率的にonにする調整を行いながら終了。このあたりの調整で、結局非同期でやっていたログ送信部分を同期処理に戻すということもおこなうことになった…。最終的には、1万3千点位を安定的に出すようになっていた。

最後は、再起動試験も行うのを諦め終了した…。DB1台、アプリ1台しか使えなかったので、再起動試験しなくても大丈夫だろうと思ってはいたのですが、それを含めてそもそも再起動試験を諦めたのは、競技者として失格感がありますね…。

敗因の一つはlogのAPIのbulk送信を見落とすミス

そんな感じで競技が終了し、1位には3倍近くの差をつけられての6位でした。

敗因は、logのAPIのbulk送信を見落としていたことに尽きます。ここの非同期化が必須であることはチームメンバーで見抜けていたのですが、ドキュメントを見落としていたことは痛恨です。

ここさえ気づいていれば、かなり順位をあげられたと思うのですが、そもそもそこをちゃんと読まなかったことが実力不足ということはわかっています。

まとめ

自分が得意だったはずの分野で学生に惨敗してしまったことは、ショックが大きい。去年3位で終えて、もうISUCONは引退しようと思う気持ちもあったが、今回の惨敗を受けて、まだまだ来年もリベンジしようと思った。何より、ISUCON1からずっと本戦に出続けているのは、fujiwaraさんと僕の2人だけなので、そこは負けるまで続けようと思う。

今回は、本当に非の打ち所がない問題と運営だった。バクもなくベンチマークも快適でした。毎年運営のレベルも上がっていて、本当にすごいことだと思う。

LINEさんの運営や、DeNAさん、カヤックさんの問題作成に関しては、予想通り流石だなと感じたのですが、サーバー提供のGMO ConoHaさんもサーバー構成や、人員構成含めすごい体制でのフルコミットだったようで、そこは懇親会などで話を聞いて感服しました。懇親会前の運営企業アピールタイムでもっとそこを押せばよかったのに、とも思ったりしました。

ということで、ISUCON続いて欲しいと思っております。来年も楽しみにしております。

created at
last modified at

2018-11-12T05:08:39+0900

comments powered by Disqus