Amazon Web Services ブログ

Amazon RDS for PostgreSQL クロスリージョンリードレプリカのためのベストプラクティス

Amazon RDS for PostgreSQL のマネージドサービスのひとつにクロスリージョンリードレプリカがあります。クロスリージョンリードレプリカを使用することで、災害対策ソリューションの確保、データベースの読み込みワークロードのスケーリング、およびリージョン間での移行が可能になります。クロスリージョンリードレプリカは、Amazon RDS コンソールAWS CLI、または create-db-instance-read-replica API を使用して作成できます。クロスリージョンリードレプリカには、追加のデータ転送料金がかかります。

Amazon RDS はクロスリージョンリードレプリカを容易にしますが、最良の経験を実現するために認識しておく必要がある注意点がいくつかあります。この記事では、以下のトピックに関する Amazon RDS for PostgreSQL クロスリージョンレプリケーションのベストプラクティスを説明します。

  • クロスリージョンリードレプリカの作成の流れ
  • レプリケーション遅延を最小限化する方法
  • Amazon RDS for PostgreSQL クロスリージョンレプリカの使用中における一般的な問題

クロスリージョンリードレプリカの作成の流れ

クロスリージョンリードレプリカは、Amazon RDS for PostgreSQL のバージョン 9.5.2 以降でサポートされます。クロスリージョンレプリカの作成中、システムは以下のステップを実行します。

  • ソースインスタンスのスナップショットを作成する。
  • スナップショットをレプリケーション先のリージョンにコピーする。
  • ソースとクロスリージョンレプリカ間におけるストリーミングレプリケーションスロットを設定する。
  • ソースからレプリカへのログ先行書き込み (WAL) のストリーミングを開始する。WAL ファイルは PostgreSQL のトランザクションログです。データ変更は、まず WAL ファイルに記録されてから、永続ストレージに書き込まれます。

Amazon RDS for PostgreSQL のクロスリージョンレプリカは、以下の手順に従うことで最も簡単に作成できます。

  1. Amazon RDS コンソールで、Amazon RDS for PostgreSQL ソースインスタンスを選択します。
  2. [アクション] ドロップダウンメニューで [リードレプリカの作成] を選択します。
  3. 適切なターゲットリージョンを選択します。

AWS CLI create-db-instance-read-replica を使ってクロスリージョンリードレプリカを作成することも可能です。同じリージョンにあるレプリカのための物理的なストリーミングレプリケーションとは異なり、Amazon RDS for PostgreSQL はクロスリージョンレプリカのためにスロットによる物理的なストリーミングレプリケーションを使用します。従来のストリーミングレプリケーションでは、wal_keep_segments パラメータがインスタンスの WAL ファイル数を維持します。archive_command パラメータは、Amazon S3 に追加の WAL ファイルがアーカイブされるかどうかを決定します。物理的なレプリケーションスロットは、このパラメータの依存関係を解決します。レプリケーションスロットは、クロスリージョンレプリカが WAL セグメントを受け取るまでは、マスターがそれらを削除しないようにする自動化された手段を提供します。これは、リージョン間でネットワーク問題が発生しても、WAL がアーカイブされずにソースインスタンスに蓄積されることを確実にします。アーカイブ先からの WAL ファイルの復元は、レプリケーション遅延を長引かせ、レプリケーションパフォーマンスの妨げとなります。

以下の図は、Amazon RDS for PostgreSQL が異なるリージョン内のソースとレプリカの間でレプリケーションを実行する方法を示しています。

レプリケーション遅延の最小限化

ソースインスタンスで発生しているデータ変更がクロスリージョンレプリカに直ちに反映されないというシナリオは多数存在します。次のセクションでは、Amazon RDS for PostgreSQL クロスリージョンリードレプリカの使用中におけるレプリケーション遅延を最小限化するためのベストプラクティスについて説明します。

インスタンスクラスとストレージタイプ

最適なパフォーマンスを得るには、レプリカインスタンスがソースインスタンスと同じ、またはそれ以上のクラスである必要があります。レプリカインスタンスは、マスターと同様の書き込みアクティビティを再生するだけでなく、追加の読み込みワークロードにも対応します。このため、レプリカを適切なインスタンスクラスに設置することが必要不可欠です。ソースよりも低いインスタンスクラスでレプリカがホストされている場合、CPU、メモリ、およびスループット不足が発生する可能性があります。これは、レプリカパフォーマンスの全体的な低下につながる恐れがあり、この低下がレプリケーション遅延を引き起こします。

