こんにちは。API・バックエンド/SREチームの清水です。 普段はAPIサービスの開発、インフラ監視や障害の調査などに関わっています。
今回のエントリでは、2020年12月に新しくAWSが発表したEBSボリュームタイプ gp3 について、IOのレイテンシやスループットの観点から性能調査を行ったので、gp2 との比較を行いながら紹介します。
gp3ボリュームとは
gp3はAWSが提供するEBS(データを保存するためのブロックストレージサービス)の一種です [1]。 gp3は最新世代の汎用SSDボリュームでgp2 の次世代にあたり、コスト上も有利とされています。 AWSには以下のように書かれています [1]。
ストレージ容量に関係なくパフォーマンスをプロビジョニングできる一方、既存の gp2 ボリュームよりも GB あたり最大 20% 低い料金を実現しています。
gp3 では容量によらず 3000 IOPS、125 MiB/秒のスループットがベースラインパフォーマンス (基本性能) として保証されています。 より大きな性能が要求される場合は、追加料金により性能を拡張することもできます [1]。
一方 gp2 はベースラインパフォーマンスが容量によって決定される仕組みです。このため、IO性能を確保するためには容量を余分に確保する必要がありました。 またバーストと呼ばれる性能が一時拡張される機能があり、知らないうちにバーストバランスを使い果たすと性能が制限されるという、少し扱いづらい挙動もありました。 gp3ではこれらが改善されて分かりやすくなったイメージです。
詳しい説明は、汎用ボリューム (gp2)で確認できます。
以下の図は、AWS UserGuideを参考に作成したgp2 と gp3 のベースラインIOPS性能です。 おおむね1000GiBまではgp3のほうがベースラインが高くなります。

調査の背景
日経ではこれまで主にgp2のボリュームを利用してきましたが、コストメリットからgp3の導入を始めています。
そんな中、社内で運用しているElasticsearchクラスターのEBSボリュームを gp3 に変更したところ、 利用しているサービスのレイテンシがわずかに上昇する現象が見られました。 以下の図のように、切り替え時点 (図中縦線から右側) から若干の増大が見られます。

