EC2のインスタンスストアとEBSでのElasticsearchの性能差を比較

## 動機
AWSのEC2には、EBSの他にインスタンスストアがあります。EBSは仮想マシンとネットワークを通して通信しますが、インスタンスストアは仮想マシンが起動したハードウェアのディスクを使いますので、その分高速であるとAWSのドキュメントには書かれています。
その代わりインスタンスストアは一旦仮想マシンを停止して再度起動するとデータは失われますので、永続化が必要なデータストレージとしては使えません。

今回はデータストアにはElasticsearchを使い、データの永続化は無いけど、5分おきに1000万オブジェクトが送られてきて、それを5分おきに書き込みながら読み込みクエリに応えるようなアプリを想定。
5分おきに元になるデータが送られてくるので永続化は必要ないけど、書き込みやインデックス作成が忙しい感じのアプリ。

そういうアプリでElasticsearchを使う場合、EC2のEBSよりインスタンスストアのほうが高速なんじゃないかと適当に想定してみたけど、ほんとにそうかわからんので実際に計測してみます。

## Rallyとは

RallyはElasticsearchのベンチマークを取るためのオープンソースソフトウエア。
ベンチマークだけでなく、自動で指定したバージョンのElasticsearchをセットアップしてくれるので非常に楽ちん。

