Introducing Aiven for PostgreSQL® change data captureの翻訳です。
2021年6月22日
PostgreSQL®の変更データ取得のためのAivenのご紹介
(更新) PostgreSQLはどのようにデータの変更をキャプチャするのでしょうか?この投稿を読んで、利用可能な方法を見てみましょう。
変更は常に起こります。あなたのデータでさえもです。(では、PostgreSQLのデータがテーブル内で変更され、迅速な対応が必要になった場合はどうなるのでしょうか?
たいていの場合、あなたの会社のシステムを通過するデータの旅は、最初の格納場所で始まり、最初の格納場所で終わります。実際、ETL(Extract、Transform、Load)の話をしているのであれば、これらの更新は定期的(例えば毎日や毎週)にしか実行されないかもしれません。
もし、情報が離れた地点ですぐに必要とされ、タイムリーにアクションを起こせるとしたらどうだろうか?
数年前までは、定期的な一括更新がデータベース全体をコピーする唯一の選択肢でした。幸いなことに、変化は起こり、進歩も起こります。現在では、同期操作中に変更点だけを複製することができます。
デルタ(つまり、変更されたデータ)のみを転送することは、テーブル全体をミラーリングしたりクローンするよりもはるかに効率的です。さらに、この変更は容易にロールバックしてデータストアを以前の状態に戻すことができます。
この記事では、Aiven for PostgreSQLがどのように変更されたデータをキャプチャするかを見ていきます。
組み込みの変更データ取得
チェンジ・データ・キャプチャ(CDC)とは、変更されたデータを特定(追跡)するために使用される一連のソフトウェア設計パターンのことである。変更されたデータに対してのみアクションを実行できるため、リソースと時間を大幅に節約できる。
PostgreSQLには、すべての変更を記録するWAL(write-ahead log)という形で、このための機能が組み込まれています。WALは通常、特定の状態に戻すために再生することで、データ復旧に使用されます。
WALはPostgreSQLインスタンスの状態に関する真実の情報源です。PostgreSQLのテーブルはログの問い合わせ可能なキャッシュと考えることができます。
いくつかの問題の解決論理デコードによるCDC
PostgreSQLでは、論理デコードとは、WALの内容をSQL文のようなアプリケーション固有の形式にデコードする処理を指します。
最新のアプローチでは、PostgreSQLはWALを復号化することで、全てのデータベースの変更を追跡することができます。PostgreSQLは複数の異なる論理復号出力プラグインをサポートしており、異なる形式でデータを出力することができます。CDC WALベースのアプローチは、これまで取り上げたものの中で圧倒的に効率的です。PostgreSQLがクラッシュリカバリのために既に書き込んでいたWALを利用することで、二重書き込みの必要性をなくします。
CDCに論理デコードを使用することで、全てのDML(`INSERT´、´UPDATE´、´DELETE´)の変更を追跡し、特定の変更のサブセットの読み取りを許可することができます。実際、変更単位はコミットされたデータ行に過ぎません。
論理データデコーディングによるCDCは、´postgresql.conf´で以下のパラメータを設定することで簡単に有効にすることができます:
wal_level=logical
max_replication_slots = 10 # 少なくとも1つ
max_wal_sender = 10 # 少なくとも1つ``クリップボードにコピーする
次に、特定のレプリケーション・ロールを作成する:
`$ CREATE ROLE foo REPLICATION LOGIN;`クリップボードにコピーする
この種のアプローチは多くのPostgreSQLドライバ(JDBCやPythonのpsycopg2を含む)でサポートされており、その使用方法はCDCを超えてレプリケーションや監査にまで広がっています。
とはいえ、これにはいくつかの顕著な欠点があります。ひとつは、論理デコードによるCDCでは、テーブルのカラム追加などのDDL変更をレプリケートできないことです。イベントトリガを設定してレプリケーションシステムに関連するDDLを実行させるなどの回避策はありますが、PostgreSQLはまだこれをネイティブにはサポートしていません。
しかし、利用可能な出力プラグインは全てのデータ型をサポートしているわけではありません。また、障害が発生した場合、レプリケーションスロットがスタンドバイフェイルオーバーに引き継がれないため、ノードを失った場合、優雅には扱われません。
最後の制限は、与えられたストリームの変更は単一の論理データベースのみに関係するということです。
このアプローチのいくつかのバリエーションを見てみよう。
pg_recvlogicalとwal2jsonによるCDC
Euler Taveira de Olivieraによって開発され、GitHubでホストされているwal2json
は、論理的な変更をJSONフォーマットにデコードすることで動作する。JSONが通常扱うデータ型に限定されるが、wal2jsonはAivenでサポートされている。また、wal2json
は Apache Kafka Debezium プラグインで動作する。
pg_recvlogical は論理変更の受信を可能にするコマンドラインツールである。pg_recvlogical
を wal2json
と共に設定すると、すべての論理的変更を受信してファイルに書き出すことができる。しかし、1つの欠点があります。1つの受信者が1つのファイルに変更を書き込むことです。その1つのファイルが失われると、変更のログ全体を失うことになる。
データの変更を直接アプリケーションに送る
最も単純なCDCのアプローチは、おそらくトランザクションログを読み込む必要のあるターゲットアプリケーションにプッシュするだけでしょう。必要なことは、PostgreSQLの論理的な変更をすべてアプリケーション自体に直接書き込むことだけです。データは転送中に変換され、リアルタイムで処理することができます。
この方法の利点は以下の通りです:
1.マスターデータベースへのパフォーマンスへの影響が最小限である。
2.アプリケーションやデータベース・テーブルへの変更が不要。
多くの場合、この直接ログベースのCDCが選択されるアプローチである。
アプリケーションをホストしているノードがダウンすると、その変更データを処理する能力もダウンします。さらに重大なのは、複数のアプリケーションが同じ変更を読み取る必要がある場合、1つのWALを同時に読み取ることによるリソースのロックやパフォーマンスの低下といった問題に直面する可能性があるということです。それではどうするのか?
ストリーミング・プラットフォームを使用するCDC
複数のアプリケーションがPostgreSQLから直接データを消費する代わりに、変更データを仲介するストリーミング・プラットフォームを使って、変更の取り込みと配信のフェーズを分離する方がよい。もちろん、Apache Kafkaのことです。
上述したように、すべてのアプリケーションが個別にPostgreSQLインスタンスに接続すると、PostgreSQLインスタンスのパフォーマンスが低下する可能性があります。さらに、複数のアプリケーションがPostgreSQLのWALにアクセスしようとすると、問題が発生する可能性があります。
コンシューマ・アプリケーションにデータを提供するためにApache Kafkaを使用する場合とは対照的です。このシナリオでは、Apache KafkaのプロデューサがKafkaに変更を送信し、切り離されたコンシューマアプリケーションが自分のペースでその変更を消費することができます。
これにより、これまでのアプローチにあった単一障害点の問題が解決される。一般的に、ストリーミング・プラットフォームを使用することで、任意の数の読者が同じデータにアクセスし、簡単に後処理を行うことができる。また、コンシューマを追加しても、PostgreSQLデータベースの負荷は増えないので、必要に応じて拡張することができます。
しかし、何事にもコストがかかります。分散システムをもう1つ追加することになり、アーキテクチャ全体の複雑さが増します。この方法を取る前に、この種の機能が必要であることを確認してください。
Apache Kafkaは信頼性が高く、スケーラブルで、データのストリーミングに適している。そして、CDCを念頭に置いて特別に拡張された場合は、CDCのためにさらによく機能する。
Debeziumの紹介
Debeziumはそのような機能拡張です。これはKafkaの上に構築された抽象化レイヤで、アプリケーションやメッセージングサービスがPostgreSQLインスタンスからの挿入、更新、削除(DML)に直接応答できるようにします。Debeziumは監視デーモンのように動作し、対象データベースの行レベルの変更をスキャンし、コミットされた順にストリーミングします。
Debeziumには、Kafka Connectを使用したApache Kafka用のコネクターを含む多くのコネクターが付属しています。MySQL、MongoDB、PostgreSQL、Oracle、SQL Server、Cassandraを含む様々なデータベースをサポートしています。
Debeziumは、Kafkaトピックに変更のストリームをレプリケートするために論理レプリケーションを使用する。Debeziumは、受信したデータに対してカスタム変換コードを実行することができ、PostgreSQLの組み込みのネイティブなpgoutput
フォーマット、protobuf
出力プラグイン、または先に説明したwal2json
をサポートしている。
Debezium は頻繁に Kafka を中心としたアーキテクチャの基礎を形成します。このような場合、データがいつ、誰に、どのように消費されるかを事前に知る必要はないし、気にする必要もない。いったんデータがKafkaに入れば、Kafka Connectコネクターを使って複数のダウンストリームシステムやストアにデータを配信することができる。もちろん、PostgreSQLの変更にもリアルタイムで対応できる。
いくつかのDebezium - PostgreSQLの問題点
PostgreSQLマスターのフェイルオーバーが発生すると、PostgreSQLのレプリケーションスロットが消えてしまうことに注意してください。事前に作成されていないトピックを使用している場合、クリーンアップポリシーがCOMPACT
ではなくDELETE
に設定され、データの永続性に影響を与えます。
さらに、UPDATE
と DELETE
の両方の変更を反映させたい場合は、REPLICA IDENTITY FULL
を設定する必要があります。
まとめ
今日、変更されたデータは論理デコードと直接レプリケーションを使って簡単にPostgreSQLに取り込むことができます。特に複数のダウンストリームアプリケーションが同じ変更を必要とする場合、その限界は明らかです。より堅牢なソリューションとしては、Apache KafkaとDebeziumを使って、PostgreSQLデータベースの変更の取り込みと、そのデータの膨大な種類(数)のダウンストリームシステムへのレプリケーションを切り離すことができます。
次のステップ
次のステップとして、Aiven for PostgreSQLをチェックしてみてください。
まだAivenのサービスをご利用でない方は、https://console.aiven.io/signupから無料トライアルにお申し込みください!
それまでは、changelogとblogのRSSフィード、またはLinkedInとTwitterのアカウントをフォローして、製品や機能関連の最新情報をご確認ください。
情報源
1.データ取得パイプラインをPostgreSQLからKafkaに変更
2.CDC for a brave New World: Hannu Valtonen presents at PostgresConf US 2018
3.Debezium.io