ほんま正直、Cloud Spannerのウォームアップの指標、真剣に検証しました。そこに関して何の嘘もありません。包み隠さず全て話します。

[グレンジ Advent Calendar 2019] をやるんですね、
正直、めちゃくちゃ悩みました。そしてほんまに真剣に、真剣に検証を重ねて気づいたんです。
[Cloud Spanner]、感動しました。そこに関して何の嘘もありません。
その強さ、がどこから来たのか…

包み隠さず全て話します。

## Cloud Spanner ウォームアップの重要性

### ノード
[Cloud Spanner] は、全体の  **CPU 使用率を 65% 以下** に抑えるため、十分な数の Cloud Spanner ノードのプロビジョニングが必要になります。
コールド状態の Cloud Spanner は、事前にウォームアップしておかないと、リリースに必要なノードが提供されません。

### [データベースのスプリット]
**スプリット**は、Cloud Spanner でのデータの単位です。
Cloud Spanner は複数のノードをフル活用するためにテーブルを自動的に Split に分割します。

スプリットは、以下の条件で分割されます。

-  **Size-dased splits** 
    - データサイズによる分割
    - 数GB程度でテーブルをスプリット
-  **load-dased splits** 
    - 負荷による分割
    - 分散できる負荷でスプリット

十分なスプリットが作成されることで Cloud Spanner の全ノードが活用され、
Cloud Spanner の最大のパフォーマンスを得られます。

負荷試験、リリース前には、Cloud Spanner をウォームアップし、十分なスプリットを作成する必要があります。

## Cloud Spanner ウォームアップの指標

スプリットの条件は、 **Size-dased splits** と  **load-dased splits** がありますが、
実際にどのタイミングでテーブルが分割されるかの保証はないとされています。

ただし、負荷試験の方法としては、
[超実践 Cloud Spanner 設計講座 slide 20]
> Cloud Spanner の負荷試験を行う場合に、5分ではなく20〜30分の負荷試験をオススメします。その理由は、データの容量が多くなることにより、Split がより多く発生して、データが正常に全ノード間に分散されるからです。

とされているので、こちらに沿って検証していきます。

また、[超実践 Cloud Spanner 設計講座 slide 20] にある
 [Google Cloud metrics #spanner]の **api/api_request_count** に注目します。

## Cloud Spanner ウォームアップの検証

負荷試験ツールは [locust] を使用します。

負荷試験の条件は以下です。

- 負荷試験の一回の実施時間は30分
- 秒間 2000〜30000 requests
- Cloud Spanner ノード数は同一

参考にする Cloud Spanner の Metric は、

- API request rate
    - api/api_request_count
- Request latencies
    - api/request_latencies

負荷試験シナリオ構成

- 負荷試験のシナリオの前半に高負荷のAPIが実行されます
- 負荷試験のシナリオはランダムに実行されます

### 負荷試験 1回目

1. データベースを新規作成
2. テーブル作成
3. 負荷試験実施

負荷試験実施後、
[Stackdriver Monitoring] で Cloud Spanner の Metric を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217081/33927892-dd62-332c-b11f-f4dbfa432383.png)

左図が API request rate、右図が Request latencies p99 です。

API request rate のグラフをみると、5:27 ごろまで安定せず、5:30 を超えたあたりから安定しました。
5:27 ごろまでは、[超実践 Cloud Spanner 設計講座 slide 20] の通り、スプリットを作成していて、5:30を超えるとスプリットの作成が終わり、安定しているようにみえます。

Request latencies p99 のグラフでも 5:27 ごろまでのレイテンシは安定せず、5:30 を超えたあたりから安定してきました。
5:27 ごろまでのExecuteStreamingSql、Commitは数秒かかるものがありましたが、
5:30 を超えたあたりから  ExecuteStreamingSql が 30 ms、Commit が 10〜13 ms と安定しました。

### 負荷試験 2回目

