レプリケーション

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

重要

このセクションは、同じKubernetesクラスターで管理される同じ`Cluster` リソース内のレプリケーションに関するものです。異なるKubernetesクラスター間でも、別のPostgres Cluster リソースを使用して複製する方法については、 レプリカクラスターから分散トポロジへ を参照してください。

セクション。

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

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

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

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

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

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

PostgreSQL 9.02010は、 ホットスタンバイ を介したWALストリーミングと読み取り専用レプリカを導入しました。 2011年、PostgreSQL 9.1はトランザクションレベルで同期レプリケーションを導入し、RPO=0クラスターをサポートしました。カスケードレプリケーションはPostgreSQL 9.22012で追加されました。論理レプリケーションの基礎はPostgreSQL 9.42014で確立され、バージョン102017では、オリジンからデスティネーションにデータをレプリケートするためのパブリッシャー/サブスクライバーパターンのネイティブサポートを導入しました。以下の表は、これらのマイルストーンをまとめたものです。

Version

Year

Feature

8.2

2006

Warm Standby with WAL shipping

9.0

2010

Hot Standby and physical streaming replication

9.1

2011

Synchronous replication (priority-based)

9.2

2012

Cascading replication

9.4

2014

Foundations of logical replication

10

2017

Logical publisher/subscriber and quorum-based synchronous replication

この表は、主要なPostgreSQLレプリケーション機能とその各バージョンを強調表示しています。

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

現時点では、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クライアント証明書認証を適用します。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が証明書を管理する方法の詳細については、 証明書 を参照してください。

ドキュメントで。

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

参考

CloudNativePGが高可用性レプリカのレプリケーションスロットを自動的に管理する方法の詳細については、 高可用性のためのレプリケーションスロット を参照してください。

以下。

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

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

同期レプリケーション

CloudNativePGは、両方の quorum-based and priority-based synchronous replication for PostgreSQL をサポートしています。

警告

トランザクションコミットのWALデータをレプリケートするために必要な数のスタンバイノードが利用できない場合、同期レプリケーションは書き込み操作を停止することに注意してください。このような場合、アプリケーションの書き込み操作はハングします。この動作は、CloudNativePGでの以前の実装とは異なりますが、この機能に対するPostgreSQL DBAの期待と一致しています。

synchronous_standby_names オプションの直接構成は禁止されていますが、CloudNativePGでは、そのコンテンツをカスタマイズ、 .spec.postgresql.synchronous を介してCluster リソースを超えて同期レプリケーションを拡張できます。

同期レプリケーションはデフォルトで無効になっています。 synchronous スタンザは定義されていません。定義すると、2つのオプションが必須です。

  • method any クォーラムまたはfirst プライオリティ

  • number トランザクションが応答を待機する必要がある同期スタンバイサーバーの数

クォーラムベースの同期レプリケーション

PostgreSQLのクォーラムベースの同期レプリケーションは、WALレコードが少なくとも特定の数のスタンバイにレプリケートされるまで、トランザクションコミットを待機させます。この方法を使用するには、 method をany に設定します。

非推奨の同期レプリケーション実装からの移行

このセクションでは、非推奨のフォームを使用して定義された既存のクォーラムベースの同期レプリケーションを、CloudNativePGの新しいより堅牢な機能に移行する手順を説明します。

次のマニフェストがあると仮定します。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: angus
spec:
  instances: 3

  minSyncReplicas: 1
  maxSyncReplicas: 1

  storage:
    size: 1G

次のとおりに、新しいクォーラムベースの形式に変換できます。

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: angus
spec:
  instances: 3

  storage:
    size: 1G

  postgresql:
    synchronous:
      method: any
      number: 1

重要

新しい機能との主な違いは、PostgreSQLが常に高可用性よりもデータの耐久性を優先することです。したがって、使用可能なレプリカがない場合、プライマリへの書き込み操作はブロックされます。ただし、この動作は、この機能に対するPostgreSQL DBAの予想と一貫しています。

優先度ベースの同期レプリケーション

