😺

CDC(Change Data Capture)で開発を高速化する

2022/09/22に公開

Kafkaを触ってみて、これいいじゃんってなったのがつい半年前。
ただ、KafkaはKafkaで個人で使うにはすごく高い!

Schema Registry、KSQL、zookeeper、Kafka、Kafka Connectと
後はお好みでTopic系のUIとRest Proxyなどもうそれはそれはたくさん必要でした。

ECSのEC2で最小メモリでそれぞれたちあげたりしましたが、どんなにカンバっても月3万くらいかかりました。
なのでそういうのはやはり仕事でやります。

そこでKafkaを個人て使うことは諦めてたのですが、そこで見つけたこの記事。

https://qiita.com/fetaro/items/c8420f5de48f48317391

KafkaなしてRDBの変更データキャプチャが取れることを知りました。

改めて変更データキャプチャが取れる仕組みを棚卸ししました。
前提として、データベースから外部のサービスにれんけいできるものとします。

AWS DMS

https://aws.amazon.com/jp/dms/

SourceにはRDSなどが指定でき、Replication Instance(多分複製されたRDB)を立ててそこから、Targetに対してデータを配信する。
DMSはマネージドサービスなので、ローカルでDockerで構築できない。テストなどは単体テストをメインで保守性を高める必要があり。

Debezium Server(OSS)

https://debezium.io/documentation/reference/stable/operations/debezium-server.html

KafkaのConnectでRDBからwalを使用してlogical replicationしたものをstreamにするときによく使われる。ただ、単体でserverが構築できるのはあまり知られてない模様。
自分が検証したのは、AWSのRDSとGCPのCloudSqlで、どちらもpostgresを使用した。ただ、後述するけれど、RDSはちょっと運用が難しい印象でした。

GCP Datastream

https://cloud.google.com/blog/ja/products/databases/new-cloud-based-cdc-replication-across-databases

serverlessで料金体系を見る限りではインスタンスに対しては課金されていないで、純粋にデータ送信量での計算になっている模様。

Kafka Connect(Debezium)

https://debezium.io/documentation/reference/stable/architecture.html

Kafka Connectで使用される。

どれくらいの規模か

小規模くらいなら、debezium-serverから、awsならkinesisそして、gcpならcloud pub/subにstreamして対応できるだろう。実際自分は、お金をかけたくないのでcloud pub/subで運用している。

どれくらいのイベントを流せるかはちょっとわからないけれど、
更新頻度、キャプチャーしたいテーブル数によってはちょっと大きめのdebezium-serverを立てることで足りることもあると思う。あとはcpuとmemoryを見てください。

どんな用途か

たとえば、マーケティング用にデータをレプリケーションしたい場合なんかは、フルマネージドなサービスを使ったら良さそう。

たとえば、アプリケーションで注文完了などのトランザクションを非同期にリッチにしたいや、メール送信を非同期に送りたいなどの場合は、outboxパターンなどでしっかりtransactionをはってでーたをとうろくしつつ、イベントをstreamしてメール送信や、テーブルをリッチにするなどのことをしたいのならdebezium-serverなどは開発しやすいと思う。topic routingやlocal環境の構築といった点で非常に便利。

どんな用途があるのかについては、その道のプロであるconfluentのtutorial兼cookbookを参考にしてみてください。
https://developer.confluent.io/tutorials/

debezium-serverをAWSで使ってみた感想。

先ほども少し触れたのだけれど、RDSの場合はちょっと運用に難があるのがわかりました。
開発環境でほとんど書き込みがない場合に放置すると、diskfullのエラーが頻繁に生じました。
最初は、全く原因がわからずとりあえずディスク容量を増やして対応していたのですが、ディスク容量に対しても課金されるのでこれはまずいというふうに色々試行錯誤しました。

結果わかったのは、データベースの設定の問題ではなくaws側で我々使用者に見えないところで頻繁に書き込みを発生させているようなので、勝手にwalが増えていき、postgresのslotに消費されない変更履歴がどんどん溜まっていってました。slotに蓄積したデータがでかくなりすぎると、当然ディスク容量もふえますが、slot自体も途中で使用不可になりました。

なので、awsのRDSのcdcをやるならdebezium-serverではなく、dmsからkinesisやkafkaに流すということが必要そうです。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/diskfull-error-rds-postgresql/

下記のSQLを実行したときになにもしなくてもどんどんreplicationSlotLagが増えていきます。。。。

SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) AS replicationSlotLag, 
active FROM pg_replication_slots ;

ただ、ECSでもdebezium-serverは構築できたので、自前のterraformでci/cdのcdまでは一瞬で構築できました。

debezium-serverをGCPで使ってみた感想。

cloudsqlでpostgresをたてて、cloudrun上で起動させたdebezium-serverから変更差分を取得しました。cloudrunでのdebeziumサーバーの構築は、

  • 常にcpuを割り当てる
  • 実行を環境を第2世代にする。

のオプションを有効にさせることで、簡単に起動できました。
awsであったようなよくわからないけど、replicationSlotLagが増えるということもありませんでした。
debezium-serverで取得した変更はcloud pub/subに流すことですべてgcpでそれにお安く構築できます。awsのkinesisはたかい。。

まとめ

debezium-serverであればサクッと、ローカル環境も構築できるし、outboxパターンを使った機能開発やpurpose buildなデータベース構築も捗ります。
実際にelasitcsearchなどのデータ連携もスムーズでした。メール送信も楽勝です。

Discussion

ログインするとコメントできます