PeerDB + ClickHouse + MySQL でCDC検証をしてみた話

目次

PeerDBとは

公式ドキュメントの「What is PeerDB?」より一文引用します。

https://docs.peerdb.io/introduction

What is PeerDB?

At PeerDB, we are building a fast, simple and the most cost effective way to stream data from Postgres to Data Warehouses, Queues and Storage engines.

(PeerDBでは、Postgresからデータウェアハウス、キュー、ストレージエンジンへデータをストリーミングするための、高速でシンプルかつ最もコスト効率の高い方法を開発しています。)

上記公式ドキュメントの文言からわかるように、PeerDBは元々PostgreSQL向けに開発されていたETLツールですが、最近ではMySQLにも対応しています。 しかし、依然としてQuickstart GuideなどにPostgreSQL用手順は載っていても、MySQL用手順がないのが現状です。 そこで、今回は、MySQL用PeerDB Quickstart Guideと称して、チュートリアル的な内容の記事を用意しました。

なお、MySQLもサポートされていることが公式ドキュメントから確認できますので、安心して使えます。

https://docs.peerdb.io/features/supported-connectors

検証の目的

今回は、以下の構成でCDC(Change Data Capture)によるデータ同期の動作を検証しています。

  • MySQL: ソースデータベース

  • PeerDB: ETLツール

  • ClickHouse: ターゲットデータベース

検証の目的は、MySQLで発生したINSERT/UPDATE/DELETEの変更イベントが、PeerDBを通じてClickHouseにどのように反映されるかを確認することです。

バージョンは以下の通りです。


検証環境の準備

まずはPeerDBを起動し、ClickHouseとMySQLを同じDockerネットワークに接続します。 ここではDockerを使って環境を構築しました。

PeerDBの起動

https://docs.peerdb.io/quickstart/sql-quickstart より抜粋

ClickHouseの起動

https://clickhouse.com/docs/jp/install/docker より抜粋

PeerDBと同じDockerネットワークに接続します。

ClickHouse側では、PeerDBが書き込みできるように必要な権限を付与しています。

https://docs.peerdb.io/connect/clickhouse/clickhouse-cloud より抜粋

MySQLの起動

次にMySQLを起動し、PeerDB用のユーザーを作成します。

PeerDBに正しくバイナリログを受け渡すためには、binlog_row_metadataシステム変数をFULLに設定する必要があります。そのため、カスタムmy.cnfを使用してMySQLコンテナを作成しました(その他の設定値はMySQLイメージのデフォルトを保持しています)

https://dev.mysql.com/doc/refman/8.4/en/docker-mysql-getting-started.html より抜粋

 

PeerDBと同じDockerネットワークに接続します。

MySQL側のユーザーは以下のように作成しました。

必要な権限については、公式ドキュメントの説明ページが見当たりませんでしたので、PostgreSQL用の権限を見様見真似で作ってみたり、エラーメッセージを見て追加したりしました。参考程度に留めていただければ幸いです。

  • REPLICATION SLAVE権限

  • REPLICATION CLIENT権限

  • performance_schemaSELECT権限



 

Peerの作成

Peerの作成(ClickHouse側)

ブラウザからlocalhost:3000にアクセスし、+ New PeerからClickHouse用の接続情報を登録します。

主要なパラメータ

項目

説明

Name

clickhouse

任意のPeer名

Host

clickhouse

ホスト名

Port

9000

ポート

User

peerdb_user

接続用ユーザ

Password

<your_password>

接続用パスワード

Database

peerdb

データベース

Disable TLS?

ON

TLS使用有無

検証目的のため、TLS暗号化を有効化しないをONにして、ClickHouseの9000ポート(非TLS用)を指定しました。

Validateボタンを押してPeer is valid成功表示が出ればOKです。そのままCreate peerで作成を完了します。

Peerの作成(MySQL側)

ブラウザからlocalhost:3000にアクセスし、Peersタブの+ New PeerからMySQL用の接続情報を登録します。

主要なパラメータ

項目

説明

Name

mysql

任意のPeer名

Host

mysql

ホスト名

Port

3306

ポート

User

peerdb_user

接続用ユーザ

Password

<your_password>

接続用パスワード

Disable TLS?

ON

TLS使用有無

検証目的のため、TLS暗号化を有効化しないをONにしました。

Validateボタンを押してPeer is valid成功表示が出ればOKです。そのままCreate peerで作成を完了します。


テスト用テーブルの作成(MySQL側)