同様に、レプリカをソースインスタンスと同じストレージタイプに設置することもグッドプラクティスです。たとえば、マスターインスタンスが 20,000 IOPS の 500 GB プロビジョンド IOPS SSD タイプのストレージを使用している場合、500 GB の汎用 SSD ストレージではソースを最適に使用する時にクロスリージョンレプリカのパフォーマンスが低下する可能性があります。レプリカにおけるリソース不足 (CPU、メモリ、および IOPS など) が原因で、レプリカがソースインスタンスの書き込みアクティビティの再生に失敗する場合、レプリケーション遅延が増加します。

ソースインスタンスでの書き込みアクティビティ

RDS ストレージにデータを書き込むには、まず WAL ファイルにトランザクションを記録してから、これらの変更を物理ストレージブロックに書き込みます。ソースインスタンスでの書き込みアクティビティが多いと、WAL ファイルが急増する可能性があります。WAL ファイルの高生成率と、リードレプリカでのこれらのファイルの再生は、全体的なレプリケーションパフォーマンスを減速させます。ソースインスタンスでの書き込みパフォーマンスは、Amazon CloudWatchWriteIOPS および WriteThroughput メトリクスを使ってモニタリングできます。

以下のスクリーンショットは、100 GB GP2 ストレージを使用するソースインスタンスでの大量の書き込みアクティビティを示しています。

以下のスクリーンショットは、ソースインスタンスでの大量の書き込みアクティビティが原因で増加したクロスリージョンレプリカ遅延を示しています。

ソースインスタンスでの排他ロック

ALTER TABLETRUNCATEDROP TABLEREINDEXCLUSTER、および VACUUM FULL などの PostgreSQL コマンドは、最も厳しいロックモードである ACCESS EXCLUSIVE LOCK がテーブルで発生する原因となります。このモードは、他のすべてのロックモードと競合します。このロックは、ロックの持続期間中、その他すべてのトランザクションからのテーブルへのアクセスを阻止します。一般に、テーブルはトランザクションが終了するまでロックされたままになります。ロックを取得したトランザクションの結果は、レプリケーション競合の原因となる場合があります。たとえば、ソースインスタンスにテーブルをドロップする場合、クエリがそのテーブルにアクセスしていると、レプリカは変更を適用しません。詳細については、PostgreSQL ウェブサイトの「Explicit Locking」を参照してください。

このようになることを避けるため、pg_locks および pg_stat_activity カタログテーブルを定期的にクエリして、この状況を監視するようにしてください。たとえば、以下のコードは PostgreSQL 9.6 以降の PostgreSQL インスタンスにおけるロックをモニタリングします。

SELECT pid,
       usename,
       pg_blocking_pids(pid) AS blocked_by,
       QUERY AS blocked_query
FROM pg_stat_activity
WHERE cardinality(pg_blocking_pids(pid)) > 0;

その代案として、Amazon RDS Performance Insights を使ってデータベースロックをモニタリングすることもできます。Performance Insights は Amazon RDS DB インスタンスの負荷をモニタリングするので、データベースのパフォーマンスを分析し、トラブルシューティングすることができます。Performance Insights ダッシュボードでは、データベースの負荷を視覚化し、負荷を wait、SQL ステートメント、ホスト、またはユーザーでフィルタすることが可能です。以下のグラフは、22:23 から 22:53 の間に発生した多数の LWLock:buffer_mapping および LWLock:buffer_content wait イベントを示しています。

クロスリージョンレプリカでのパラメータ設定

デフォルト設定では、ソースインスタンスがリードクエリの開始時間、およびクロスリージョンレプリカでアクセスされた行の情報を認識せず、これらの行がレプリカインスタンスで使用されている可能性を考慮せずに、行の古いバージョンをクリーンアップ (VACUUM) します。レプリカはこのクリーンアップを再生し、これらの行を読み込んでいるクエリを強制的にキャンセルしなければなりません。このため、対応する行がソースインスタンスで更新または削除される場合、クロスリージョンレプリカでの長時間実行されるリードクエリが以下のエラーを伴って失敗する可能性があります。

ERROR: canceling statement due to conflict with recovery 
Detail: User query might have needed to see row versions that must be removed.

この状況は、hot_standby_feedback パラメータを有効化することによって避けることができます。この設定は、レプリカで行の古いバージョンがアクセスされるまで、対応するテーブルでの VACUUM を延期します。この設定の欠点は、テーブルを大幅に増大させ、ストレージ不足問題、およびトランザクション ID 周回のリスクを生じ得ることです。詳細については、PostgreSQL ウェブサイトの「Routine Vacuuming」を参照してください。

