ストーリー
田
田中VPoE
イベント駆動アーキテクチャでは、新しいイベントをプロデュースする設計を見た。しかし、既存のアプリケーションDBにはイベントを発行する仕組みがないことが多い
あなた
確かに、PostgreSQLやMySQLの変更をリアルタイムにデータ基盤に連携するにはどうすればいいですか?
あ
田
田中VPoE
それがChange Data Capture — CDCだ。データベースのトランザクションログ(WAL/binlog)を読み取り、INSERT/UPDATE/DELETEの変更をリアルタイムにストリームとして配信する
あなた
データベースのレプリケーションに似ていますね
あ
田
田中VPoE
まさにそうだ。ただしCDCの目的はデータ基盤への連携だ。ソースDBに負荷をかけずに、秒単位の遅延でデータをDWHに連携できる。従来の「日次でSELECT * FROM …」というETLとは根本的に異なるアプローチだ
CDCの仕組み
CDCの方式
| 方式 | 仕組み | メリット | デメリット |
|---|
| ログベースCDC | DB のトランザクションログを読み取る | ソースDBへの負荷が最小、削除も検出可能 | DB固有の設定が必要 |
| タイムスタンプベース | updated_at列で差分を検出 | 実装が簡単 | 削除が検出できない、タイムスタンプ列が必要 |
| トリガーベース | DBトリガーで変更を記録 | 柔軟 | ソースDBに負荷、パフォーマンス影響 |
| 差分比較 | 前回スナップショットとの差分を計算 | DB設定不要 | 大量のSELECT、高負荷 |
ログベースCDCの仕組み
ログベースCDC(PostgreSQL WAL の例):
┌──────────────────────────────────────────────┐
│ PostgreSQL │
│ │
│ テーブル: orders │
│ ┌─────────────────────────────────────────┐ │
│ │ INSERT INTO orders (id, amount, status) │ │
│ │ VALUES (1, 5000, 'pending') │ │
│ └────────────────────┬────────────────────┘ │
│ ↓ │
│ WAL (Write-Ahead Log) │
│ ┌─────────────────────────────────────────┐ │
│ │ LSN: 0/16B3740 │ │
│ │ Operation: INSERT │ │
│ │ Table: public.orders │ │
│ │ Data: {id:1, amount:5000, status:pending}│ │
│ └────────────────────┬────────────────────┘ │
└───────────────────────┼──────────────────────┘
↓
┌───────────────────────┴──────────────────────┐
│ Debezium (CDC Connector) │
│ ┌─────────────────────────────────────────┐ │
│ │ WALを読み取り、変更イベントに変換 │ │
│ │ Kafka Topic: dbserver1.public.orders │ │
│ └────────────────────┬────────────────────┘ │
└───────────────────────┼──────────────────────┘
↓
┌───────────────────────┴──────────────────────┐
│ Apache Kafka │
│ Topic: dbserver1.public.orders │
│ ┌─────────────────────────────────────────┐ │
│ │ { │ │
│ │ "op": "c", // c=create, u=update │ │
│ │ "before": null, │ │
│ │ "after": { │ │
│ │ "id": 1, │ │
│ │ "amount": 5000, │ │
│ │ "status": "pending" │ │
│ │ }, │ │
│ │ "source": { │ │
│ │ "ts_ms": 1718456789000, │ │
│ │ "db": "orders_db", │ │
│ │ "table": "orders" │ │
│ │ } │ │
│ │ } │ │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
CDCツールの比較
主要ツール
| ツール | ライセンス | 対応DB | デプロイ方式 | 特徴 |
|---|
| Debezium | OSS | PostgreSQL, MySQL, MongoDB, SQL Server, Oracle | Kafka Connect | 最も広く使われるCDCツール |
| AWS DMS | マネージド | 主要RDBMS + MongoDB | AWSサービス | フルマネージド、マイグレーション向け |
| Fivetran | SaaS | 主要RDBMS + SaaS | SaaS | ノーコード、簡単セットアップ |
| Airbyte | OSS | 300以上のコネクタ | セルフホスト / Cloud | OSSで柔軟、EL特化 |
| Striim | 商用 | 主要RDBMS | オンプレ / クラウド | エンタープライズ向け |
Debezium + Kafka Connect の構成
Debezium + Kafka Connect:
Kafka Connect Cluster
┌───────────────────────┐
PostgreSQL ───→│ Debezium Source │──→ Kafka Topic
MySQL ───→│ Connector │──→ Kafka Topic
MongoDB ───→│ │──→ Kafka Topic
└───────────────────────┘
↓
┌───────────────────────┐
│ Kafka Connect Sink │
│ Connector │
│ ├── S3 Sink │──→ データレイク
│ ├── BigQuery Sink │──→ DWH
│ └── Elasticsearch Sink│──→ 検索
└───────────────────────┘
CDCパイプラインの設計
データレイクへの取り込みパターン
| パターン | 説明 | レイテンシ | 複雑さ |
|---|
| CDC → Kafka → S3 (Bronze) | KafkaからS3にParquetで書き出し | 分〜時間 | 低 |
| CDC → Kafka → Flink → DWH | Flinkでリアルタイム変換してDWHに書き込み | 秒〜分 | 高 |
| CDC → Kafka → Kafka Connect → BigQuery | Kafka Connectで直接BigQueryに書き込み | 分 | 中 |
初期ロードと増分同期
CDC パイプラインの流れ:
Phase 1: 初期ロード(Initial Snapshot)
┌──────────────┐
│ ソースDB │ → テーブル全体をスナップショット → Bronze層
│ 10億レコード │ (数時間かかる場合あり)
└──────────────┘
Phase 2: 増分同期(Incremental Sync)
┌──────────────┐
│ ソースDB │ → WALの変更のみをリアルタイム配信 → Bronze層
│ INSERT/UPDATE │ (秒単位の遅延)
│ DELETE │
└──────────────┘
注意点:
- 初期ロード中にも変更は発生する
- スナップショットのLSN以降のWALを増分として適用
- Debeziumはこのハンドオフを自動で管理する
「CDCは『ソースDBの変更をデータ基盤にリアルタイムで同期する橋』だ。日次ETLではできなかった『ほぼリアルタイムのDWH更新』を、ソースDBに負荷をかけずに実現する」 — 田中VPoE
まとめ
| ポイント | 内容 |
|---|
| CDC | データベースの変更をリアルタイムにキャプチャし、ストリームとして配信 |
| ログベースCDC | WAL/binlogを読み取る方式が最もソースDB負荷が低い |
| Debezium | OSSで最も広く使われるCDCツール、Kafka Connectで動作 |
| パイプライン設計 | 初期ロード → 増分同期の2フェーズで構成 |
チェックリスト
次のステップへ
次は「リアルタイム分析基盤」を学びます。CDCとストリーム処理を組み合わせて、リアルタイムダッシュボードやリアルタイムMLを実現する設計を身につけましょう。
推定読了時間: 30分