レプリケーション

物理レプリケーションは PostgreSQL の強みの 1 つであり、世界最大の組織の一部がビジネス継続性のコンテキストでのデータ管理に PostgreSQL を選択した理由の 1 つです。主に高可用性を実現するために使用される物理レプリケーションは、読み取り専用ワークロードのスケールアウトと、プライマリからの一部の作業のオフロードも可能にします。

重要

このセクションでは、同じ Kubernetes クラスターで管理されている同じ Cluster リソース内のレプリケーションについて説明します。異なる Kubernetes クラスター間であっても、別の Postgres Cluster リソースで複製する方法については、 レプリカ クラスタ を参照してください。

セクション。

アプリケーションレベルのレプリケーション

何年にもわたって PostgreSQL のレプリケーション機能に貢献してきた私たちは、ネイティブの物理レプリケーション テクノロジの上に CloudNativePG で高可用性を構築し、それを Kubernetes API に直接統合することにしました。

Kubernetes の用語では、これは ストレージ レベルのレプリケーション とは対照的に、 アプリケーションレベルのレプリケーション と呼ばれます。

非常に成熟したテクノロジー

PostgreSQL には、プライマリ インスタンスから 1 つ以上のレプリカにデータをレプリケートするための非常に堅牢で成熟したネイティブ フレームワークがあり、WAL (Write Ahead Log) に継続的に保存されるトランザクション変更の概念に基づいて構築されています。

物理レプリケーションは、クラッシュ リカバリとポイント イン タイム リカバリ テクノロジーの進化として始まりました。物理レプリケーションは、プライマリから連続リカバリのウォーム スタンバイへの WAL シッピングを通じて、PostgreSQL 8.2 (2006) で最初に導入されました。

PostgreSQL 9.0 (2010) では、ホット スタンバイ を介して WAL ストリーミングと読み取り専用レプリカで強化され、9.1 (2011) ではトランザクション レベルで同期レプリケーションが導入されました (RPO=0 クラスターの場合)。カスケード レプリケーションは、PostgreSQL 9.2 (2012) でリリースされました。論理レプリケーションの基盤は PostgreSQL 9.4 で構築されましたが、バージョン 10 (2017) では、発信元から宛先にデータを複製するパブリッシャー/サブスクライバー パターンのネイティブ サポートが導入されました。

ストリーミング レプリケーションのサポート

現時点では、CloudNativePG は、spec で提供された instances の数に基づいて、クラスター内の物理ストリーミング レプリカを宣言的な方法でネイティブかつ透過的に管理します。

replicas = instances - 1 (where  instances > 0)

クラスターの初期化直後に、オペレーターは次のように streaming_replica というユーザーを作成します。

CREATE USER streaming_replica WITH REPLICATION;
   -- NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOBYPASSRLS

すぐに使用できるオペレーターは、暗号化されたチャネルを介してクラスター内でストリーミングレプリケーションを自動的にセットアップし、streaming_replica ユーザーに TLS クライアント証明書認証を適用します。

#  Require client certificate authentication for the streaming_replica user

hostssl postgres streaming_replica all cert
hostssl replication streaming_replica all cert

ドキュメントで。

構成されている場合、オペレーターは HA クラスター内のすべてのレプリカのレプリケーション スロットを管理し、フェイルオーバーまたはスイッチオーバーの後でも、各スタンバイに必要な WAL ファイルがプライマリーのストレージに保持されるようにします。

下。

継続的なバックアップ統合

クラスターで継続的なバックアップが構成されている場合、CloudNativePG は、継続的な復旧時に restore_command を利用するようにレプリカを透過的に構成します。その結果、PostgreSQL は、ストリーミングレプリケーションによる WAL のプルが失敗するたびに、フォールバック オプションとして WAL アーカイブを使用できます。

同期レプリケーション