調べたところ、一部でもgp3のレイテンシがgp2よりも大きくなる場合があることが報告されていました [2]。
レイテンシ増大の原因を詳しく特定するべく gp2とgp3のIO性能を比較することとしました。
性能調査の概要
IOの性能調査では、実際に負荷を発生させてレイテンシやIOPS、スループットを計測します。 負荷の内容(ワークロード)に対するストレージの特性の傾向を観察するため、複数の負荷状況を用意して検証しています。
ここでは、IO負荷計測ツールとして広く利用されている fio [3] を利用して、ディスクのレイテンシを計測します。 これはAWSが公式に提示しているEBSボリュームのベンチマークでも利用されています。 負荷の内容として、IOされるブロックサイズの大小、同時に同じIO負荷を実行するスレッド数(並列度)の大小の組み合わせで4パターン用意しました。 この他に、EBS暗号化の有無によっても性能差が発生するか検証を行いました。
また参考までに、Elastic社が公式に提供している Rallyを利用したレイテンシ計測も行いました。 このツールはElasticsearchの負荷を実際に発生させ、サービスタイムやレイテンシを計測することができます。今回は、Elasticsearchを gp2 と gp3 の双方に用意し、これに対してRallyを実行しています。ただし、Elasticsearchは、基本的にファイルシステムのキャッシュをかなり活用しているため、本エントリでは、参考値として扱います。
前提条件
今回の性能調査では、1台のEC2に対しgp2 、gp3 の各ボリュームをマウントして行いました。 まず、EC2インスタンスの仕様は以下です。
- EC2インスタンスタイプ:
r5.large
- OS:
Amazon Linux 2
EBSは以下のような仕様で用意しました。
gp2 は実際には2000秒まで3000IOPSにバーストされます。これにより、IOPS性能がgp3のベースラインと同等になります。 gp3については、スループット性能を128MiB/sでプロビジョンしました。 これは100GiBの容量を持つgp2ボリュームが、バーストしたときの最大性能と同じくするためです。
リージョンはEC2、EBSともにapne1-az2を利用しています。 fioによる調査では、ボリュームの暗号化・非暗号化の影響についても調査しました。 まずは、暗号化ボリュームを基本として各種レイテンシ等を計測、次いで、非暗号化ボリュームでも同様の計測を行いました。
ボリュームタイプ | 容量 | スループット設定 | IOPS設定 | フォーマット | デバイス名 | マウントポイント |
---|---|---|---|---|---|---|
gp2 | 100 GiB | - (最大 128MiB/s) | 300 (最大 3000) | xfs | /dev/sdb | /home/ec2-user/gp2 |
gp3 | 100 GiB | 128MiB/s | 3000 | xfs | /dev/sdc | /home/ec2-user/gp3 |
参考までに、この設定での東京リージョンにおけるコストは、gp2 が 約 12.00 USD/月に対し、gp3 が 約 9.74 USD/月と安価になっています。
fioを使ったディスクレイテンシの計測
負荷計測ツール fio では様々なパラメータを変更して、負荷状況を作り出すことができます。例えば、IOのブロックサイズについても、単調に同じ負荷を与え続けるだけではなく、ブロックサイズごとに割合を指定して負荷を与えるパラメータも存在します。この詳細は、公式ドキュメントのjob-file-parametersに詳しく説明されています。
ディスクへの負荷内容の定義
fioでは、負荷の内容をジョブファイルとして定義して、実行することができます。これらの実行は、gp2、gp3 のボリュームをマウントしたディレクトリに対して行いました。
本エントリでは、負荷の内容に従って、以下の4パターンのジョブを作成しました。なお、アクセス方式はシーケンシャルアクセスで、読み書きは同時に計測します。また、本エントリでは、同時実行スレッド数は並列度と呼ぶこととします。
並列度 | ブロックサイズ | 補足 |
---|---|---|
2 | 16K | ブロックサイズが小さく、並列度が少ない |
2 | 256K | ブロックサイズが大きく、並列度が少ない |
16 | 16K | ブロックサイズが小さく、並列度が多い |
16 | 256K | ブロックサイズが大きく、並列度が多い |
以下が今回用いたものと同じジョブ定義です。ブロックサイズはbs
、並列度はnumjobs
で指定します。試験対象となるディレクトリは、directory
に指定します。今回は、gp2を/home/ec2-user/gp2
、gp3を/home/ec2-user/gp3
にマウントするため、設定項目にこれらのパスを指定しています。また、バッファを回避するため、ダイレクトIOモードを指定しています。これはdirect=1
により指定できます。
試験の都合上、並列度ごとにファイルを分けています。したがって、定義中のnumjobs
が16のものも用意しています。まずは、これらのIO状況におけるレイテンシを計測しました。
[global]
size=128m
filename=fio-bench
direct=1
directory=/home/ec2-user/gp2
[Sequential-ReadWrite-16k]
rw=readwrite
bs=16k
numjobs=2
group_reporting
stonewall
[Sequential-ReadWrite-256k]
rw=readwrite
bs=256k
numjobs=2
group_reporting
stonewall
計測結果のIOPS・スループット性能の比較
はじめに、暗号化ボリュームに対しての負荷を実行しました。基本的な性能として、IOPSやスループットの性能を観察します。 IOPSについては読み書きの合算値としています。
これらの調査の結果として、gp2 と gp3の両者ではIOPSやスループット上の性能差はほとんど見られないことがわかりました。また、ワークロードの内容によっては、IOPS性能の上限に達したために、スループットの性能が発揮できなかったと考えられる場合や、いずれの性能も上限値を達成できなかったと考えられる場合も観察されました。
IOPS
3000 IOPSを達成できた箇所を赤字で示します。いずれのボリュームタイプでも、ブロックサイズが小さく、並列度が大きいときに3000 IOPSを達成しました。一方で、1000程度や550程度に留まったケースも見受けられました。
この結果から、ワークロードの内容によっては、いずれのボリュームタイプも規定どおりのIOPS性能を発揮できないことがあることがわかります。
- IOPS
並列度 | IOブロックサイズ | gp2 (回/s) | gp3 (回/s) |
---|---|---|---|
2 | 16K | 2706 | 2878 |
2 | 256K | 1024 | 1024 |
16 | 16K | 3068 | 3068 |
16 | 256K | 545 | 546 |
(数字が大きいほうが良い)
スループット
スループットは、今回の設定では各ボリュームタイプも 128.0 MB/s が上限となります。上限値を達成できた場合を赤字で示します。 以下の結果を見ると、ブロックサイズが小さい場合 で、スループットが大幅に上限値を下回っている場合が存在しました。
したがって、IOPSと同様に、負荷によっては上限までのスループット性能が発揮できない場合があることがわかります。
読み込みスループット
並列度 | IOブロックサイズ | gp2 (MB/s) | gp3 (MB/s) |
---|---|---|---|
2 | 16K | 21.94 | 23.34 |
2 | 256K | 137.98 | 137.98 |
16 | 16K | 24.60 | 24.60 |
16 | 256K | 70.02 | 70.03 |
(数字は大きい方が良い)
書き込みスループット
並列度 | IOブロックサイズ | gp2 (MB/s) | gp3 (MB/s) |
---|---|---|---|
2 | 16K | 21.36 | 22.73 |
2 | 256K | 124.16 | 124.16 |
16 | 16K | 24.50 | 24.50 |
16 | 256K | 69.88 | 69.90 |
(数字は大きい方が良い)
レイテンシ値の比較 (50パーセンタイル)
より良好な結果を得た方について赤字で示します。結果を見ると、読み込みの場合で、gp3 のレイテンシが大きくなる傾向が見受けられました。特に、ブロックサイズが大きく並列度が小さい場合を除いて、gp3がわずかに不利な結果となっています。
一方で、書き込みに関しては、いずれの場合でも gp3 のレイテンシが小さくなる結果となりました。特に、並列度が小さく、ブロックサイズが大きい場合においては、gp2よりも高速となっています。
また、同じ並列度でブロックサイズを変化させたとき、gp3 はレイテンシの増大が小さく抑えられている場合がありました。例えば、読み込み・並列度2で、ブロックサイズを16Kから256Kに変化させた場合に注目してみます。gp2 では、418μs → 932μsと500μs近くレイテンシが増大したのに対し、gp3 は280μs以下の増加に留まっています。
読み込み
並列度 | IOブロックサイズ | gp2 (μs) | gp3 (μs) |
---|---|---|---|
2 | 16K | 418 | 470 |
2 | 256K | 932 | 748 |
16 | 16K | 5024 | 5088 |
16 | 256K | 30336 | 30592 |
(数字は小さい方が良い)
書き込み
並列度 | IOブロックサイズ | gp2 (μs) | gp3 (μs) |
---|---|---|---|
2 | 16K | 1032 | 860 |
2 | 256K | 2416 | 1800 |
16 | 16K | 5600 | 5536 |
16 | 256K | 31872 | 31616 |
(数字は小さい方が良い)
レイテンシ値の比較 (90パーセンタイル)
同様に、90パーセンタイル値も観察しました。こちらも、より良好な結果を得た方について赤字で示します。読み込みで並列度が低い場合に着目すると、gp3のレイテンシが比較的大きくなる傾向が観察できました。特に、並列度が小さくブロックサイズが大きいとき、1000μs近く遅い結果となっています。一方で、書き込みでは、基本的に、gp3 のほうが良好な結果となりましたが、やはり読み込みと同様に、レイテンシが大きくなるケースが存在するようです。
また、50パーセンタイル値と比較すると、gp3 はレイテンシに大きいばらつきが生じる可能性があることもわかりました。特に、並列度2・ブロックサイズ256Kでの読み込み時に着目した場合では、gp2は、932μs → 2896μsと約2000μs程度の変化であったのに対し、gp3は、748μs → 3824μsと約3000μs程度変化し、比較的大きな変動が観察されました。
読み込みレイテンシ(90パーセンタイル)
並列度 | IOブロックサイズ | gp2 (μs) | gp3 (μs) |
---|---|---|---|
2 | 16K | 494 | 740 |
2 | 256K | 2896 | 3824 |
16 | 16K | 5344 | 5472 |
16 | 256K | 31360 | 31360 |
(数字は少ない方が良い)
書き込みレイテンシ(90パーセンタイル)
並列度 | IOブロックサイズ | gp2 (μs) | gp3 (μs) |
---|---|---|---|
2 | 16K | 1208 | 1096 |
2 | 256K | 3184 | 4640 |
16 | 16K | 5984 | 5920 |
16 | 256K | 33024 | 32384 |
(数字は少ない方が良い)
非暗号化ボリュームとの比較
最後に、暗号化ボリュームと同じ方法で、非暗号化ボリュームでも同様のレイテンシ計測を行いました。 gp2 と gp3 で読み込み時の50パーセンタイル値のレイテンシを比較してみると、gp3 では、暗号化・非暗号化による影響は大きくないと考えられます。 一方で、gp2 では並列度が小さい場合、特にブロックサイズも小さい場合で、暗号化によるレイテンシへの影響が観察されました。
- gp2レイテンシ
並列度 | IOブロックサイズ | 暗号化 (μs) | 非暗号化 (μs) |
---|---|---|---|
2 | 16K | 418 | 278 |
2 | 256K | 932 | 732 |
16 | 16K | 5024 | 5088 |
16 | 256K | 30336 | 30336 |
(数字は少ない方が良い)
- gp3レイテンシ
並列度 | IOブロックサイズ | 暗号化 (μs) | 非暗号化 (μs) |
---|---|---|---|
2 | 16K | 470 | 462 |
2 | 256K | 748 | 724 |
16 | 16K | 5088 | 5088 |
16 | 256K | 30592 | 30592 |
(数字は少ない方が良い)
結果と考察
これらの比較を踏まえると、gp3 には以下の特性があることが考えられます。
- 負荷の内容により、平均的なレイテンシが gp2 より大きくなる可能性がある
- 書き込みについては、平均的に高速な書き込みを期待できる
- 読み書きが遅くなるオペレーションが発生する可能性がある (特に並列度が小さい場合)
- 暗号化の有無によるレイテンシ値への影響はほんとんどない
Elasticsearch Rallyを使ったベンチマーク
Elasticsearchでの実際の負荷におけるレイテンシの計測も行いました。Rallyは、Elastic社が中心となって開発しているElasticsearchのOSSのベンチマークツールです [4]。 実際のデータ操作やクエリ操作等の擬似的に行い、サービスタイムやレイテンシを含む、様々な指標を得ることができます。 負荷試験はTrackという形で定義され、いくつか標準の定義も提供されています。また、このTrackは、Taskと呼ばれるクエリ操作などの負荷試験のタスクが含まれています。更に、これらのTaskはchallengeというセットにまとめられています。
方法
本エントリでは、TrackとしてNOAA Trackを利用することにしました。challengeとしては、append-no-conflicts
を利用します。なお、試験先のElasticsearchは、Docker Composeを用いて、ストレージが gp2、gp3 になるよう、それぞれ構築します。
各Elasticsearchに対し、負荷試験を走行させます。なお、Rallyの導入方法については、Installationを参照してください。
負荷試験は、以下のようなコマンドで実行できます。このうち、target-hosts
で試験先のElasticsearchを指定します。この場合では、localhost:9203
でElasticsearchが稼働しています。また、pipeline=benchmark-only
は、自身でElasticsearchを構築して負荷試験する場合のみ利用するオプションです。同一EC2から、別々のEBSの性能を比較するため、このオプションを利用します。また、report-file
により、結果をファイルに出力することもできます。
$ esrally race --track=noaa --challenge=append-no-conflicts \
--target-hosts=localhost:9203 --pipeline=benchmark-only \
--report-format=csv --report-file=~/es-benchmarks/gp3.csv
また、Rallyでは、Latency
とService Time
というメトリクスが得られますが、本エントリでは、このうちの後者をレイテンシとして扱います。これは、前者のLatency
が、Elasticsearchが処理を受け付けるまでの待機時間を含んだ値であり、実際に内部の処理に要した時間はService Time
として表現されているためです。
結果と考察
まずは、各負荷試験のレイテンシ値を示します。ここでは、50パーセンタイル値の比較を紹介します。なお、実際はより詳細な値が得られますが、本エントリでは、小数点以下2桁となるように丸めています。
以下の結果では、より良好な結果を得られた値を赤字で示します。いずれも検索を実行するElasticsearchのクエリですが、一つのTaskを除いて gp2 が有利な結果となりました。特にTaskによっては、40ms程度の差を生じているものも観察されました。
なお、gp3 が有利となった range_field_conjunction_small_range_big_term_query は、検索条件として、整数値の範囲 range
が小さい一方、文字列一致 term
でヒットする件数が多いような検索を実行しています。
今回の実験では、Elasticsearchのデータディレクトリを gp2 と gp3 で切り替えた以外、同一条件で実施しました。したがって、ワークロードの内容とEBSストレージの特性により、Elasticsearch上でのレイテンシに差異が発生することが示唆されます。ただし、Elasticsearchでは、ファイルキャッシュが活用されるため、単純にストレージの性能のみでレイテンシが増大・減少したとは言い切れないかもしれません。
Task | gp2 (ms) | gp3 (ms) |
---|---|---|
range_field_big_range | 60.84 | 86.83 |
range_field_small_range | 28.27 | 56.56 |
range_field_conjunction_big_range_small_term_query | 32.14 | 32.24 |
range_field_conjunction_small_range_small_term_query | 59.52 | 63.42 |
range_field_conjunction_small_range_big_term_query | 270.14 | 241.06 |
range_field_conjunction_big_range_big_term_query | 581.95 | 585.75 |
range_field_disjunction_small_range_small_term_query | 89.18 | 94.04 |
range_field_disjunction_big_range_small_term_query | 155.60 | 194.64 |
おわりに
本エントリでは、次世代EBSボリュームタイプ gp3 のレイテンシ計測について紹介しました。
ストレージの性能は、ワークロードの種類や内容によって大きく左右されます。今回は、非バッファなIOにより、gp3 のディスク特性を観察してみました。結果としては、IOの並列度やブロックサイズが小さくなるなど、負荷の状況によっては、gp2 よりレイテンシが大きくなることもあるようです。一方で、適切なIOを行うことで、gp2 よりも高速かつ安価に利用できる利点もあります。
また、本エントリでは触れませんでしたが、これらの実際のIOの状況や、ファイルキャッシュの状況を調査するには、eBPFを活用したiovisor/bccというツールも有用です。
本エントリを、皆様の開発にお役立ていただければ幸いです。
備考
このエントリは、2021年5月時点での調査結果に基づき作成しました。
参考文献
[1]: Amazon EBS ボリュームの種類, https://aws.amazon.com/jp/ebs/volume-types/ (accessed 27 April 2021).
[2]: Looking into performance of the new EBS gp3 volumes, https://silashansen.medium.com/looking-into-the-new-ebs-gp3-volumes-8eaaa8aff33e/ (accessed 6 May 2021).
[3]: fio - Flexible I/O tester rev. 3.26, https://fio.readthedocs.io/en/latest/fio_doc.html (accessed 27 April 2021).
[4]: Rally, https://github.com/elastic/rally (accessed 27 April 2021).