Tips:RDSでのIOクレジットバランスの考え方(汎用SSDボリューム)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ベルリンの半瀬です。

はじめに

RDSのI/Oクレジットバランス周りで調べ物をしたときのメモです。

ボリュームタイプとI/Oクレジットバランス(I/Oクレジット)の基本

  1. RDSは、データベースとログのストレージとして EBSボリュームを使用している。
  2. ボリュームタイプに汎用SSDを利用している場合、サイズに比例するI/Oのベースラインパフォーマンスが決まっている
  3. ベースラインパフォーマンスを超えたI/Oリクエストを受けることは可能
  4. ベースラインパフォーマンスを超えたI/Oリクエストを受けている場合、超過分のI/Oクレジットが消費される(バースト)
  5. ボリュームの初期作成時に、5,400,000 I/Oクレジットが割り当てられる
  6. I/Oリクエストがベースラインを下回った(バーストが終わった)場合、I/Oクレジットは補充されていく
  7. I/Oクレジットの補充速度はボリュームサイズに比例して速くなる

※参考: Amazon RDS のストレージ

確認した内容

「バースト」とは、利用しているボリュームのベースラインパフォーマンスを超えたI/O性能を発揮させることです。
バーストが継続可能な期間は、バースト開始時点でのI/Oクレジットバランスの残量に制限され、残量が0となるとベースライン以上のパフォーマンスは出ません。

※参考: Amazon EBS ボリュームの種類 ー I/O クレジットバランスが空になったらどうなりますか。

RDSを運用するとき、I/Oクレジットバランスを十分に把握する必要がありますが、以下の点をよく理解できていませんでした。

  1. I/Oクレジットバランスの消費状況や残量を知る方法
  2. バースト時のI/Oクレジットバランス消費量

ということで、色々ドキュメント周りを確認してみました。

1. I/Oクレジットバランスの消費状況や残量を知る方法

要点をまとめると、

  1. RDSに関してI/Oクレジットバランスの残量を示す指標は、今のところ提供していない
  2. 1回のI/O処理で、扱うデータサイズが32KB以上の場合、1回以上のIOクレジット消費として扱われる。
  3. CloudWatchのメトリクスではWriteIOPS/ReadIOPS(秒間IO処理数)、WriteTroughput/ReadTroughput(秒間データ処理サイズ) の値を確認する必要がある。

と、いうことのようでした(あくまで現時点では)。
ドキュメントでは、以下の参考箇所にあたります。

※参考 ー Amazon RDS ストレージに関する情報

I/O サイズはメトリックスによって報告される IOPS 値には影響しません。メトリックスは一定期間の I/O 数のみに基づいています。つまり、I/O サイズが 32 KB より>大きい場合、指定より少ない I/O で Provisioned IOPS がすべて消費される可能性もあります。たとえば、5,000 IOPS にプロビジョニングされたシステムでは、64 KB の I/O では最大 2,500 IOPS、128 KB の I/O では 1,250 IOPS を達成できます。

32 KB 未満の I/O リクエストは、1 つの I/O として扱われます。たとえば、1,000 >件の 16 KB の I/O リクエストは、1,000 件の 32 KB のリクエストと同様に扱われます。32 KB を超える I/O リクエストの消費は、1 つの I/O リクエストより多くなり>ます。Provisioned IOPS 消費は、サイズが 32 KB を超える I/O リクエストの線形関数です。たとえば、48 KB の I/O リクエストは、I/O リクエスト 1.5 件分のストレージ容量、64 KB の I/O リクエストは I/O リクエスト 2 件分、のように消費します。

例えば、
CloudWatch WriteIOPS + ReadIOPS が 500[IO/sec] 発生し、
CloudWatch WriteThrouput + ReadThrouput が 100[Mbyte/sec] 発生しているケースを考えます。

この場合、 Throuput合計 100 * 1024[Kbyte] を IOPS合計 500 [IO/sec] で割って、
100 * 1024 / 500 = 204.8[Kbyte/IO] が一度のIO内で取り扱われています。

IOクレジットバランスの消費で考えると、32Kbyteが1クレジットバランス消費単位となるため、
204.8[Kbyte/IO]を32[Kbyte/IO]で割って、
204.8 / 32 = 6.4 クレジットバランスが一度のIO処理に消費されていることとなります。