PostgreSQLの優先度ベースの同期レプリケーションは、WALレコードが、優先度に基づいて選択された要求された数の同期スタンバイにレプリケートされるまで、トランザクションコミットを待機させます。 synchronous_standby_names オプションで前にリストされたスタンバイには、より高い優先順位が与えられ、同期とみなされます。現在の同期スタンバイが切断されると、次に優先度の高いスタンバイにすぐに置き換えられます。この方法を使用するには、 method をfirst に設定します。

重要

現在、この方法は、以下で説明する`maxStandbyNamesFromCluster` 、standbyNamesPre 、および`standbyNamesPost` オプションを使用して、現在のクラスターを超えて同期レプリケーションを拡張する場合に最も役立ちます。

synchronous_standby_names コンテンツの制御

デフォルトでは、CloudNativePGはCluster リソースのローカルポッドの名前をsynchronous_standby_names に設定し、PostgreSQLクラスター内の同期レプリケーションを保証します。 .spec.postgresql.synchronous スタンザの次のオプショナルパラメーターを使用して、要件とレプリケーション方法クォーラムまたは優先順位に基づいてsynchronous_standby_names のコンテンツをカスタマイズできます。

  • maxStandbyNamesFromCluster PostgreSQLのsynchronous_standby_names オプションに自動的に含めることができるローカルCluster オブジェクトのポッド名の最大数。

  • standbyNamesPre オペレーターによって自動的にリストされたローカルポッド名のリストの前に追加されるスタンバイ名のリスト特にapplication_name 。

  • standbyNamesPost オペレーターによって自動的にリストされたローカルポッド名のリストに追加されるスタンバイ名のリスト特にapplication_name 。

警告

standbyNamesPre および`standbyNamesPost` の名前が正しいことを確認する責任があります。 CloudNativePGは、ここにリストされている`application_name` でスタンバイを管理し、高可用性を保証することを想定しています。エントリが間違っていると、PostgreSQLデータベースのアップタイムが危険にさらされる可能性があります。

例

次に、いくつかの例を示します。すべては、3つのインスタンスを持つcluster-example に基づいています。

設定すると

postgresql:
  synchronous:
    method: any
    number: 1

synchronous_standby_names の内容は次のとおりです。

ANY 1 (cluster-example-2, cluster-example-3)

設定すると

postgresql:
  synchronous:
    method: any
    number: 1
    maxStandbyNamesFromCluster: 1
    standbyNamesPre:
      - angus

synchronous_standby_names の内容は次のとおりです。

ANY 1 (angus, cluster-example-2)

設定すると

postgresql:
  synchronous:
    method: any
    number: 1
    maxStandbyNamesFromCluster: 0
    standbyNamesPre:
      - angus
      - malcolm

synchronous_standby_names の内容は次のとおりです。

ANY 1 (angus, malcolm)

設定すると

postgresql:
  synchronous:
    method: first
    number: 2
    maxStandbyNamesFromCluster: 1
    standbyNamesPre:
      - angus
    standbyNamesPost:
      - malcolm

synchronous_standby_names オプションは次のようになります。

FIRST 2 (angus, cluster-example-2, malcolm)

同期レプリケーション非推奨

警告

CloudNativePG 1.24より前では、クォーラムベースの同期レプリケーション実装のみがサポートされていました。この方法は現在非推奨ですが、すぐに削除されることはありません。新しい方法は、自己修復よりもデータの耐久性を優先し、優先度ベースの同期レプリケーションや`synchronous_standby_names` オプションの完全な制御など、より堅牢な機能を提供します。前の段落で説明したように、同期レプリケーションの新しい構成方法に徐々に移行することをお勧めします。

重要

非推奨なメソッドと新しいメソッドは相互排他的です。

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とPostgresポッドを保持するPVCが存在するノードラベルに基づいて、アンチアフィニティルールを介してクォーラムベースの同期レプリケーションセットに参加する資格のあるPostgreSQLインスタンスを選択できます。

参考

一般的なポッドアフィニティおよびアンチアフィニティルールの詳細については、 スケジューリング を確認してください。

警告

.spec.postgresql.syncReplicaElectionConstraint オプションは、同期レプリケーションの古い実装にのみ適用されます 同期レプリケーション非推奨 を参照してください。

