レプリケーション

物理レプリケーションは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

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

クラスターで継続的バックアップが構成されている場合、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、メモリなど、ノードを説明する他のラベルに基づいてこの動作をカスタマイズできます。