Stackdriver Monitoring で Cloud Spanner の Metric を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217081/76dd0163-a465-5f86-9811-efede24031ba.png)

API request rate のグラフを 1回目と比較をすると前半(6:15 ごろまで)のグラフが1回目と比較すると、緩やかであることがわかります。

Request latencies p99 のグラフについては、
Request latencies p99 のグラフでも 6:15 ごろまでのレイテンシは安定しませんが、1回目で数秒かかっていたのが、数ミリ秒になっているのが確認できます。
その後は、ExecuteStreamingSql が 30 ms、Commit が 10〜15 ms と安定しました。

### 負荷試験 3回目

Stackdriver Monitoring で Cloud Spanner の Metric を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217081/0d6d4628-8eb5-6099-6c41-2914cc0477a9.png)

API request rate のグラフは、2回目と大差ないことが確認できます。
Request latencies p99 のグラフは、ExecuteStreamingSql が 30 ms、Commit が 10〜13 ms と安定しています。

## 負荷試験の結果から

負荷試験 1回目の  **API request rate のグラフ** に着目すると、安定したグラフになってから、
 **Request latencies p99**  が 1回目、2回目、3回目とほぼ大差ないレイテンシになっています。
1回目の API request rate のグラフが安定したころから Cloud Spanner のウォームアップが完了したと考えても問題なさそうに思います。

負荷試験の2回目と、3回目の Request latencies p99 のグラフに差異が見られますが、
アプリケーションのp99のレイテンシを比較したところ大きな差異が見られなかったので、負荷試験シナリオのランダム性の偏りによるものと考えます。

## Cloud Spanner ウォームアップの指標

Cloud Spanner ウォームアップの仕方は各社様々あると思いますが、
Stackdriver Monitoring で確認できる、 Cloud Spanner の Metric  `API request rate`  がウォームアップの一つの指標として参考になれば幸いです。:rose:

## 参考
- [Cloud Spanner]
- [データベースのスプリット]
- [ゲーム データベースとして Cloud Spanner を使用する場合のベスト プラクティス]
- [超実践 Cloud Spanner 設計講座]
- [『ドラゴンボール レジェンズ』の舞台裏を支える Google Cloud]
- [株式会社コロプラ『GKE と Cloud Spanner が躍動するドラゴンクエストウォーク』第 9 回 Google Cloud INSIDE Game & Apps]
- [Google Cloud metrics #spanner]


[グレンジ]: https://www.grenge.co.jp/
[グレンジ Advent Calendar 2019]: https://qiita.com/advent-calendar/2019/grenge
[Cloud Spanner]: https://cloud.google.com/spanner/?hl=ja
[Stackdriver Monitoring]: https://cloud.google.com/monitoring/?hl=ja
[データベースのスプリット]: https://cloud.google.com/spanner/docs/schema-and-data-model?hl=ja#database-splits
[ゲーム データベースとして Cloud Spanner を使用する場合のベスト プラクティス]: https://cloud.google.com/solutions/best-practices-cloud-spanner-gaming-database?hl=ja
[株式会社コロプラ『GKE と Cloud Spanner が躍動するドラゴンクエストウォーク』第 9 回 Google Cloud INSIDE Game & Apps]: https://www.slideshare.net/GoogleCloudPlatformJP/gke-cloud-spanner-9-google-cloud-inside-game-apps
[超実践 Cloud Spanner 設計講座]: https://www.slideshare.net/HammoudiSamir/cloud-spanner-78081604
[超実践 Cloud Spanner 設計講座 slide 20]: https://www.slideshare.net/HammoudiSamir/cloud-spanner-78081604/20
 [『ドラゴンボール レジェンズ』の舞台裏を支える Google Cloud]: https://cloud.google.com/blog/ja/topics/customers/behind-the-scenes-with-the-dragon-ball-legends-gcp-backend
[locust]: https://locust.io/
[Google Cloud metrics #spanner]: https://cloud.google.com/monitoring/api/metrics_gcp#gcp-spanner