この機能のユースケースの例として 単一の同期レプリカを持つクラスターでは、同期レプリカがプライマリインスタンスとは別のアベイラビリティーゾーンにあることを確認できます。通常は 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は、プライマリから各スタンバイに物理レプリケーションスロットのコンテンツを同期するターンキーソリューションを提供し、2つのユースケースに対応します。

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

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

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

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

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

この機能はデフォルトで有効になっており、構成から無効にできます。詳細については、 ReplicationSlotsConfiguration {postgresql-cnpg-io-v1-ReplicationSlotsConfiguration} を参照してください。以下に、メインオプションの簡単な説明を示します。

.spec.replicationSlots.highAvailability.enabled true の場合、機能は有効です true がデフォルトです

.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
  # Disable replication slots for HA in the cluster
  replicationSlots:
    highAvailability:
      enabled: false

  storage:
    size: 1Gi

ユーザー定義レプリケーションスロット

CloudNativePGは、物理レプリケーションスロットを宣言的に定義する方法をサポートしていませんが、

create your own slots via SQL はできます。

注釈

現時点では、宣言的な方法でレプリケーションスロットを管理する計画はありませんが、ユーザーから受け取るフィードバックによっては変更される可能性があります。その理由は、レプリケーションスロットは特定の目的のために存在し、プライマリ上のスロットのライフサイクル全体を監督する特定のアプリケーションで各スロットを管理する必要があるためです。

CloudNativePGは、上記で説明したHAレプリケーションスロットの場合と同様に、プライマリとスタンバイ間のユーザー管理の物理レプリケーションスロットの同期を管理できます。唯一の違いは、レプリケーションスロットを作成する必要があることです。

この機能はデフォルトで有効になっていますが、レプリケーションスロットが同期されることを意味しますが、 synchronizeReplicas スタンザを介して無効にするか、正規表現を使用して一部のスロットを除外するなど、その動作をさらにカスタマイズできます。例

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3
  replicationSlots:
    synchronizeReplicas:
      enabled: true
      excludePatterns:
      - "^foo"

詳細については、 ReplicationSlotsConfiguration {postgresql-cnpg-io-v1-ReplicationSlotsConfiguration} を参照してください。以下に、メインオプションの簡単な説明を示します。

.spec.replicationSlots.synchronizeReplicas.enabled trueまたは指定されない場合、プライマリのすべてのユーザー定義のレプリケーションスロットは、各スタンバイで同期されます。 falseに変更した場合、オペレーターは、各スタンバイで自分自身が以前に作成したレプリケーションスロットを削除します。

.spec.replicationSlots.synchronizeReplicas.excludePatterns 同期から除外するユーザー定義のレプリケーションスロットの名前と一致する正規表現パターンのリスト。これは、命名規則に基づいて特定のスロットを除外する場合に役立ちます。

警告

この機能を利用するユーザーは、ユーザー定義のレプリケーションスロットを注意深く監視して、運用要件を満たし、フェイルオーバープロセスを妨げないことを確認する必要があります。

同期周波数

この例のように、スタンバイがプライマリで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:
    updateInterval: 300

  storage:
    size: 1Gi

レプリケーションスロット用に保持されるWALサイズのキャップ

レプリケーションスロットが有効になっている場合、PostgreSQLがレプリケーションスロットによって要求されたWALファイルを保持しようとするため、ディスク領域が不足する場合があります。これは、スタンバイが一時的にダウンしている、遅延している、または単に孤立したレプリケーションスロットが原因で発生する可能性があります。

PostgreSQL 13以降、 max_slot_wal_keep_size を利用できます。

構成オプションは、レプリケーションスロットがチェックポイント時にpg_wal ディレクトリに保持できるWALファイルの最大サイズを制御します。デフォルトでは、PostgreSQLではmax_slot_wal_keep_size は-1 に設定されています。これは、レプリケーションスロットが無制限の量のWALファイルを保持できることを意味します。その結果、レプリケーションスロットのサポートが有効になっているときにmax_slot_wal_keep_size を明示的に設定することをお勧めします。例

# ...
postgresql:
  parameters:
    max_slot_wal_keep_size: "10GB"
# ...

レプリケーションスロットの監視

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

参考

CloudNativePG展開をモニタする方法の詳細については、 ClusterMonitoringTLSConfiguration {postgresql-cnpg-io-v1-ClusterMonitoringTLSConfiguration} を参照してください。