CloudNativePG は、minSyncReplicas および maxSyncReplicas と呼ばれる 2 つの構成オプションを介して クォーラムベースの同期ストリーミングレプリケーション の構成をサポートします。これらは、いつでも使用できると予想される同期スタンバイ レプリカの最小数と最大数です。自己回復の目的で、オペレーターは常にこれら 2 つの値を使用可能なレプリカの数と比較して、クォーラムを決定します。

重要

デフォルトでは、同期レプリケーションは利用可能なすべてのレプリカの中から区別なく選択します。次のセクションで説明するように、syncReplicaElectionConstraint オプションを使用してノード ラベルを操作することにより、同期レプリカをスケジュールできるノードを制限できます。

同期レプリケーションはデフォルトで無効になっています (minSyncReplicas と maxSyncReplicas は定義されていません)。 minSyncReplicas と maxSyncReplicas の両方が設定されている場合、CloudNativePG は PostgreSQL の synchronous_standby_names オプションを次の値に自動的に更新します。

ANY q (pod1, pod2, ...)

どこ:

  • q は、オペレーターによって自動的に計算される整数です: 1 <= minSyncReplicas <= q <= maxSyncReplicas <= readyReplicas

  • pod1, pod2, ... は、クラスター内のすべての PostgreSQL ポッドのリストです。

警告

自己修復機能を提供するために、そのような値が現在利用可能なレプリカの数よりも大きい場合、オペレーターは minSyncReplicas を無視できます。 readyReplicas が 0 の場合、同期レプリケーションは自動的に無効になります。

PostgreSQL documentation で述べたように、*メソッド ANY

はクォーラムベースの同期レプリケーションを指定し、WAL レコードが少なくともリスト内の要求された数の同期スタンバイにレプリケートされるまでトランザクションのコミットを待機させます*。

重要

オペレーターが同期レプリケーション設定の強制よりもセルフヒーリングを選択しても、3 つ以上のインスタンスを持つクラスター、またはより一般的には maxSyncReplicas < (instances - 1) の場合にのみ、同期レプリケーションを計画することをお勧めします。

同期レプリケーションのノードを選択

CloudNativePG を使用すると、PGDATA を保持する PVC と Postgres ポッドがあるノード ラベルに基づく非アフィニティ ルールを通じて、どの PostgreSQL インスタンスがクォーラムベースの同期レプリケーション セットに参加する資格があるかを選択できます。

この機能の使用例: 単一の同期レプリカを持つクラスターでは、同期レプリカがプライマリ インスタンスとは異なるアベイラビリティ ゾーンにあることを確認できます。通常は topology.kubernetes.io/zone

label on a node で識別されます。これにより、特に目標復旧時点 (RPO)

の観点から、単一のアベイラビリティ ゾーンで障害が発生した場合のクラスターの堅牢性が向上します。

アンチアフィニティの考え方は、クォーラムに参加する同期レプリカが、選択されたラベル (この場合はアベイラビリティ ゾーン ラベル) に対して異なる値を持つノードで実行されているポッドから選択され、次にプライマリが現在あるノードから選択されるようにすることです。実行中。このような基準に一致するノードがない場合、レプリカは同期レプリケーションに適格です。

重要

同期レプリカ選出のための追加の制約を定義している間も、自己修復の強制が適用されます ( 同期レプリケーション を参照してください)。

以下の例は、spec.postgresql 内の syncReplicaElectionConstraint セクションを介してこれを行う方法を示しています。 nodeLabelsAntiAffinity を使用すると、評価が必要なノード ラベルを指定して、現在のプライマリと、アベイラビリティ ゾーン ラベルの値が異なるアベイラビリティ ゾーン ラベルの値を持つノード上にあるレプリカとの間で、オペレータによって同期レプリケーションが動的に構成されることを確認できます。プライマリがあるノード:

spec:
  instances: 3
  postgresql:
    syncReplicaElectionConstraint:
      enabled: true
      nodeLabelsAntiAffinity:
      - topology.kubernetes.io/zone

