Amazon Web Services ブログ
Amazon RDS または Amazon EC2 を使ってホストされているデータベースで実稼働ワークロードを実行するためのストレージのベストプラクティス
AWS は、OLTP ワークロードを処理するデータベースをホストするために複数のオプションを提供しており、Amazon EC2 インスタンスで独自のマネージドデータベースをホストする、または AWS が管理する Amazon RDS を使用することができます。RDS は、高可用性、自動バックアップ、データベースのアップグレード、OS パッチ、セキュリティ、およびリードレプリカを管理します。RDS は、クラウドネイティブのオプションである Amazon Aurora データベースエンジンも提供し、このエンジンは MySQL および PostgreSQL に対応しています。Aurora は、標準の MySQL と PostgreSQL データベースよりも優れたスループットを実現します。
Amazon RDS または Amazon EC2 を使ってホストされているデータベースで実稼働ワークロードを実行している時は、次のような疑問を思い浮かべたことがあるかもしれません。
- 最良のデータベースストレージタイプのオプションは何か?
- ストレージのパフォーマンス問題はどのように解決すればよいのか?
- EC2 インスタンスでホストされているデータベースに対する RAID 設定オプションには何があるのか?
- 最適なパフォーマンスのためのアプリケーション変更は何か?
- Amazon CloudWatch を使用してストレージパフォーマンスのトラブルシューティングを行うにはどうすればよいのか?
- Amazon RDS とAurora の運用パフォーマンスの違いは?
この記事では Amazon RDS または EC2 インスタンスでホストされているデータベースで実稼働ワークロードを実行するためのストレージのベストプラクティスについて説明します。
テスト、QA、またはステージングの環境と比べて、実稼働ワークロードには高速で一貫した I/O パフォーマンスが必要です。リレーショナルデータベースは多目的に使用できますが、それらの最も一般的なユースケースはオンライントランザクション処理 (OLTP) ワークロードをホストすることです。RDS または EC2 でホストされているデータベースと Aurora は、以下の異なるタイプのストレージ技術を使用します。
- Amazon RDS データベースインスタンスはストレージに Amazon EBS ボリュームを使用。
- Aurora インスタンスは AWS の専用ストレージボリュームを使用。
- EC2 インスタンスはストレージのために様々なオプションを有効化。
データベースストレージタイプの最良オプション
Amazon RDS は 3 つのストレージタイプを提供します。
インスタンスの I/O キャパシティは、インスタンスストレージのタイプとサイズに基づいています。DB インスタンスが gp2 ボリュームで設定されている場合、IOPS キャパシティのベースラインは GiB ストレージの 3 倍です。DB インスタンスが 100 GiB の gp2 ボリュームを割り当てている場合、IOPS キャパシティのベースラインは 300 です。ストレージをプロビジョニングすればするほど、IOPS キャパシティも増加します。
gp2 ボリュームは、IOPS キャパシティのベースラインに加えて、最大 3,000 IOPS のバーストキャパシティも長時間提供します。バースト機能は、ストレージが 1 TiB 以下のボリュームに限定されています。MySQL、MariaDB、Oracle、および PostgreSQL 向けの DB インスタンスは 20 GiB~32 TiB で設定できますが、最大のベースライン IOPS は 100~16,000 IOPS に制限されます。このため、5.34 TiB 以上の gp2 ボリュームは、同じ 16,000 IOPS のベースラインを提供します。
実稼働ワークロードが多くの OLTP と高速で一貫したスループットパフォーマンスを必要とする場合、DB インスタンスは io1 ボリュームで設定するべきです。最大 16,000 IOPS のベースライン IOPS を提供する gp2 ボリュームと比べて、io1 ボリューム は MySQL、MariaDB、Oracle、および PostgreSQL 向けの DB インスタンスに対して最大 40,000 IOPS、SQL Server インスタンスに対して最大 32,000 IOPS を提供できます。
IOPS の使用パターンが常に 16,000 を超えている場合は、DB インスタンスを変更して、ストレージタイプを gp2 から io1 に変更する必要があります。Amazon RDS はマグネティックストレージも提供していますが、これは一貫した I/O パフォーマンスと低レイテンシーを必要とする OLTP ワークロードには適していません。
マグネティックストレージタイプは、最大ストレージ容量が gp2 または io1 よりも少ないため、I/O 集約型ワークロードには推奨されません。IOPS キャパシティも最大 1,000 IOPS に制限されています。
ストレージパフォーマンス問題
gp2 ストレージの使用は、多種多様な DB ワークロードに適しています。このストレージタイプについては、データベースの読み込み/書き込みワークロードを、ReadIOPS と WriteIOPS の合計値が IOPS キャパシティのベースラインを超えることが一切ないように設計します。
バーストキャパシティは長時間利用できますが、バーストキャパシティを使用した後は、一貫して高い値の読み込みおよび書き込み IOPS がインスタンスのパフォーマンスを劣化させます。この劣化は、増加した WriteLatency または ReadLatency 値によって生じます。観念的に、gp2 ストレージは 1 桁ミリ秒のレイテンシーに適していますが、IOPS の過剰な使用は 10 ミリ秒を超えるレイテンシーの原因となり得ます。
以下の画像は、Amazon RDS DB インスタンスで WriteIOPS が一貫してベースラインの 300 IOPS キャパシティを消費するにつれて増加した WriteLatency 値を示しています。この例では、Amazon RDS PostgreSQL インスタンスが 100 GiB の gp2 ボリュームを使った t2.small インスタンスでホストされています。
上の画像は、ベースラインパフォーマンスである 300 IOPS を一貫的に消費する書き込み IOPS を示しています。
上の画像は、IOPS の過剰な使用が原因で最大 25 ミリ秒まで急増した書き込みレイテンシーを示しています。
ベストプラクティスとして、ワークロードがインスタンスの IOPS キャパシティを超えないことを確実にしてください。ReadIOPS 値を低減させる方法には以下のようなものがあります。
- Amazon RDS リードレプリカを使用する。
- より多くの RAM を使用する。
Amazon RDS リードレプリカの使用
MySQL、MariaDB、Oracle、および PostgreSQL 向けの Amazon RDS DB インスタンスは、RDS リードレプリカを提供します。これらのインスタンスは、データベースのトランザクションログを再生することによって、ソース DB インスタンスと同期化された個別の DB インスタンスです。ソース DB インスタンスでのデータ変更は、すべてリードレプリカに適用されます。リードレプリカを使用すると、アプリケーションからのリードクエリをリードレプリカにルーティングすることによって、ソース DB インスタンスの負荷が低減されます。また、ソース DB インスタンスでの追加の書き込みアクティビティのための IOPS キャパシティも解放されます。
リードレプリカでは、レプリケーション遅延を監視することが重要です。一般に、レプリケーション遅延の多発は、ソース DB インスタンスでの書き込みアクティビティが多いことが原因です。
Amazon RDS DB インスタンスでは、CloudWatch メトリクスの ReplicaLag を使ってレプリカ遅延を監視できます。レプリカ遅延が多発している場合は、ソース DB インスタンスでの書き込みアクティビティも監視する必要があります。これは、CloudWatch メトリクスの WriteIOPS と WriteThroughput を監視することで実行できます。ソース DB インスタンスが IOPS 不足 (つまり、すべての IOPS キャパシティが書き込みおよび読み込みワークロードで使用されている) である場合、レプリカも遅れ続けます。
遅延レプリカの原因のひとつは、ほとんどの DB エンジンにおいてリードレプリカのリカバリにシングルスレッドプロセスが関与することです。これは、マスターインスタンスでの負荷が高いほど、リードレプリカでのリカバリが指数関数的に遅くなることを意味します。ソース DB インスタンスでの書き込みアクティビティがさらに多くなると、リードレプリカ遅延も指数関数的に増加します。CloudWatch メトリクス以外にも、ReplicaLag では SQL クエリによって遅延を監視することも可能です。
PostgreSQL では、以下のクエリを使ってリードレプリカ遅延を計算できます。
MySQL では、以下のコマンドでレプリケーションステータスをチェックできます。
Amazon RDS リードレプリカでは、レプリカで発生した特定レベルのレイテンシーまたはレプリケーションエラーが、別のレプリカエンドポイントへの接続試行をトリガーするようにクライアントを設定できます。
アプリケーションが最良状態のレプリカを見つけることを確実にするための良い方法は、CloudWatch メトリクスを呼び出して ReplicaLag と読み込み/書き込みレイテンシーの現行値を確認することです。レプリケーション遅延は、前述の例にあるように、SQL コマンドで確認することができます。AWS Command Line Interface (AWS CLI) コマンドの describe-db-instances を呼び出して、レプリカの現行状態を確認することも可能です。レプリカの現行状態が「replicating」以外の場合、クライアントは別のレプリカへの接続を試行しなければなりません。
読み込みトランザクションを分散するメリットに加えて、リードレプリカはデータのシャーディングにも使用できます。シャードの「share-nothing」アーキテクチャに従って、各シャードに対応するリードレプリカを作成し、スタンドアロンシャードに変換することにした時にそれらを昇格することができます。
より多くの RAM の使用
Amazon RDS DB インスタンスには、メモリ内にワーキングセットのすべてを格納するために十分な RAM が搭載されている必要があります。リードクエリはメモリからデータを読み込むことができるので、ストレージボリュームとの通信量が少なくなります。その結果、書き込み目的のために使用できる ReadIOPS キャパシティの使用率も低くなります。
ワーキングデータセットのサイズを確認するための直接的な方法はありません。リードクエリを調べて、どれだけのデータがヒットされているかを確認します。例えば、データベースのサイズが 100 GiB であり、ワーキングセットが 20 GiB である場合、少なくとも 20 GiB のメモリがある Amazon RDS DB インスタンスを使用する必要があります。そうすることで、メモリ内にすべてのワーキングセットを格納できます。
EC2 インスタンスでホストされているデータベースに対する RAID 設定オプション
EBS ボリュームは、永続ブロックストレージを提供するブロックレベルのストレージボリュームです。これらのボリュームは高可用性のストレージボリュームで、同じアベイラビリティーゾーン内の EC2 インスタンスにアタッチできます。EBS ボリュームは EC2 インスタンスでホストされているデータベースに最適です。データベース用に EC2 インスタンスのエフェメラルストレージを使用することは推奨されません。
EC2 インスタンスで EBS ストレージボリュームを使用することにより、どの RAID レベルでもボリュームを設定できます。例えば、より優れた I/O パフォーマンスには、複数のボリュームを一緒にストライプできる RAID 0 を使用できます。RAID 1 は、2 つのボリュームを一緒にミラーリングすることから、データ冗長性のために使用できます。
RAID 設定に関わらず、EBS ボリュームデータは、データ損失を避けるためにセカンダリサーバー全体にレプリケートされます。RAID 5 と RAID 6 は、I/O パフォーマンスが RAID 0 または RAID 1 ほど良くないため、EC2 インスタンスでホストされているデータベースには推奨されません。
以下の表は、これら 2 つの異なる RAID 設定の長所と短所を示したもので、可能なユースケースが提案されています。
設定 | 長所 | 短所 | ユースケース |
RAID 0 | 耐障害性よりも I/O パフォーマンスに優れている | 単一ボリュームの損失が完全なデータ損失を引き起こす | データベースにデータ可用性よりもより優れたスループットが必要で、データが再生可能な場合 |
RAID 1 | I/O パフォーマンスよりも耐障害性に優れている | 書き込みパフォーマンスが低い | データが重要で、I/O パフォーマンスよりもデータベースの耐障害性のほうが重要な場合 |
最適なパフォーマンスのためのアプリケーションの変更
データベースインスタンスにストレージ問題が発生しており、長いコミット時間やレイテンシーなどの問題に直面しているときは、アプリケーションにおける変更がこの劣化を軽減できる場合があります。アプリケーションは、エクスポネンシャルバックオフまたはエラー再試行を有効化するように変更できます。
エクスポネンシャルバックオフは、アプリケーションが継続的なエラーレスポンスに対して、再試行間の待機時間を徐々に長くすることを可能にします。アルゴリズムには増分遅延を使用するものもありますが、ほとんどのエクスポネンシャルバックオフアルゴリズムはランダム化された遅延を使用します。以下は、異なるアルゴリズムの例です。
ランダム遅延:
- アプリケーションがリクエストを開始する。
- リクエストが失敗すると、rand(1000,3000) ミリ秒間待機し、リクエストを再度開始する。
- リクエストが失敗すると、rand(1000,3000) ミリ秒間待機し、リクエストを再度開始する。
- リクエストが失敗すると、rand(1000,3000) ミリ秒間待機し、リクエストを再度開始する。
増分遅延:
- アプリケーションがリクエストを開始する。
- リクエストが失敗すると、wait 1 = 1000 ミリ秒間待機し、リクエストを再度開始する。
- リクエストが失敗すると、wait 2 = wait 1 + 1000 ミリ秒間待機し、リクエストを再度開始する。
- リクエストが失敗すると、wait 3 = wait 2 + 1000 ミリ秒間待機し、リクエストを再度開始する。
Amazon RDS マルチ AZ インスタンスと Aurora クラスターでより迅速なフェイルオーバーを実現するには、特定のベストプラクティスを使用してください。TCP keepalive パラメータを有効化し、それらをアグレッシブに設定することで、クライアントが DB インスタンスに接続できなくなった場合に、すべてのアクティブな接続がすぐさま閉じられるようにします。この変更は、アプリケーションがより迅速にフェイルオーバーに反応し、新しいエンドポイントに素早く接続することも可能にします。
クライアントでの DNS キャッシングタイムアウトを短くすることもできます。読み込みおよび書き込み接続は、適切なエンドポイントに対して迅速に確立されます。サーバー TCP 設定パラメータにも変更できるものがあります。これらの変更は、より迅速なフェイルオーバーのために役立ちます。例えば、PostgreSQL では、tcp_keepalives_count、tcp_keepalives_idle、および tcp_keepalives_interval の各パラメータによって制御できます。
CloudWatch を使用したストレージパフォーマンスのトラブルシューティング
インスタンスストレージの正常性の定期的なモニタリングは、パフォーマンス問題がデータベースに深刻な影響を与える前に、その発生を早期に特定します。ここでは、定期的に監視する必要があるストレージの CloudWatch 関連のメトリクスをいくつか取り上げます。
書き込み操作
- WriteIOPS: 回数/秒の割合で測定されるこの CloudWatch メトリクスは、1 秒あたりのディスク書き込み I/O 操作の平均回数を測定します。データベースインスタンスがマルチ AZ で設定されている場合は、このメトリクスに注目します。
マルチ AZ を使用すると、別のアベイラビリティーゾーンに、セカンダリインスタンスがマスターインスタンスとアタッチされた EBS ストレージボリュームと同じインスタンス設定で作成されます。このストレージは、インスタンスストレージと同期的に同期されます。データ冗長性については、デフォルトで、各 EBS ボリューム内のデータが同じアベイラビリティーゾーン内にある別のセカンダリ EBS ボリュームにコピーされます。これは、クライアントに確認を送信する前に、書き込みトランザクションが 4 か所にコミットされる必要があることを意味します。インスタンスの IOPS とスループットキャパシティを超える大規模な書き込みアクティビティは、全体的なパフォーマンスを低下させます。 - WriteThroughput: この CloudWatch メトリクスは、ディスクに書き込まれる 1 秒あたりの平均バイト数を表します。インスタンススループット、またはストレージスループットの上限を超えると、インスタンスパフォーマンスが損なわれます。書き込みアクティビティを監視し、書き込みワークロードを適切な遅延で分散して、パフォーマンスを最適化することをお勧めします。
- WriteLatency: これは、ディスクの I/O 操作ごとにかかる平均時間です。ほとんどの場合、WriteLatency は CPU、IOPS、およびスループットなどのインスタンスリソースの過剰な使用が原因で増加します。
読み込み操作
- ReadIOPS: 回数/秒の割合で測定されるこの CloudWatch メトリクスは、1 秒あたりのディスク読み込み I/O 操作の平均回数を測定します。ReadIOPS 値の増加は、読み込みワークロードが多すぎる、またはインスタンスにより多くの空きメモリが必要なことを示唆しています。
- ReadThroughput: このメトリクスは、ディスクから読み込まれる 1 秒あたりの平均バイト数を表します。インスタンスと EBS の上限を超えると、レイテンシーが長くなります。
- ReadLatency: これは、ディスクの I/O 操作ごとにかかる平均時間です。このメトリクスの値が高い場合は、読み込みワークロードを調べて、それがインスタンスリソースを過剰に使用していないことを確認してください。
その他のメトリクス
前述のメトリクスと共に、以下の CloudWatch メトリクスも監視するようにしてください。
- DiskQueueDepth は、ディスクへのアクセスを待機している未処理の I/O (読み込み/書き込みリクエスト) の数を表します。通常、これは高ワークロードの結果です。
- FreeStorageSpace は、利用可能なストレージ容量を測定します。ベストプラクティスとして、インスタンスの空きストレージ容量がしきい値 (15%など) 未満になり次第 SNS 通知を受け取ることができるように、CloudWatch アラートを設定する必要があります。
Amazon RDS とAurora の運用パフォーマンスの違い
前述したとおり、Amazon RDS DB インスタンスと EC2 インスタンスの IOPS にはストレージボリュームに対する依存性があります。gp2 および io1 ストレージタイプには、それぞれ独自の IOPS 制限があります。
ワークロードにより優れた IOPS パフォーマンスとスループットが必要である場合、高スループットワークロードに適切な可用性とコスト効率に優れたソリューションである Aurora への移行を計画するとよいでしょう。現在、Aurora は MySQL および PostgreSQL 対応のエンジンを提供しています。
Aurora を使用するときは、技術的に IOPS の制限がない一方、スループットは基盤となる Aurora インスタンス規制に制限できることを確実にしてください。より良いスループットには、より高い Aurora インスタンスクラスを使用します。
Aurora は、どのような IOPS についてもレイテンシーがほとんど、またはまったく必要ないアプリケーションに最適です。Aurora は、高速のデータ速度を処理するように設計されており、従来の MySQL や PostgreSQL エンジンよりも優れたスループットを提供します。ローストア型データベースであるため、高容量で同時実行数が多い OLTP ワークロードに申し分ありません。
Aurora のもうひとつのユースケースは、HTAP (hybrid transaction analytical processing) です。Aurora は最大 15 のレプリカをサポートします。これらのレプリカはそれぞれ、書き込みインスタンスの 15~20 ミリ秒内に実行されます。最近追加された Amazon Aurora Parallel Query 機能を使うと、クエリ処理が後で Aurora ストレージにプッシュされます。クエリは、コンピューティングノードに送信する前にデータを処理、微調整、および集計するために、Aurora クラスター内で何千ものストレージノードを使用する可能性があります。
まとめ
この記事では、Amazon RDS DB インスタンスおよび EC2 インスタンスでホストされているデータベースで実稼働ワークロードを実行するためのストレージのベストプラクティスについて学びました。これらのベストプラクティスには以下が関与します。
- 読み込みワークロードをリードレプリカに割り当てる。
- IOPS キャパシティと、ストレージのサイズとタイプに対する IOPS の依存性を理解する。
- アプリケーションアーキテクチャを変更する。
- RAID オプションを検討する。
- CloudWatch メトリクスを監視する。
また、Aurora と、その専用ストレージの機能が EBS ボリュームの機能とどのように異なるかについても学びました。これらの知識はすべて、AWS データベースで実稼働ワークロードをスムースに問題なく実行するために役立ちます。データベースブログ記事: Introducing the Aurora Storage Engine で、Aurora がどのようにストレージレイヤーを使ってデータベースの速度と可用性に対応するかの詳細を検討することも可能です。
著者について
Vivek Singh は、RDS/Aurora PostgreSQL エンジンを専門とする AWS のデータベーススペシャリストテクニカルアカウントマネージャーです。Vivek はエンタープライズカスタマーと連携して、PostgreSQL の運用パフォーマンスに関する技術的なサポートを提供し、データベースのベストプラクティスを提供しています。