レプリケーション

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

重要

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

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

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

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

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

PostgreSQLには、プライマリインスタンスから1つ以上のレプリカにデータを複製するための非常に堅牢で成熟したネイティブフレームワークがあります。

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

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

注釈

pg_rewind 要件のため、PostgreSQL 10では`streaming_replica` ユーザーが`SUPERUSER` 権限で作成されます。

オペレーターはすぐに、暗号化されたチャネルを介してクラスター内にストリーミングレプリケーションを設定し、 streaming_replica ユーザーにTLSクライアント証明書認証を強制します- pg_hba.conf から取得した次の抜粋で強調表示されています。

#  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 Podのリストです

警告

自己修復機能を提供するために、オペレーターは`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、メモリなど、ノードを説明する他のラベルに基づいてこの動作をカスタマイズできます。

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

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

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

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

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

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

  • スタンバイHAスロット :そのライフサイクルは、プライマリのpg_replication_slots ビューのコンテンツに基づいて、クラスター内の別のスタンバイによって完全に管理され、pg_replication_slot_advance() を使用して定期的に更新されます。

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

ReplicationSlotsConfiguration

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

.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 メトリックに、スロットの名前、タイプ、アクティブかどうか、プライマリからのラグなどのキー情報を提供します。