GoogleCloudSQLの第一世代・第二世代のベンチマーク比較

# あらまし
なんか気づいたらCloudSQLに「第二世代」って項目が追加されていたので
うっかりベンチマークをとってみた。
![image](https://qiita-image-store.s3.amazonaws.com/0/51208/a156f390-f665-54be-d60d-b65a97cb18f0.png)

# 検証
VMからCloudSQLに対してsysbenchを実行してqpsを見てみる。
従来の第一世代・新しくできた第二世代のCloudSQLで比較する。

## 検証環境の作成

### ベンチ用VMの構築
DeveloperConsoleを使用。
公式のdebian-wheezy-backportのimageを使ってVMを作成。
スペックはn1-standard-2
sysbenchとmysql-clientをinstall。

```sh
$ sudo apt-get install sysbench
$ sudo apt-get install mysql-client
```

### CloudSQLの構築
DeveloperConsoleを使用。
設定は変更せず構築。
構築後、ベンチ用VMからアクセスできるよう、VMのExternal_IPを
承認済みネットワークに追加。

**第一世代での設定画面**
![image](https://qiita-image-store.s3.amazonaws.com/0/51208/39deb69d-c685-aef4-3636-46a943f80d8f.png)

**第二世代での設定画面**
![image](https://qiita-image-store.s3.amazonaws.com/0/51208/fc90ffc8-9382-1207-6ce4-d0fe55afc304.png)

### CloudSQLへのdatabase設定
第一世代・第二世代のCloudSQLに接続し、それぞれ以下SQLを実行し
databaseとsysbench用userを作成する。

```mysql
mysql> CREATE DATABASE sbtest;
mysql> GRANT ALL ON sbtest.* TO 'sysbench'@'%';
mysql> SET PASSWORD FOR 'sysbench'@'%' = PASSWORD('sysbench');
```

### CloudSQLへのtest data作成
1GBのデータを作成。

```sh
$ sysbench --test=oltp \
  --mysql-table-engine=innodb \
  --oltp-table-size=1000000 \
  --db-driver=mysql \
  --mysql-user=sysbench \
  --mysql-password=sysbench \
  --mysql-host=<CloudSQLのIP> \
  prepare
```

## ベンチの実行
read-onyl,read-writeの2パターンでベンチを実行。

### read-only
```sh
$ sysbench  --test=oltp \
  --oltp-table-size=10000 \
  --num-threads=4 \
  --oltp-test-mode=complex \
  --mysql-user=sysbench \
  --mysql-password=sysbench \
  --mysql-host=<CloudSQLのIP> \
  --oltp-read-only \
  run
```

### read-write
```sh
$ sysbench  --test=oltp \
  --oltp-table-size=10000 \
  --num-threads=4 \
  --oltp-test-mode=complex \
  --mysql-user=sysbench \
  --mysql-password=sysbench \
  --mysql-host=<CloudSQLのIP> \
  run
```

# 検証結果
sysbenchの `OLTP test statistics:read/write requests` の値を比較。
## read-only
第二世代が2倍以上のqpsを出している。速い。

|CloudSQLの世代| read/write requests (qps) | 
|---|---:|
|第一世代 | 1904.60 |
|第二世代 | 3923.71 |

## read-write
第二世代が3倍以上のqpsを出している。めっちゃ速い。

|CloudSQLの世代| read/write requests (qps) | 
|---|---:|
|第一世代 | 1015.72 |
|第二世代 | 3117.38 |

# 結論
第二世代のCloudSQLはめっちゃ速い。

で、終わっちゃうのは気持ち悪いので、もうちょい突っ込んでみる。

# 突っ込んで調べる
## 第一世代と第二世代のスペック比較
今回デフォルト設定で構築したが、スペックとしては以下。

**第一世代:D1 (CPU不明,0.5GB RAM)**
**第二世代:db-n1-standard-1 (1vCPU,3.75GB RAM)**

メモリ量が違いすぎる。
そりゃ第二世代のCloudSQL速いだろ、って話だ。

## 第二世代のmemory sizeを第一世代D1相当に合わせてベンチを比較
第二世代のVM構築時に `db-f1-micro (1vCPU(shared),614.4MB RAM)` を選択。
同様にベンチをかけた結果がこちら。

|CloudSQLの世代| read/write requests (qps) | 
|---|---:|
|第一世代(前述の値) | 1904.60 |
|第二世代(db-f1-micro) |  722.52 |

|CloudSQLの世代| read/write requests (qps) | 
|---|---:|
|第一世代(前述の値) | 1015.72 |
|第二世代(db-f1-micro) |  600.31 |

メモリサイズは同等なのに第二世代のほうが明らかに遅い。
（むしろdb-fn-microのほうが100MB程度多い）

# メモリサイズが一緒なのに何故遅いのか。
DBのチューニングといえばメモリ。**※個人の見解です**
ということでメモリチューニングでまず見るべき`innodb_buffer_pool`を見てみる。

## 第一世代 D1

```mysql
mysql> show variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 402653184 |
+-------------------------+-----------+
1 row in set (0.00 sec)
```

## 第二世代 db-f1-micro

```mysql
mysql> show variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 123731968 |
+-------------------------+-----------+
1 row in set (0.01 sec)
```

第一世代(D1)が384MB、第二世代(db-f1-micro)が118MB。
第二世代のほうが割り当てが全然小さいなこれ。そりゃ遅いよ。

ちなみに第二世代(db-n1-standard-1)の`innodb_buffer_pool_size`は2GB程度。
そりゃ桁違いに速いよね。

## 第二世代 db-n1-standard-1

```mysql
mysql> show variables like 'innodb_buffer_pool_size';
+-------------------------+------------+
| Variable_name           | Value      |
+-------------------------+------------+
| innodb_buffer_pool_size | 2132803584 |
+-------------------------+------------+
1 row in set (0.00 sec)
```

なおMySQL5.6ベースなので`innodb_buffer_pool_size`は動的には変更できない。残念。

```mysql
mysql> set global innodb_buffer_pool_size = 402653184;
ERROR 1238 (HY000): Variable 'innodb_buffer_pool_size' is a read only variable
```

# あらためて結論
DeveloperConsoleからデフォルトで構築したら第二世代のCloudSQLのほうが速い。
ただし速いのはスペック(メモリサイズおよび`innodb_buffer_pool_size`)が大きいから。 
beta版からGAになり、料金がでないとパフォーマンスに対するコストは現在のところ判断できなさげ。

現場からは以上です。