ご想像のとおり、アベイラビリティ ゾーンは単なる例ですが、ストレージ、CPU、メモリなど、ノードを説明する他のラベルに基づいてこの動作をカスタマイズできます。

高可用性のためのレプリケーション スロット

は、9.4 で導入されたネイティブの PostgreSQL 機能であり、接続されているすべてのストリーミングレプリケーションクライアントが WAL セグメントを受信するまでプライマリが WAL セグメントを削除しないようにする自動化された方法を提供し、プライマリが行を削除しないことを保証します。スタンバイは (一時的に) 切断されます。

レプリケーション スロットは、それを作成したインスタンスにのみ存在し、PostgreSQL はそれをスタンバイ サーバーにレプリケートしません。その結果、フェイルオーバーまたはスイッチオーバーの後、新しいプライマリには古いプライマリのレプリケーション スロットが含まれません。これにより、古いプライマリに接続されていてスロットを失ったストリーミングレプリケーションクライアントに問題が発生する可能性があります。

CloudNativePG は、高可用性クラスターから始めて、クラスター管理のレプリケーション スロットの概念を導入することで、このギャップを埋めます。この機能は、プライマリとスタンバイの両方で、高可用性クラスター内の各ホット スタンバイ レプリカの物理レプリケーション スロットを自動的に管理します。

CloudNativePG では、次の用語を使用します。

  • プライマリHAスロット : ライフサイクルがクラスターの現在のプライマリによって完全に管理され、ストリーミングレプリケーションで特定のスタンバイにマップすることを目的とする物理レプリケーション スロット。このようなスロットは、プライマリのみに存在します。

  • スタンバイHAスロット : プライマリの pg_replication_slots ビューの内容に基づいてライフサイクルがクラスター内の別のスタンバイによって完全に管理され、pg_replication_slot_advance() を使用して定期的に更新されるスタンバイの物理レプリケーション スロット。

CloudNativePG 1.18 で導入されたこの機能は、構成によって有効にすることができます。詳細は

を参照してください。次に、主なオプションの簡単な説明を示します。

.spec.replicationSlots.highAvailability.enabled : true の場合、機能が有効になります (false がデフォルトです)

.spec.replicationSlots.highAvailability.slotPrefix : この機能のオペレーターによって管理されるレプリケーション スロットを識別するプレフィックス (デフォルト: _cnpg_ )

.spec.replicationSlots.updateInterval : スタンバイがレプリケーション スロットのローカル コピーの位置を現在のプライマリの位置と同期する頻度 (秒単位) (デフォルト: 30)

重要

この機能には pg_replication_slot_advance() に依存しているため、PostgreSQL 11 以降が必要です。

複製スロットの位置を直接操作します。

警告

PostgreSQL 11 では、レプリケーション スロットを最初に無効にした場合に有効にするか、逆に最初に有効にした場合に無効にすると、クラスターのローリング アップデートが必要になります (起動時にのみ読み取られる recovery.conf ファイルが存在するため)。

お勧めしませんが、別の動作が必要な場合は、上記のオプションをカスタマイズできます。

たとえば、次のマニフェストは、レプリケーション スロットが有効なクラスターを作成します。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3
  # Enable replication slots for HA in the cluster
  replicationSlots:
    highAvailability:
      enabled: true

  storage:
    size: 1Gi

次の例のように、スタンバイがプライマリの pg_replication_slots ビューをクエリし、レプリケーション スロットのローカル コピーを更新する頻度を制御することもできます。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3
  # Reduce the frequency of standby HA slots updates to once every 5 minutes
  replicationSlots:
    highAvailability:
      enabled: true
    updateInterval: 300

  storage:
    size: 1Gi

レプリケーション スロットは、インフラストラクチャで注意深く監視する必要があります。デフォルトでは、Prometheus エクスポーターの pg_replication_slots メトリクスに、スロットの名前、タイプ、アクティブかどうか、プライマリからのラグなどの重要な情報を提供します。