社内ISUCONを主催した話

12月某日に社内ISUCONを開催し, それなりの盛況を見せて無事終了しました.
「うーんみんなもうちょっと仕事っていうか遊び感覚でコードいじりする楽しみ覚えてもいいし本家のISUCONも出場してほしいよね」程度の軽いノリで開催に至りました.
ノリは軽かったですが楽しかったし勉強になることも多かったのでやってよかったです.


主催・運営は @shuyuhey と2人でやりました.


1. 参加者向けに運営の内情を紹介する
1. これから社内ISUCONを主催・運営してみようかなという人向けに何か参考になる情報を提供できたらいいなあ

ということでこの記事を公開します.

# コンセプト
ISUCON経験なし, Railsエンジニア, インフラ経験ほぼなし, という参加者がほとんどだったので, 以下のようなコンセプトを設定しました.

* 何かいじって試したらスコアが上がって楽しいというのがISUCONの醍醐味だと思ってるのでそれを体験してほしい
* 計測する→いじる→試す→計測するというサイクルを回す体験をしてほしい
* 難易度はISUCON未経験でも十分楽しめるように低め低めで

このコンセプトに従って, 具体的には以下のような作戦を取りました.

* 速度チューニングは敷居が高いかもしれないので, 参考実装にわざとバグを仕込んでおき, バグを修正してもスコアが上がるようにする.
* 一個一個の問題の難易度としては簡単にし, ちょっと計測すればすぐわかるようにする.(ベンチのときだけ遅いとかはできるだけ避けた)
* アプリケーションの改善だけで十分にスコアが伸びるようにする(OS, ミドルウェアに詳しくないとチューニングできないということがないようにする)
* 当日まで問題は秘密だが予習しておいたほうがいいことは事前に参加者に伝えておく

# 準備
準備を開始した段階では, 参考実装・ベンチマーカーさえあれば競技できるだろうと思っていましたが, まともな競技会として成立させるためにはそれなりにドキュメントを用意したりインフラを用意したりと予想外の準備が色々と必要になりました.

## 参考実装
準備時間もそこまで無いしどうせ誰もRuby以外選択しないだろうということでRuby + sinatra + mysql2で作っていきました.  
Ruby + sinatra + mysql2を使うことになるということは事前に参加者に伝えておき, 予習できるようにしておきました.

バグは3つほど埋め込んでおき, API仕様書と実装を比較することでバグの存在に気付けるようにしておきました.

参考実装の作成は特に困ったポイントはなかったですが, 「思ったより遅くないなあ」というシーンは何度かありました.  
気がついたら全部N+1による低速化を施すことになってしまって, 低速化の引き出しを増やしておくというのは運営の今後の課題になりそうです.

## ベンチマーカー
Goで実装しました. Goは並列処理が書きやすくていいですね.

かなり探り探りで実装していくことになりましたが特に困ったのは, レスポンスをどこまで厳密にチェックするかという点と, リクエストの順番次第でスコアが大きく変化する点です.

色々いじくりましたが結論としてはレスポンスの内容チェックは少々甘めにしました. 実装が楽で都合が良かったのと, 最終的には競技終了後の運営目視チェックで失格にすればよかろうという判断でした.  
本家ISUCONのベンチマーカーの実装を見るとかなり頑張ってレスポンスの内容をチェックしているようで, 次回はもっと本家を参考にしつつ良い実装にしていきたいところです.

リクエストの順番等でスコアが大きく変化してしまう点については, ベンチマーカーのリクエスト順のランダム性を極端に減らしました.
これによって参加者はアクセスログを眺めるだけでベンチマーカーの挙動を看破できてしまうことになりましたが, 最悪看破されることはよしとして, スコアの安定性となにより「バグを修正したらちゃんとスコアが上昇する」という点を重視した調整にしました.
ベンチマーカーの実装ではこの調整に一番時間がかかった気がします. 前日まで細かい調整を繰り返していました.

## インフラ
インフラはAWS EC2を使用しました. @shuyuhey がAnsibleおじさんなので一晩でだいたいできてました. 感謝.

### EC2に意図的に負荷かけることになるけどいいの?
[Amazon EC2 Testing Policy](https://aws.amazon.com/jp/ec2/testing/)というものがあって, EC2に対して大きな負荷をかけるテストを行う場合はAWSに事前に申請する必要があります.
今回は参考実装をある程度作った段階でトラフィック量を試算し, 申請が不要であることを確認しました.

どのくらいが「大きな負荷」なのかということも上記のページに書いてありますが, ISUCONのような用途の場合は普通は申請不要なのではないかと思います.

## ドキュメント
地味にこれが大変で, 以下のものを作りました.

* 開会式・閉会式のパワポ
* 事前ドキュメント
    * どんな競技になるのかの説明, バグ修正要素の予告, 予習情報など
* 当日マニュアル
    * インスタンスの操作方法, アプリケーションの起動方法, 採点方法の説明など
* API仕様書
    * 参考実装に求められる仕様, バグのヒント

## ポータルサイト
・・・はめんどくさいので作りませんでした. ベンチマークは運営が手でコマンドを打って実行することにしました.
スコアランキングを表示する画面だけは作っておきました.

# 当日
9チームが参加しました. 制限時間は4時間としました.
ポータルサイトを作っていないので参加者を一つの会議室に集めて, ホワイトボード上にベンチマーク待ちのキューイングシステムを構築しました.

ベンチマーカーの思わぬバグに遭遇するとか, 誰もスコアを伸ばせないとか, ベンチマークが手動だからめちゃめちゃに待ちが発生するとか, 想定外のトラブルがいっぱいおきて競技が成立しないとか, 様々な心配がありましたがスムーズに進行することができました.

再起動試験は9チーム全てに実施することにしましたが, かなり急いでやって40分程度でした. もっとチーム数が増えたら上位チームだけに再起動試験することにしないと時間の都合がつかなさそうです.

## 結果
結局, ベンチマーカーの挙動を看破してあえてバグを修正しなかったチームが優勝を手にしました. 

運営としてはハックのような攻略をされて悔しいが, 初心者に気持ちいい難易度調整を行った結果なのでしょうがないかなという気分でもありました.

# まとめ
参加者がレポを書いてくれたりしました.
https://www.kaqiita.com/entry/2019/12/22/111151
https://qiita.com/koheiyamaguchi0203/items/728e238a33fe4c19eb32
https://taichi0315.hatenablog.com/entry/2019/12/24/105401

参加者アンケートを見た感じでも楽しんでくれたようで運営としても満足です.
参加者も「勉強になりました」と言ってくれましたが, 運営もめちゃくちゃ勉強になったし楽しかったです. いずれ今回の参加者と一緒に運営やりたいですね.

規模が小さければ10日くらいで準備できてしまうので社内ISUCONおすすめです, 参加者にも運営にも学びがある会です.
本家ISUCONのほうも頑張っていきます.