* [Rally登場：Elasticsearchのベンチマークツール](https://www.elastic.co/jp/blog/announcing-rally-benchmarking-for-elasticsearch)
* [elastic/rally](https://github.com/elastic/rally)

## テスト環境、仮想マシンのスペックなど

* ap-northeast-1（東京リージョン）
* インスタンスタイプ: c6gd.4xlarge
* ルートパーティション： EBS（gp3 3000iops）, 100GB
* 追加パーティション： インスタンスストア, 884GB
* OS: Ubuntu 20.04LTS

## EC2にインスタンスストアをマウント

`lsblk`で状況確認。

```
$ lsblk

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0         7:0    0   25M  1 loop /snap/amazon-ssm-agent/4046
loop1         7:1    0 61.9M  1 loop /snap/core20/1242
loop2         7:2    0 42.2M  1 loop /snap/snapd/14066
loop3         7:3    0 67.2M  1 loop /snap/lxd/21835
loop4         7:4    0 55.5M  1 loop /snap/core18/2253
nvme1n1     259:0    0 69.9G  0 disk 
nvme0n1     259:1    0   75G  0 disk 
└─nvme0n1p1 259:2    0   75G  0 part /
```

`nvme1n1`にパーティションがないので、これがインスタンスストアの模様です。
続いてEXT4でフォーマットします。

```
$ sudo mkfs -t ext4 /dev/nvme1n1
```

`/data` にマウントポイントを作ってマウントします。

```
$ sudo mkdir /data
$ sudo mount /dev/nvme1n1 /data
```

```
$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0         7:0    0   25M  1 loop /snap/amazon-ssm-agent/4046
loop1         7:1    0 61.9M  1 loop /snap/core20/1242
loop2         7:2    0 42.2M  1 loop /snap/snapd/14066
loop3         7:3    0 67.2M  1 loop /snap/lxd/21835
loop4         7:4    0 55.5M  1 loop /snap/core18/2253
nvme1n1     259:0    0 69.9G  0 disk /data
nvme0n1     259:1    0   75G  0 disk 
└─nvme0n1p1 259:2    0   75G  0 part /
```

無事、インスタンスストアが `/data` にマウントされたようです。
`/data` 以下はインスタンスストア、それ以外はEBSになります。

## Rallyのセットアップ

必要なものをインストールします。

```
$ sudo apt install openjdk-8-jdk
$ sudo apt install python3-pip
$ pip3 install esrally
```

JAVA関係の環境変数を設定。

```
$ export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")
$ export JAVA8_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")
$ export PATT=$PATH:$JAVA_HOME/bin
```

## 実行

```
export PATH=/home/ubuntu/.local/bin:${PATH}
esrally race --distribution-version=6.0.0 --track=geonames
```

### EBSでベンチマーク

まずはデフォルト設定で実行。デフォルトでは `$HOME/.rally` 内でテストするのでEBSを使うことになります。

```
$ esrally race --distribution-version=6.0.0 --track=geonames

    ____        ____
   / __ \____ _/ / /_  __
  / /_/ / __ `/ / / / / /
 / _, _/ /_/ / / / /_/ /
/_/ |_|\__,_/_/_/\__, /
                /____/

[INFO] Race id is [aafc91d3-b4bd-43ce-82c3-7caf44b01c41]
[INFO] Preparing for race ...
[INFO] Downloading Elasticsearch 6.0.0 (26.7 MB total size)                         [100%]
[INFO] Downloading track data (252.9 MB total size)                               [100.0%]      

（...省略...）

----------------------------------
[INFO] SUCCESS (took 4802 seconds)
----------------------------------
```

### インスタンスストアでベンチマーク

次はインスタンスストアでベンチマークを取ります。 `~/.rally/rally.ini` の設定を変更し、インスタンスストアで実行されるようにします。

```~/.rally/rally.ini
[node]
#root.dir = /home/ubuntu/.rally/benchmarks
#src.root.dir = /home/ubuntu/.rally/benchmarks/src

root.dir = /data/rally
src.root.dir = /data/rally/benchmarks/src

```

保存したら同様にベンチマークを実施。

```
$ esrally race --distribution-version=6.0.0 --track=geonames
```

## 結果

結果はそれぞれのディレクトリに出来てて、このままでは比較できないので最初に実施したベンチマーク結果をコピーします。

```
$ cp -a ~/.rally/benchmarks/races/aafc91d3-b4bd-43ce-82c3-7caf44b01c41 /data/rally/races/

```

するとベンチマークのリストが２つになります。

```
$ esrally list races


Race ID                               Race Timestamp    Track     Track Parameters    Challenge            Car       User Tags    Track Revision    Team Revision
------------------------------------  ----------------  --------  ------------------  -------------------  --------  -----------  ----------------  ---------------
0d7d4d44-259d-43b0-922e-0a934f3bc48c  20220308T073143Z  geonames                      append-no-conflicts  defaults               f607dd0           09981c9
aafc91d3-b4bd-43ce-82c3-7caf44b01c41  20220308T040756Z  geonames                      append-no-conflicts  defaults               f607dd0           09981c9
```

では、この２つを比較します。

```
$ esrally compare --baseline=aafc91d3-b4bd-43ce-82c3-7caf44b01c41 --contender=0d7d4d44-259d-43b0-922e-0a934f3bc48c
```
おそらく緑はポジティブな結果（EBSよりインスタンスストアのほうが良い結果）

![スクリーンショット 2022-03-08 23-05-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13835/01098e57-4ab5-fca6-0905-a7434820c8b1.png)

`Mincomulative flush time across primary shard` から３項目がいい結果だけど、これなんだろ...

![スクリーンショット 2022-03-08 23-07-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13835/70cb3ff9-75e2-8a7e-5ca0-1037c0cb521d.png)
![スクリーンショット 2022-03-08 23-08-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13835/45f411c7-6528-3131-b877-bf7fb3dab20c.png)
![スクリーンショット 2022-03-08 23-09-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13835/f1e61b60-0649-51dd-0d1c-703b516b34ab.png)

`painless_static` の `50th percentile servicve time` が、なんと5倍以上の時間がかかって悪い結果。

![スクリーンショット 2022-03-08 23-12-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13835/3f682ca0-dd0e-faac-59b1-cc4dc0e0c05f.png)

ひとつひとつ意味を理解しないとわからないけど、インスタンスストアを使ったからっていい結果にはならないっぽい。