gatling による負荷試験とテレビ露出見積り

表題の通りですが、本記事では次の事項は扱いません。

- gatling の使用方法

目的
----

テレビ露出時にかかる負荷をある程度予測しておくことで、それにかかる費用をできるだけ小さく留めること（最小化とは言いません）。

最小化しようとするとギリギリのラインを攻めるためにかなり厳密に見積もらないといけなくなりますが、そうすると人件費の方が高くつくので本末転倒です。
その計算をするのに僕のリソースをもって 1日かかるなら、1〜2万円多く AWS や GCP に献上した方が他の仕事も進められてみんな幸せです。
従って、本記事での検証は比較的ざっくりです。

構成
----

本試験は、以下の様な構成のアプリケーションを対象に行います。

### AWS

特に特筆すべきことのない、標準的な構成です。
DNS とかはあまり関係ないので抜いています。

- Amazon ELB
- Amazon EC2
- Amazon RDS（MySQL、マスタスレーブ構成）

### ミドルウェア

こちらも Railsアプリケーションの王道です。

- Nginx
- unicorn
- Rails

ミドルウェアの設定は次の通りです。

| ミドルウェア | 項目 | 値 |
| :---: | :---: | :---: |
| nginx | conn./worker | 2048 |
| unicorn | worker processes/cpu | 2 or 3 |


Railsアプリケーションは、多くのリクエストが READ のみで、自然言語による検索を除いて RDB から引いてくるような標準的なアプリケーションです。
明示的なキャッシュ機構は特に持たせておらず、ActiveRecord によるキャッシュ頼みの構成となっています。
自然言語による検索に関しては 3ノードからなる elasticsearchクラスタが責任を持ちます。

## 負荷試験

負荷試験は、以下の 4ステップに渡って実施します。

1. インスタンス単体における負荷試験
2. 非冗長化システム（WEBサーバ1台 + RDS）における負荷試験
3. 冗長化システム（ELB + WEBサーバ複数台 + RDS）における負荷試験
4. チューニングを変えて 1から 3までを繰り返す

### 負荷試験手順

[Gatling](http://gatling.io/#/) を用いて試験を行います。

> Gatling is an open-source load testing framework based on Scala, Akka and Netty
- High performance
- Ready-to-present HTML reports
- Scenario recorder and developer-friendly DSL


```markdown:拙訳
Gatling は Scala、Akka、Netty をベースとしたオープンソースの負荷試験フレームワークです。

- ハイパフォーマンス
- HTML形式のレポート
- シナリオレコーダーと開発者-friendlyなDLS

（という特徴を持ちます）
```

試験に使用するスクリプトは次のようなものです。

https://github.com/Nicogory/samples/blob/master/gatling/simulations/NicogorySim201512161700.scala

自動生成されたものをサンプル用に変形しているのですが、僕は scala に明るくないので文法的に誤りがあれば教えてください。

gatling の使用方法は冒頭で言ったとおり書きませんが、興味のある方は Web上に幾つか素晴らしい記事があるので探してみてください。
`gatling load test` とか `gatling 負荷試験` とかでググればヒットします。

---

基本的に負荷試験は AWS上で行います。
本番で行うと設定によってはサービスが停止するので必ず専用のインスタンスを建ててください。

1. 負荷試験用のインスタンスを1台用意する
2. 試験を実施し、おおよその peek QPS を見積もる
3. インスタンスを一旦停止してインスタンスサイズを拡大し、同時に nginx、unicorn の設定ファイルを書き換える
4. 試験を実施し、インスタンスサイズに関して増加傾向を観測する
5. 複数のインスタンスを用意し ELB に接続する
6. 試験を実施し、台数に関して増加傾向を観測する


#### 注意点

- 負荷はゆっくり上げないと ELB が先にハングアップする気がします
- やり過ぎると当月の AWS使用料金が跳ね上がります

### 検証結果

以上の設定で、t2.small(1vcpu, 2GB RAM) に対して gatling で負荷試験を行いました。
詳細なデータやグラフは割愛するが、注意すべき点は以下の通りです：

| 項目 | 最大値 |
| :---: | :---: |
| #users | 130 |
| cpu usage | 〜70% |

その他は余裕で、完全に cpuバウンドという結果になりました。

## 見積り

上記の試験結果を元に見積りを行います。
以降、式変形が続くため常態の文章になります。

#### 仮定

| 項目 | 値 | 単位数 |
| :---: | ---: | ---: |
| 人口 | 1億3千万人 | $1.3 \times 10^8$ |
| 平均視聴率 | 10% | $10^{-1}$ |
| WEB検索する人の割合 | < 1% | $\lt 10^{-2}$ |
| 平均ページ内遷移回数 | 5回 | 5 |

アクティブユーザーは、

```math
1.3 \times 10^8 \times 10^{-1} \times 10^{-2} = 1.3 \times 10^5
```

より、13万人と予想される。
従って、番組放送中におけるリクエスト数は、$(1.3 \times 10^5) \times 5$ より、65万リクエストとなる。

この内、半数の人が番組開始から 10分以内に訪れるとすると、1秒あたりのリクエスト数は、

```math
\frac{6.5 \times 10^5}{2 \times 10[\mathrm{min}] \times 60} < 500 [\mathrm{req/sec}]
```

となるため、1,000[req/sec] くらい捌ければ十分そうである。

## まとめ

以上より、1vCPU で 100 [req/sec] 捌けるとすると、単純に 10vCPU くらいあれば耐えられそうです。
これに安全係数をかけて、v8 * 2台構成くらいであれば大丈夫そう、という見積となりました。
シミュレータで確認したところ、2時間で 1万円くらいですね。
体感でもまぁこんなもんかなという感じなので、この構成で行きます。


## 後日談（テレビ露出中のアクセス・負荷解析）

Google Analytics を使ってリアルタイム解析をしていました。
結局、分単位の丸め値で最大 800ユーザーくらい断続的にアクセスが来ていました。
サービスはどれもダウンしなかったので、見積もりはおおよそ正しかったのかと思います。

## おまけ

[GCP で Autoscaling Groups を使う](http://qiita.com/chase0213/items/6cad4475a5b57895aca1)