その代わりに、レプリカインスタンスで max_standby_archive_delay または max_standby_streaming_delay といったパラメータを有効化して、長時間実行されるリードクエリを完了できるようにすることができます。これらのパラメータはどちらも、レプリカでリードクエリが実行されている間に対応するソースデータが変更されると、レプリカでの WAL 再生を一時停止します。-1 の値は、リードクエリが完了するまで WAL 再生を待機させます。ただし、この一時停止は、WAL が蓄積されることが原因で、レプリケーション遅延が無限に増加し、ストレージの消費率も高くなります。これらのパラメータの値を高くすると、クロスリージョンレプリカで高レプリケーション遅延を引き起こす場合があります。たとえば、レプリカでクエリが 30 分間実行される場合、max_standby_streaming_delay が 30 分に設定されていると、最大 30 分のレプリケーション遅延が発生し、ソースインスタンスで 30 分の WAL ログが蓄積される原因となります。これら 3 つのパラメータのいずれかを変更する場合は、レプリカインスタンスで長時間実行されるリードクエリに注意することで、ソースインスタンスを正常に保ち、レプリケーション遅延を管理可能な範囲に維持します。

以下の SQL クエリも役に立つかもしれません。リードレプリカに以下のコードを入力することで、5 分を超える読み込みトランザクションをすべて終了させます。

SELECT
   pg_terminate_backend(pid) 
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes';

Amazon RDS for PostgreSQL クロスリージョンレプリカの使用中における一般的な問題

クロスリージョンレプリカ問題の大半は、ワークロードを管理し、インスタンス設定を変更することで対処できます。このセクションでは、Amazon RDS for PostgreSQL クロスリージョンレプリカに関連する一般的な問題と解決方法について説明します。

レプリカにレプリケーション遅延が発生している

ソースインスタンスでワークロードが実行されていない場合でも、クロスリージョンレプリカでは最大 5 分の遅延が予想されます。予想外の遅延が発生する場合は、ソースでの書き込みワークロードの負荷を調べ、ソースとレプリカのインスタンスクラスとストレージタイプが一致していることを確認して、ソースとレプリカ間における既存のネットワーク問題の有無を調べます。また、ソースまたはレプリカが、CPU、メモリ、IOPS といったリソースをスロットリングしていないことも確認します。

それでも遅延の原因がわからない場合は、AWS サポートでサポートケースを開始して、リージョン間におけるネットワーク問題を追跡してください。ソースインスタンスの pg_stat_activity ビューを確認して、レプリケーションプロセスを妨げる可能性がある特定の実行中クエリを停止することも重要です。レプリケーション遅延は、CloudWatch の ReplicaLag メトリクスを使ってモニタリングできます。また、select pg_current_wal_lsn(); コマンドを使ってレプリカでの LSN の増加をチェックすることも可能です。

ソースインスタンスでの低空き容量

クロスリージョンリードレプリカは、ソースインスタンスで作成された物理的なレプリケーションスロットを使用します。レプリケーションスロットは WAL ファイルを保持するため、クロスリージョンレプリケーション遅延がソースインスタンスで WAL が大量に蓄積される原因となり、最終的にはストレージ不足などの深刻な問題を引き起こします。CloudWatch の OldestReplicationSlotLag および TransactionLogsDiskUsage メトリクスを使って、遅延しているレプリカのサイズと、トランザクションログが使用するディスク容量を判断することができます。この問題を迅速に解決する方法は、既存のクロスリージョンレプリカをドロップして、新しいクロスリージョンレプリカを作成することです。

FreeStorageSpace に対する CloudWatch アラームを設定しておくと、ソースインスタンスでのワークロード関連問題を修正する時間ができ、レプリカの再作成を避けることができます。詳細については、Amazon RDS の空きストレージ容量を監視する CloudWatch アラームを作成して、ストレージが満杯になる問題を防ぐにはどうすればよいですか? を参照してください。

まとめ

AWS では、データベースレプリケーションパフォーマンスの信頼性と能率性を高め続けています。Amazon RDS for PostgreSQL クロスリージョンレプリカは、リージョン間での読み込み遅延の低減、リージョン間でのデータベースの移行、および低 RPO/RTO の災害対策のための優れたツールです。Amazon RDS はレプリカのワンクリック作成に対応しますが、レプリケーション問題を避けるためにも、ワークロードとインスタンスの設定に注意する必要があります。Amazon RDS for PostgreSQL リードレプリカの制限事項、モニタリング、およびトラブルシューティングの詳細については、「Amazon RDS での PostgreSQL リードレプリカの使用」を参照してください。

いつものように、AWS では皆さんのフィードバックをお待ちしています。コメント欄から、皆さんのご意見またはご質問をお寄せください。

 


著者について

 

Vivek Singh は、Amazon RDS/Aurora PostgreSQL エンジンを専門とする AWS のシニアデータベーススペシャリストです。Vivek はエンタープライズカスタマーと連携して、PostgreSQL の運用パフォーマンスに関する技術的なサポートを提供し、データベースのベストプラクティスをもたらしています。