ISUCONのすゝめ

[フューチャー Advent Calendar 2018](https://qiita.com/advent-calendar/2018/future) 20日目の記事です。昨日は@tarosaibaさんでした。

　弊社フューチャーには社内に競プロ部が存在するほど、競技プログラミングが好きなエンジニアたちがたくさんいるようですが、その方たちのためにISUCONを紹介し、参加を促したいと思います。

# ISUCONとは
> お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それがISUCONです。 — [ISUCONトップページから](http://isucon.net/)

　上記の通り、予め用意されたWebサービスをいい感じに(**I**ikanjini)高速化する(**S**peed **U**p)コンテスト(**CON**test)、略してISUCONになります。

競技プログラミングと違うところといえば、

- チームで戦う(１〜3人)
- すでに作られてるシステムを改善する
- プログラミング以外のスキルも必要
- **プログラマーだけじゃなくインフラエンジニアも参加できる**

といったところでしょうか。
個人的には最後のインフラエンジニアとして戦うことができるところが特にISUCONの魅力かなと思います。

あとは下記のスライドもいい参考になると思います。
[ISUCONの勝ち方 YAPC::Asia Tokyo 2015](https://www.slideshare.net/kazeburo/isucon-yapcasia-tokyo-2015)
Youtube版：https://youtu.be/vl1mYTq1ZYI

## もっと具体的に(レギュレーションなど)
　回を重ねるに連れ、毎年多少変わって来たりしますが、とりあえず直近で参加したISUCON8を基準に説明します。
参加した回と過去問から経験則で書いてるので、来年も下記のようなシステムがお題になるとは限りません。

### システム構成
- Web Server(Reverse Proxy)
- Application Server
- Database

　Webサービスでよく見かける3層構造が多かった印象です。
サーバーの台数は直近では3台まで自由に使えましたが、以前は1台だけだった回もあったらしいです。

### 参考実装(アプリケーション)
　不特定のクライアントからの大量のリクエストをさばくシステムをチューニングするという観点から、BtoCのWebサービスが用意されると思います。
言語はWebサービスでよく使われがちな下記の言語などから好きなものが選べます。

- Perl
- PHP
- Python
- Go
- Ruby
- Node.js
- その他

### 制限時間
　本選は経験がないのでわかりませんが、予選だと朝10時から18時までの8時間で、1日をまるっと使う感じです。実際やってみるとこの8時間は焦りと不安などが重なり、とても短く感じると思います。どれほど集中力とメンタルを維持できるかがポイントといったところでしょうか。

### 環境
　予選ではリモート参加、本選は会場参加が原則のようです。予選でも会場提供があったりしますが、そういった環境では自分みたいな豆腐メンタルの持ち主だと思わずビビってしまうので、予選はホテルの部屋でもとって落ち着いた環境で挑みたいところです。
　開発環境としては、お題のシステムはチームごとに与えられたインスタンスにデプロイ済みで、参加者各自が用意したパソコンでSSHなどを利用してチューニングしていく感じです。

### 評価方法
　チューニング対象のサーバーとは別に、ベンチマークサーバーが用意されます。ベンチマーカーを起動すると、対象サーバーにリクエストを大量に送るなどしてパフォーマンスが計測され、スコアが記録されます。もし仕様変更などレギュレーション違反になった場合、0点扱いになります。時間内ならばベンチマークは何回も起動可能です。

# 勝ち進めるには
　1回しか参加してない、しかも予選で爆死した自分ですが、一回経験してみてここがポイントかなといったところを書いてみました。

## 個人の能力
　当たり前ですけどパフォーマンスチューニングする上での知識・判断力・手の速さ・メンタルなど、個々人の能力は大事です。アプリ側だったらアプリケーション・サーバー設定くらいは自分でできたり、インフラ側だったらアプリのロジックを把握した上で最適なチューニングができたりなど、互いの領域の知識がある程度備わっていた方がいいと思います。

## チームワーク
　一人参加で高スコアを引き出す化け物みたいな方も少なからずいらっしゃるようですが、自分のような凡人にはチームがないとISUCONは太刀打ちできません。3人のチームを作ったとしても、コミュニケーションコストがかかるし、何より制限時間があるので効率よく動くために、方針決定・役割分担・フィードバックループなどのチームワークが上記の個人能力以上に重要なポイントになります。なので普段業務で一緒にやっているメンツで構成するとかなり有利になると思います。
好ましいチーム構成としてアプリ1人・インフラ1人・全体を眺めつつアプリ・インフラ両方できる万能型1人ってところでしょうか。

## 事前準備
　デプロイ用リポジトリ・ツールの選定・ミドルウェアセッティング用「秘伝のタレ」・作業フローなど、事前準備もいいスコアを出すためには不可欠です。監視ツール・コミュニケーションツールなどの選定とか、複数人で修正が必要なファイルをどう分割して改修し、新しいバージョンをリポジトリからどうやってデプロイしていくかなどのDevOps戦略など、普段の業務でも重要なポイントがISUCONにも必要になります。
過去問を解いて実戦をシミュレーションしてみるとかは当たり前ですね。

# チューニングの勘所
　人によってISUCONの参考実装はびっくりするほどアレなシステムが用意されます。よくありがちなアンチパターンから本当にどうでもいいtypoまで、ありとあらゆる罠が各所に散りばめられています。しかし、大会の雰囲気に飲み込まれメンタルが崩壊してしまうと、出来て当たり前のことどころか、パフォーマンスになんの影響も及ぼさないどうでもいいtypoに足元すくわれたりするものです。そのあたり前のことかも知れないいくつかのチューニングの勘所についてざっくり。

## システムロジック
　ISUCONのお題となる参考実装は、出題される会社さんが過去に作ったサービスのダメだった実装をベースにしているのが多いかなと思います。それにはどんな歴史的経緯があり、どうリファクタリングして高速化ができたかというノウハウがスコアアップにつながる場合も多いと思います。

### Database
　いわゆるスロークエリ問題。N+1問題、Indexチューニング、デッドロック、そもそものテーブル設計問題などが、アプリ側から高速化を図る上で避けられないかつ勝負どころなんじゃないかと思います。「**ファイルはメモリより遅い**」という命題をしっかり理解した上でそのパフォーマンス上の不整合をどう補えるかがポイントとなるでしょうか。対策としてはSELECTクエリの最適化・遅延書き込みなど、各問題に対しての正攻法ももちろん効果的ですが、オンメモリ戦略など普通の客向けサービスではできないが、ISUCONのベンチマーカー向けの短期対策としては効果的な奇策が功を奏する場面があったりします。
　個人的には@kazeburoさんが上記のスライドなどで仰った「**心にいつもB+Treeを**」がかなり刺さりました。

### 静的ファイル配信
　CSS/JS/画像ファイルをどうやって配信するか。キャッシングやCDNまで関わるとインフラ側と協力して策を練る必要があったり、gzipで圧縮したり、HTTPヘッダーの調整が必要だったり、結構やることが多いのに後回しにされがちな印象です。HTMLテンプレートのコンパイル問題もこちらの領域になるんでしょうか。

## Caching
　クライアント・サーバー・クエリなど、様々なところでのキャッシング処理はスコアアップにやはり不可欠でしょう。memcached/Redisなどをデータストアとして使うことで、上記のDB問題において更なる改善の可能性が出てきます。

## サーバー設定
　Webサーバー・アプリケーション・サーバー・DBとしてどのミドルウェアを使うか、そのミドルウェアの設定、カーネル設定などいろいろあるみたいですが、自分はインフラに弱いのでコメントでいただけたらと…

## サーバー負荷分散
　複数のサーバーが与えられた場合、各サーバーのCPU/Memなどのリソースを効率良く使うために、システム全体にかかる負荷をどう分散させるかなどインフラ設計のところ。インフラ弱いのでやはり割愛します。

# 過去の問題
過去8回のISUCONのお題は有志により作られたリポジトリを使うとVagrant上でデプロイすることができます。もちろんアプリソースコードなども公開中なので、自分で用意したインスタンスなどにデプロイすることも可能です。

https://github.com/matsuu/vagrant-isucon

　その他にもPixivなど多くの会社が高速化のノウハウを共有するために、社内ISUCONを開いて公開中なので、ぐぐってみたらいろいろと出てくると思います。

# 最後に
　以上、ISUCONについていろいろ書いてみましたが、いかがだったでしょうか。ISUCONはある意味、普段の業務の延長を縛りプレイでやる大会でもあるので、嫌な響きで聞こえたという方がいらっしゃるかもしれません。しかし、普段の業務のスキルに関わる大会だからこそ、「オイラこそ誰よりも一番仕事がうまいんだぞ！」と意気込んでるエンジニアや、もっと業務に必要なスキルを伸ばしたいエンジニアにとっては絶好の機会なんじゃないかなと思います。そうでない方であっても、一回参加してみたら自分の中でなにか燃え上がるものを感じられると思いますので、皆さん是非一度挑戦してみてください。

明日は@tsukammoさんです。