双六工場日誌

平凡な日常を淡々と綴ります。

今更ながらの #isucon 3 参加報告:「isuconに勝てる銀の弾丸などなかった」

isucon参加ブログ書こうと思いつつ、転職・引っ越しとバタバタした日々が続いて、すでにisucon3から1ヶ月経ってしまいました。。。

今更感もありますが、遅ればせながら自分なりの反省エントリを書いておきます。

予選トップで通過したのに、本戦では惨敗...orz

 まず結果ですが、僕たちのチーム「勝浦タンタンメン」は、本戦は最終計測でスコアが出ずFAILし、あえなく惨敗いたしました…orz 負けた原因も完全に実力不足で、なんの言い分できないほど、完膚なきまでの敗北です。

 どのようにしたら勝てたのかは、@ 氏のエントリや公式の関連エントリまとめを見てみてください。また、isucon 3を体験できるAMIも公開されているので、問題自体はそちらを見てみてくださいませ。

 僕たちのチームは、予選ではフロントで捌く戦術がうまくハマって、スコアトップで予選通過することができましたが、本戦は小手先の技だけではどうにもできない良問*1で、自分たちの道具立てでは、ベンチマークのスコアも伸ばすことができないまま時間切れ。

 ちなみに、本戦は予選突破した25チームのうち、7チーム以外はベンチマークを完走することもできないという、死屍累々のハードコアなイベントでした。

 せめて動くようにできればよかったのですが、最後の方は浮足立ってしまって、動かすことすらかないませんでした…

反省点

 このような結果となった理由は、細かく上げればいろいろあるのですが、自分としての大きな反省点は、以下の2つです。

制限事項の理解と適切なアーキテクチャの選定ミス

 結果として、isucon 3で勝負を決めたのは、初期段階でのアーキテクチャ選定だったと思います。

 優勝チームは、フロント側のネットワーク帯域に100Mbps制限がかかっていることから、フロント4台、バックエンド1台構成にすることを、午後の早い段階で決めたと言っていました。

 チューニングでは、「推測するな計測せよ」が基本的な心構えだと言われることが多いですが、アーキテクチャから考えないといけない状況では、

  • 与えられた環境からどこがボトルネックになりやすいのか
  • どの程度のレスポンスタイム/スループットを出しうるのか

といったことを与えられた環境から割り出して、それを踏まえて動き出すことが重要でした。

 優勝チームの結果を見ると、以下の2つが今回の課題のボトルネックでした。

  • 画像変換のCPUボトルネック
  • フロントのネットワーク帯域のボトルネック

 特に自分では、フロントの100 Mbps制限がどれだけのものか肌感覚でわかっておらず、逆にディスクIOボトルネックの発生を気にしてしまって、考えのとっかかりとしてデータの分散配置を考える方に考えが向いてしまい、失敗しました。

 経験不足から、この辺りのことを肌感覚でわかっていなかったために、初動のところでコケてしまうことになりました。

チーム力の課題

 もう一つの反省点は、チーム力です。

 もし正しいアーキテクチャを考えられたとしても、それを実装しきるためのチーム力が必要がなければ勝つことはできません。特に、今回は課題のアプリが高度だったため、方針が決まっても、それをチームで分担して実装しなければ時間内に必要な修正を行い切ることは難しくなっていました。

 正直なところ、初動が正しかったとしても、自分たちのチームではそれを実装しきることはできなかったと思います。

 自分たちのチームは、会社もバラバラの混成チームで、ここは開催当初から課題でした。そのため、一度、isucon 2の問題を一緒に解く一旦合宿までやったのですが、当日の課題からすると、この程度の付け焼き刃のチームワークでは太刀打ちできませんでした。

 これまでの優勝チームの話を聞くと、チームメンバーが実際に何をやったのかはお互いに確認せずに作業していたとのこと。このぐらいの阿吽の呼吸ができれば理想でしたね。。。

自分がやろうとしたこと

 ということで、反省の多い本戦でしたが、自分がやろうとして失敗したことも書いて起きます。僕は、フロント2〜3台、アプリ・バックエンド2〜3台の構成で、以下のようなことをやろうとしました。

  • フロントは、Nginxをリバースプロキシとして置いて、バックエンドを "hash $request_uri;" で振り分ける
  • (結果としては動くところまで行きませんでしたが)動くところまで言ったら、フロントとアプリ・バックエンドの数を調整する

 この構成の利点は、バックエンドへの振り分けをURIごとに固定できるため、フロントのNginx複数台おいてもURIごとに決まったバックエンドを向くようにできることです。バックエンド2台ならば、配信対象コンテンツをメモリ上に載せることができるとの読みからです。

 ただ、この構成は最後まで動かし切ることができませんでした。この構成でアプリの初期状態だと、あとからPOSTされてくる画像は、一つのバックエンドに集中してしまう問題がありました。

 だんだん終了時間が迫ってきたので、見切り発車でこの変更を開始して、インフラだけ入れ替えたものの、対応するためのアプリの改修が間に合わずアウト。。。

 結果を見ると、これでディスクIOを減らしたところで影響はそれほど大きくなかったと思いますが、せめて動くようにはしたかったです。これは自分との闘いの部分なので、非常に悔しい。

 あとは、予選の印象からNginx側で捌くという発想が抜けず、冷静にレギュレーションを読んでアーキテクチャを検討できなかったのも、反省点です。変なところにこだわって、トリッキーなことをするよりは、可能な限りシンプルに済ませる方に頭をつかうべきでした。

まとめ

 isucon 3は、インフラ、アプリの総合力に加え、チーム力が問われる非常にいい大会でした。負けて非常に悔しい思いをしましたが、実力不足だったと言うしかないです。これだけの問題を用意してきた藤原さんにも完敗です。

 最後は、トリッキーなことをしてでも何とかしようとあがきましたが、状況を打開できるような「銀の弾丸」などなく、基本的なことをちゃんとやり切ったLINE選抜が圧倒的な強さで優勝しました。

 ただ、負け惜しみみたいになってしまいますが、本戦に参加できただけでも十分楽しかったです。負けたこと自体は、今でも悔しくて仕方ないですが、そう思えるのもisuconだからこそだと思います。

 こんな風にガチで技術勝負をして、出来上がったシステムの速い順に順番をつける誰から見てもわかりやすい勝負はいいですね。エンジニアの力は、普段はなかなか表に出てこないので、世の中にエンジニアの価値を知ってもらう上でもいい影響が出ているようにも思います。

 来年はまだどこがどうやるのか決まっていませんが、歴代優勝者が参加者として参加する頂上決戦があるとの噂もあり、非常に楽しみです。

 最後になりますが、主催のカヤックのみなさま、LINEのみなさま、DATAHOTELのみなさま、そして、予選・本戦とともに素晴らしい出題をしてくださった出題チームのみなさまに感謝を。ありがとうございました!

 反省点を噛み締めて、来年は、本戦でももう少しいい勝負ができるよう、この一年精進したいと思います。

 それでは、この辺で。

*1:予選の問題が悪いということを言っているわけではなく、予選は参加者の選抜という目的では非常によく出来た問題だったと思っています。本戦の問題は、本戦にふさわしい良問だったということです。念のため。