CDC の動作確認用に、シンプルなテーブルを作成します。

初期データも投入しておきます。

peerdb_userにテストスキーマへの参照権限を与えます。


Mirrorの作成

ブラウザからlocalhost:3000にアクセスし、Mirrorsタブの+ New MirrorからCDC用のMirrorを作成します。

項目

説明

Mirror type

CDC

CDC, Query Replication, Xminの内から選択

Mirror Name

mirror

任意のMirror名

Source Peer

mysql

ソースPeer名を選択

Destination Peer

clickhouse

ターゲットPeer名を選択

Select tables to syncでは先ほど作成したテストテーブルtest.t1を選択します。

+ Create Mirrorで作成を完了します。


PeerDBで同期した結果

同期開始後、程なくしてMySQLのtest.t1がClickHouse側にpeerdb.test_t1として同期されていました。

以下の点に注意が必要です。

  • MySQL側のスキーマ構造がそのまま同期されない

  • ClickHouse側Peer作成時に指定したデータベースの中にテーブルが作成される

  • <データベース名_テーブル名>の名前でテーブルが作成される

    テーブル定義を見るに、ClickHouseの独自エンジンであるReplacingMergeTreeエンジンで作成されていることが確認できます。

    MySQLテーブル定義の既存列は自動的に型変換され、新たにPeerDB用やReplacingMergeTreeエンジン用に追加されたアンダースコア(_)から始まる列が3つあります。

    列名

    データ型

    説明

    id

    Int32

    intから自動型変換

    name

    String

    varcharから自動型変換

    _peerdb_synced_at

    DateTime64(9)

    行が同期された時刻

    _peerdb_is_deleted

    UInt8

    行の削除済みフラグ

    _peerdb_version

    UInt64

    行のバージョン

    この時点で、ClickHouseにはMySQLのデータが反映されていることが確認できました。


    CDCの検証

    次にMySQL側でUPDATEDELETEを実行し、その変化がClickHouseにどう届くかを確認します。

    MySQL側で更新・削除を実行


    ClickHouse側で変更履歴を確認

    PeerDBは変更をそのまま反映するのではなく、ReplacingMergeTreeを使って履歴を保持する形で同期しているようです。 そのため、ORDER BY _peerdb_synced_atで見ると、同一キーに対する複数の変更履歴が見えます。

    出力を見ると、以下の変化が確認できます。

    • id = 2name = Postgre行が追記されている

    • id = 3_peerdb_is_deleted = 1行が追記されている

    上記からわかる通り、MySQL側のUPDATEDELETEなどの更新系は全てINSERTに置き換わっています。 これは追記型(Append-Only)を前提とした更新処理であることが伺えます。


    FINALを付けた場合の見え方

    ReplacingMergeTreeのテーブルでは、FINALを付けることで最終的な状態を確認できます。

    結果は以下のようになり、最終状態としては

    • id = 1はそのまま

    • id = 2_peerdb_versionの新しいPostgre行のみが見える

    • id = 3_peerdb_versionの新しい_peerdb_is_deleted = 1行のみが見える

    であることがわかります。

    削除済みフラグが立っている行を除外したい場合はWHERE _peerdb_is_deleted = 0などの条件でSELECTすると良いかもしれませんね。


    検証してわかったこと

    今回の検証で、MySQLでもPeerDBを使ったCDCが問題なく動作することを確認できました。

    特に印象的だったのは以下の点です。

    • MySQLの変更がClickHouseにほぼリアルタイムで反映される

    • <データベース名_テーブル名>の名前でテーブルが作成される

    • UPDATE/DELETEINSERTとして追記型で処理される

    • ReplacingMergeTreeSELECT ... FINALを使うことで現在の最新状態を取得できるが、

      DELETEされた行は依然として見えてしまうためWHERE句による除外が必要


    まとめ

    PeerDBの公式ガイドはPostgreSQLを前提とした内容が中心で、MySQL向けの情報は多くありません。しかし、今回の検証ではMySQLでも問題なくCDCを動作させられることを確認できました。 ClickHouse側ではReplacingMergeTreeとバージョン列を使って変更履歴を扱っており、CDCの仕組みがイメージしやすい構成になっています。

    スマートスタイルTECHブログについて

    スマートスタイルTECHブログでは、日頃MySQLのサポート業務に従事している有資格者で構成された技術サポートチームがMySQLに関する技術情報を発信しています。データベースのお困りごとはお気軽にご相談下さい。

    よかったらシェアしてね!
    • URLをコピーしました!
    目次