ISUCON6の予選問題作成メイン担当のSongmuです。皆さん予選はいかがでしたか?至らぬ点もあり申し訳ない部分もありましたが、楽しんでいただけたようであれば嬉しいです。
さて、遅くなりましたがISUCON6予選に使用した参照実装、ベンチマーカー、その他諸々を含むリポジトリを、このエントリと共に公開します。
https://github.com/isucon/isucon6-qualify
問題アイデア出し: Songmu/motemen/wtatsuru コンセプト実装: motemen 初期実装: Songmu 参加者用ポータル作成: motemen ベンチマーカー及びワーカー: Songmu 予行演習解答: edvakf/catatsuy/walf443/st-cyrill Azureアドバイザリ: myfinder/(matsuu) インフラ及びプロビジョニング整備: wtatsuru/y_uuki 言語移植 予選当日のシステム運用・監視: wtatsuru/motemen/Songmu/myfinder その他予選当日サポート: edvakf/catatsuy/walf443/st-cyrill/y_uuki 採点: wtatsuru/Songmu アナウンス全般: 941
参考実装 (
isuda (はてなキーワード・はてな isutar (はてなスターを模したサブアプリケーション) isupam (スパムチェッカー/Go製のバイナリのみ提供)
サーバープロビジョニング (
今回は、予選環境にAzureを使いましたが、AzureではVMイメージの直接の提供が難しい代わりに、Deploy to Azure Buttonという便利な仕組みがあり、それを利用しました。
Deploy to Azure ButtonでVMを設定する場合、内部的には任意のプロビジョニングを走らせることが可能になっていますが、今回はそれにAnsibleを利用しました。そのAnsible Playbook一式を
今回利用したインスタンスは、競技用インスタンスとベンチマーカーともにD2v2インスタンスです。
ベンチマーカー (
Go製です。去年のISUCONのベンチマーカーをかなり参考にしつつ、 https://github.com/catatsuy/private-isu のベンチマーカーをベースに作成しました。
ベンチマークの結果はJSON形式で標準出力にはきだされます。
今回のベンチマーカーシステムは、ワーカーノードのVMを起動すると、ワーカープロセスがポータルにベンチマークジョブを定期的(3秒おき)に取得しにいき、取得できた場合は手元のベンチマーカーコマンドを起動し、その結果をポータルに送信する、といった作りになっていました。
ベンチマークのキュー自体は、ポータルノード上のMySQLのテーブルになっており、ワーカーはWebAPI経由でそのジョブを取得するシンプルな作りです。1VM1ジョブ専有であり、ワーカーノードのVMを新たに起動すれば勝手にスケールする仕組みになっていました。
ワーカーが定期的にポーリングする仕組みはちょっとダサいですが、API側はジョブがない場合に204 No Contentを返し、ジョブを返す場合には200 OKを返すのはちょっとしたおしゃれポイントなんじゃないかと思っています。
ベンチマーカー、ワーカー、ポータル全てでGoを使いましたが、struct定義が使いまわせたおかげでJSONのやり取りが簡単に書けたのが思わぬ功名でした(ポータルはPerlかRubyかなーとか思っていたら、motemenがGoで書いてきたので、怪我(?)の功名だった)。
今回の予選実施の際には、再起動直後にスコアが落ち込むという報告を何件か頂きましたが、この件に関しては原因はよく分かっていません。ちなみに競技終了後の再起動を含む追試においてはスコアが大きく落ち込むようなチームも確認できませんでした。気になる方は公開したコードを元に検証してみてください。
■関連リンク
・ISUCON6 予選問題の解説と講評
さて、遅くなりましたがISUCON6予選に使用した参照実装、ベンチマーカー、その他諸々を含むリポジトリを、このエントリと共に公開します。
https://github.com/isucon/isucon6-qualify
謝辞
問題作成にあたり、多くの人に協力いただきました。以下に役割分担を書き出してみると非常に豪華な面々です。これらの方々の協力なしには予選は開催できなかったでしょう(本当に!)。ありがとうございました。- Go: y_uuki
- Ruby: aereal
- Scala: tarao
- Python/Node: walf443
- PHP: st-cyrill
公開内容の構成について
問題の講評は追っておこないますが、公開した内容について以下に解説していきます。README.md に書かれている内容との重複もありますがご容赦ください。参考実装 (webapp/
)
webapp/以下に各言語の参考実装が含まれています。実装言語は、Perl/Ruby/Python/PHP/Node.js/Go/Scala です。各言語とも以下の3つのプロセスを起動する必要があります。
(:?匿名)?ダイアリーを模したアプリケーション)
サーバープロビジョニング (provisioning/
)
今回は、予選環境にAzureを使いましたが、AzureではVMイメージの直接の提供が難しい代わりに、Deploy to Azure Buttonという便利な仕組みがあり、それを利用しました。Deploy to Azure ButtonでVMを設定する場合、内部的には任意のプロビジョニングを走らせることが可能になっていますが、今回はそれにAnsibleを利用しました。そのAnsible Playbook一式を
provisioning/ディレクトリ以下にそのまま公開しています。環境構築の際の参考にして下さい。
今回利用したインスタンスは、競技用インスタンスとベンチマーカーともにD2v2インスタンスです。
ベンチマーカー (bench/
)
Go製です。去年のISUCONのベンチマーカーをかなり参考にしつつ、 https://github.com/catatsuy/private-isu のベンチマーカーをベースに作成しました。bench/ディレクトリ内で
go buildするとベンチマーカーのバイナリが作られます。以下のようにコマンドを実行するとベンチマークの実行が可能です。
-datadirは
bench/datadirをお使いください。
% ./bench -datadir=data -target=yourhost.example.com
ベンチマークの結果はJSON形式で標準出力にはきだされます。
ベンチマーカーの分散実行について
余談ですが、ベンチマーカーの分散実行について少し。今回のベンチマーカーシステムは、ワーカーノードのVMを起動すると、ワーカープロセスがポータルにベンチマークジョブを定期的(3秒おき)に取得しにいき、取得できた場合は手元のベンチマーカーコマンドを起動し、その結果をポータルに送信する、といった作りになっていました。
ベンチマークのキュー自体は、ポータルノード上のMySQLのテーブルになっており、ワーカーはWebAPI経由でそのジョブを取得するシンプルな作りです。1VM1ジョブ専有であり、ワーカーノードのVMを新たに起動すれば勝手にスケールする仕組みになっていました。
ワーカーが定期的にポーリングする仕組みはちょっとダサいですが、API側はジョブがない場合に204 No Contentを返し、ジョブを返す場合には200 OKを返すのはちょっとしたおしゃれポイントなんじゃないかと思っています。
ベンチマーカー、ワーカー、ポータル全てでGoを使いましたが、struct定義が使いまわせたおかげでJSONのやり取りが簡単に書けたのが思わぬ功名でした(ポータルはPerlかRubyかなーとか思っていたら、motemenがGoで書いてきたので、怪我(?)の功名だった)。
今回の予選実施の際には、再起動直後にスコアが落ち込むという報告を何件か頂きましたが、この件に関しては原因はよく分かっていません。ちなみに競技終了後の再起動を含む追試においてはスコアが大きく落ち込むようなチームも確認できませんでした。気になる方は公開したコードを元に検証してみてください。
まとめ
ということで、ISUCON6の予選問題を公開しました。参加しなかった方も是非挑戦してみて下さい。不明な点があったら気兼ねなくSongmuまでお問い合わせください。ベストエフォートでお応えいたします。■関連リンク
・ISUCON6 予選問題の解説と講評