🏗️
データシステムの統合設計
バッチとストリームを統合し、DBを「アンバンドル」して再構成する考え方。DDIAの結論として、派生データとデータフローの全体設計を理解する
定義
本ファイルはDDIAの第12章「データシステムの将来」を整理したもの。個々のデータシステム(DB、キャッシュ、検索インデックス、ストリームなど)を独立したブラックボックスとして扱うのではなく、データフロー全体を一つのシステムとして設計する考え方。
データシステムの現実
アプリケーション
│
├── PostgreSQL(書き込みの正とする)
├── Redis(キャッシュ)
├── Elasticsearch(全文検索)
└── Kafka(非同期処理)
問題:
これらは別々のシステム。どうやってデータを同期するか?
どれかが故障したとき整合性はどうなるか?
典型的な「泥団子」設計:OLTPにすべて書き込み、定期バッチで他に同期。遅延・整合性不足・スケール困難の三重苦。
派生データ(Derived Data)
真実の源(Source of Truth):
書き込みが最初に到達するデータ(正規化されたデータ)
派生データ(Derived Data):
真実の源から変換・集計して作られるデータ
→ いつでも再計算できる
→ キャッシュ、検索インデックス、マテリアライズドビューはすべて派生データ
派生データの重要な特性:正しい変換ロジックがあれば、いつでも再構築できる。これがデータシステム設計の「べき等性」。
DBのアンバンドリング(Unbundling)
現代のDB(PostgreSQL等)は内部に多くの機能を統合している:
PostgreSQL の内部:
├── WAL(変更ログ)
├── インデックス(二次インデックス)
├── マテリアライズドビュー
├── レプリケーション
└── フルテキスト検索(tsvector)
「アンバンドリング」とは、これらの機能を専用のシステムに分離し、変更ログ(イベントストリーム)でつなぐ考え方。
PostgreSQL(書き込みの正)
└── WAL → Kafka(変更ログ)
├── → Elasticsearch(検索用派生データ)
├── → Redis(キャッシュ用派生データ)
└── → BigQuery(分析用派生データ)
CDC(Change Data Capture)
DBの変更をリアルタイムにストリームとして流す技術。
ツール:
Debezium: PostgreSQL/MySQL/MongoDBのWALをKafkaに流す
Maxwell: MySQL BinlogをKafkaに流す
仕組み:
DBのレプリケーションプロトコルを模倣してバイナリログを読む
→ アプリを変更せずに変更ストリームが得られる
Lambda Architecture の問題と Kappa Architecture
Lambda Architecture(2014年頃)
Input → バッチ層(正確・遅い)──→ クエリ層(マージ)→ Output
→ スピード層(速い・近似)─┘
問題:同じロジックを2つのシステムで保守しなければならない。結果の整合性管理が複雑。
Kappa Architecture
Input → ストリーム処理層(KafkaのログをReplayして再計算可能)→ Output
Kafkaに全イベントを長期間保持。「再処理が必要になったとき」はコンシューマーグループのオフセットを最初に戻してストリームを流しなおす。バッチ処理が不要になる。
前提:ストリームエンジン(Flink等)が過去データの一括処理も高速にできること。
データフロー設計の原則
不変のイベントログを中心に据える
「状態の変更をイベントとして記録する」という考え方:
状態中心の設計:
UPDATE orders SET status = 'shipped' WHERE id = 1
イベント中心の設計:
INSERT INTO events (type, payload) VALUES ('OrderShipped', {orderId:1, ...})
イベントから現在の状態を常に再計算できる
→ バグ修正を過去データに遡って適用できる
→ 任意の時点の状態を再現できる(タイムトラベル)
書き込みの境界と読み取りの最適化を分離
書き込み経路:
単一の信頼できるデータストアへ最初に書く
読み取り経路:
ユースケースごとに最適化されたビューを非同期で生成する
→ これはCQRSの物理的な実装そのもの
データメッシュ(Data Mesh)への発展
DDIAの思想を組織設計に拡張したアーキテクチャパターン。
従来の集中型データレイク:
全チームのデータを中央チームが管理 → ボトルネック
データメッシュ:
各ドメインチームがデータプロダクトを所有・公開
→ 注文ドメインは「注文イベントストリーム」をプロダクトとして提供
→ 他のチームが自律的に消費・変換
4つの原則:
- ドメイン所有のデータ(データの分散所有)
- データをプロダクトとして扱う(SLAあり、発見可能)
- セルフサービスデータプラットフォーム(インフラの共通化)
- フェデレーテッドガバナンス(中央ポリシー + 自律実装)
整合性の考え方の転換
従来の考え方:
「整合性はDBが保証する」→ 2PCで強制
DDIAの結論:
「整合性はアプリケーションが設計する」
→ 不変のイベントログが単一の真実の源
→ すべての派生データはいつでも再構築できる
→ 非同期・結果整合で十分なケースが多い
→ 本当に線形化可能性が必要なケースだけZooKeeper等を使う
DDIA シリーズ全体のまとめ
データの保存:
← データモデル・ストレージエンジン・エンコーディング
データの分散:
← レプリケーション・パーティショニング
データの一貫性:
← トランザクション・分散問題・合意
データの処理:
← バッチ処理・ストリーム処理
全体の統合:
← Saga・CDC・アンバンドリング・Kappa Architecture
関連概念
- → バッチ処理(Lambda/Kappa Architectureの詳細)
- → ストリーム処理(CDCとの統合)
- → CQRS(派生データの設計パターン)
- → イベントソーシング(不変ログの応用)
- → Sagaパターン(サービス間の整合性設計)
出典・参考文献
- Martin Kleppmann, Designing Data-Intensive Applications (2017) Chapter 12
- Jay Kreps, “Questioning the Lambda Architecture” (2014) — O’Reilly
- Zhamak Dehghani, Data Mesh (2022) — O’Reilly
- Debezium Documentation — debezium.io
- 1. 🗄️データ志向アプリケーション設計:概要
- 2. 🧩データモデルとクエリ言語
- 3. 💾ストレージエンジンとインデックス
- 4. 🔁レプリケーション
- 5. 🍕パーティショニング(シャーディング)
- 6. 🔒トランザクションとACID
- 7. ⚡分散システムの本質的な問題
- 8. 🤝一貫性と分散合意
- 9. 📦バッチ処理
- 10. 🌊ストリーム処理
- 11. 📋エンコーディングとスキーマ進化
- 12. 🔗Sagaパターンと分散トランザクション
- 13. 🏗️データシステムの統合設計
出典: Martin Kleppmann, 'Designing Data-Intensive Applications' (2017) Chapter 12