2. バースト時のI/Oクレジットバランス消費量

バースト期間の試算方法として以下の計算式があります。
20160504_01_burst_duration

バースト期間(Burst Duration)が明らかであれば、上記から「Burst IOPS」を逆算すればよいのではと考えられます。
計算のためには、実測された Burst Duration (バースト期間)が必要となりますが、これは負荷試験や運用実績から取得するとよいかと思います。

Burst Duration (バースト期間)の実測

バースト期間は、以下のようなCloudWatchメトリクスの推移から読み取ることができます。

  1. CloudWatch ReadIOPS + WriteIOPSが、利用中のボリュームのベースラインパフォーマンス以上に高騰している(バースト)
  2. バーストが一定期間継続したあと、ReadIOPSとWriteIOPSが急下降している
  3. ReadIOPS/WriteIOPS急下降の直後にCloudWatch ReadLatency/WriteLatencyが急上昇している

以下のCloudWatchのメトリクス推移は、実際にI/Oクレジットバランス枯渇が起きたケースのものですが、こちらをサンプルに上記の流れを見てみます(WriteIOPSとWriteLatencyのみで確認しています)。
汎用SSDボリュームを100GByteで使用していたため、ベースラインパフォーマンスは 100 * 3 = 300IOPS となります。

20160504_08_writeiops_latency3

WriteIOPSが急下降した②のタイミングで、IOクレジットバランスは枯渇していると考えられます。
バースト期間は約82分間であると読み取ることができます。

バースト時I/Oクレジットバランス消費量の計算例

バースト時のI/Oクレジットバランス消費量を計算してみます。
上記のサンプルから得られた情報を、「Burst Duration」算出式に代入してみます。

  1. Busrt duration = 82 * 60[sec]
  2. Credit balance = 5,400,000 [IOcredit] (※初期割り当て値を想定)
  3. Storage size in GB = 100[GByte]

上記を式に代入↓。
20160504_01_burst_duration
(82 * 60)[sec] = 5,400,000[IOcredit] / (X - 3 * 100)[IOcredit/sec]
X = 1,397.56[IOcredit/sec]

という結果になります。
サンプルの場合は、1,397.56[IOcredit/sec]ものI/Oリクエストを受け切ることができていないため、I/Oクレジットバランスの枯渇を防ぐために、ボリュームサイズの拡張もしくはProvisioned IOPSへの変更を行う必要がありそうです。

計算結果を何に使うか

I/Oクレジットバランスのバースト消費量の計算が必要なときとは、、

  1. 開発段階で、本番リリース時に必要なスペックを検討する
  2. 本番リリース後のスペックアップ指標(ボリューム拡張/タイプ変更)。 ※ 障害発生時に I/Oクレジットバランス枯渇の兆候が読み取れた場合

などかと思います。
なるべくリリース前に負荷試験を行なった上で、適切なスペックを選んでおきたいところです。

まとめ

RDSのI/Oクレジットバランスの考え方について

  1. I/Oクレジットバランスの基本を理解する。
  2. RDSのI/Oクレジットバランスの残量を示すメトリクスは、現時点では用意されていない。
  3. ボリュームごとのベースラインパフォーマンスを把握する(どのラインから「バースト」となるか)。
  4. I/Oクレジットバランスの枯渇兆候を把握する(※ CloudWatch: WriteIOPS/ReadIOPS, WriteThrouput/ReadThroughput)。
  5. バースト期間の長さから、バースト時のI/Oクレジットバランス消費量を求める。
  6. 適切なボリュームサイズ(汎用SSD)、PIOPSの割当量(Provisioned IOPS)を検討する。

蛇足:調べるきっかけ

Burst Duration の計算では CloudWatchの WriteIOPS/ReadIOPSの合計をそのまま 「Burst IOPS」 として使用すればよいと思っていました。
、、が、今回の障害については、実測されたBurst Durationの値と計算結果が合わず、IOクレジットバランスが枯渇しているのかどうかが判断出来ず、辛い思いをしました。

※その他 参考記事
RDSのGeneral Purpose (SSD)対応をベンチマークしてみた - Developers.IO
Amazon EBSのGeneral Purpose(SSD)のバーストルールを理解する - Developers.IO
Amazon EBS パフォーマンスベンチマーク 2015 #AWSSummit - Developers.IO

まだまだクンフーが足りません。

それではー。