DDIA 导读(十二):数据系统的未来
2026/9/13 20:57:21 网站建设 项目流程

本文是《Designing Data-Intensive Applications》(DDIA,中文译名《数据密集型应用系统设计》)第 12 章的导读。DDIA 是 Martin Kleppmann 所著的分布式系统经典,本系列逐章导读,把书的核心概念讲清楚。

一句话主旨

单个数据库不是孤立存在的——它总是某个更大数据流的一环。数据从源头经过若干转换落到多个目标系统,每个系统都是同一个底层数据的"派生视图"。DDIA 终章的核心是:如何让这些派生视图保持一致、可溯源、可重算?原书重心不在预测而在综合——以日志为中心把异构系统粘起来,并用端到端正确性保证跨系统一致。


核心概念拆解

1. 派生数据(Derived Data)——本章的核心概念

转换1: 结构化抽取

转换2: 文本索引

转换3: 统计聚合

源头数据
(原始文档/日志)

派生视图1
(元数据表)

派生视图2
(全文检索索引)

派生视图3
(聚合仪表盘)

派生数据的关键属性

  • 可从源头重算:派生视图不是"源数据",丢了能从源头重建。只有源头是"事实之源"(source of truth)。
  • 冗余但一致:多个视图存的是同一数据的不同侧面,冗余但应逻辑一致。
  • 更新有延迟:源头变了,派生视图要时间同步(批有批的延迟,流有流的延迟)。

当一个系统存的数据能从另一个源头重新生成,它就是派生视图而非事实之源。识别哪些是派生数据、哪个是源头,是数据集成设计的起点。

为什么不能直接双写?很多人想"源头变了,同时写多个目标系统"来保持一致——这叫双写,是派生数据纪律的核心病因。跨系统无法原子提交,部分失败导致副本永久分叉:写系统 A 成功、写系统 B 失败,A 有了新值 B 还是旧值,之后没有机制自动修复,分叉就此固化。正确做法是单写源头 + 变更传播:只写源头,用 CDC 或批处理把变更传播到派生视图,传播可重放、可对账。

2. Lambda 架构 vs Kappa 架构——批流如何统一

Kappa 架构: 只有流

输入

流处理(可重放)

服务层: 只有流结果

Lambda 架构: 批层+流层+服务层

输入

批层(Batch Layer)
批处理全量重算

流层(Speed Layer)
流处理实时增量

服务层: 合并批结果+流增量

Lambda 架构

  • 批层:定期全量重算(准确但慢)
  • 流层:实时增量(快但可能不准/有错)
  • 服务层:查询时合并批结果 + 流增量
  • 问题:维护两套代码(批 + 流),逻辑要重复实现,易不一致

Kappa 架构

  • 只有流处理一层(但流可重放且保留足够历史,所以能"回到过去"重算全量)
  • 用可重放的消息日志(Kafka)当源头,重算 = 回退 offset 重放
  • 优势:一套代码,只有流逻辑
  • 条件:消息可重放(Kafka)+ 流处理支持状态重算,且保留足够历史

Lambda 的痛点是两套代码要保持逻辑一致——批层改了流层也要改,容易漂移。Kappa 用一套流代码替代,但要求消息可重放和流处理能重算状态。

3. 数据库的 unbundling——"数据库"是多个组件的打包

DDIA 一个深刻观点:传统数据库内部做的很多事(索引、物化视图、缓存、复制),在分布式数据栈里被"解包"成独立组件

分布式栈(解包)

传统数据库(打包)

解包成独立组件

解包成独立组件

解包成独立组件

解包成独立组件

解包成独立组件

存储引擎 + 索引 + 物化视图 + 缓存 + 复制
全在一个进程

存储: 列存DB

索引: 检索引擎

物化视图: 批处理聚合

缓存: Redis

复制: 消息队列CDC

Unbundling 的含义

  • 传统数据库把存储/索引/物化视图/缓存/复制打包在一个系统里,用事务保证一致
  • 分布式栈把这些拆成独立系统,每个可独立选型、独立扩展、独立演进
  • 代价:跨系统没有事务,一致性要应用自己保证
  • 好处:每个组件可独立选型和扩展

趋势本质:数据库内部的机制(索引、物化视图、CDC、复制)正在变成独立工具。未来不是"选一个数据库",而是"选一组工具 + 自己设计集成"。这降低了组合门槛(任何组件可替换),也提高了要求(要懂数据库内部原理才能组合好)。其中日志(如 Kafka)是核心黏合剂——数据库内核早就在用日志(WAL/redo log)做复制和恢复,unbundling 只是把这根日志从数据库内部拉出来,变成跨系统的统一变更流。

Unbundling 后跨系统没有事务,端到端正确性要应用自己保证。集成纪律是用管线+调度+契约部分替代失去的事务。

4. 端到端正确性(End-to-End Correctness)

派生数据最容易出的问题:源头变了但派生视图没跟上(或反过来)。DDIA 强调端到端正确性——从源头到派生视图,数据应"不多不少"地一致。DDIA 借用 Saltzer 的端到端论据:跨系统的"恰好一次"只能靠端到端保证,不能指望中间任何单跳。

转换

端到端校验

源头: N条记录

管线

派生视图: 应有N条

源头数 == 派生数?

端到端正确性的保障手段

  • 唯一标识贯穿:源头和派生视图用同一 id,能对账
  • 可重算:派生视图能从源头重建,出错了能重算修复
  • 对账机制:定期校验源头数 vs 派生数,发现不一致
  • 幂等导入:重跑不重复

派生数据最容易"看起来对实际错"——中间结果表面正常,但和源头对不上。只有端到端校验能兜底。不信任派生结果、回到源头验证,是数据集成的核心纪律。

问题→方案:问题——同一数据要派生成多个视图(元数据表、全文索引、聚合仪表盘),跨系统没有事务保证一致。场景——分布式数据栈把传统数据库内部的索引/物化视图/缓存"解包"成独立组件,各组件独立选型但失去跨系统事务。方案——派生数据纪律:源头是唯一事实之源,派生视图可重算;用唯一标识贯穿实现对账,定期校验源头数 == 派生数;幂等导入保证重跑不重复。Lambda 用批+流两层(两套代码易漂移),Kappa 用一层可重放流(一套代码但要求消息可重放)。

5. 数据血缘(Data Lineage)——追踪数据从哪来

原始文件

抽取/下载

中间数据

目标1: 索引

目标2: 表

统计报告

血缘的价值

  • 排障:派生视图出问题,顺着血缘回溯到源头定位
  • 影响分析:源头某字段变了,知道影响哪些派生视图
  • 合规:数据从哪来、经过什么处理

6. 批/流做集成——同步 vs 异步派生

更新定期全量/增量实时持续
延迟分钟~小时毫秒~秒
复杂度高(CDC/状态/水位线)
一致性窗口大(批之间不一致)小(近实时)

一致性窗口多小才值得上流——如果场景不需要近实时,批同步完全够,上流是过度工程。流的复杂度成本只在"批给不了的延迟"时才值得付。越来越多系统从"批同步"转向"流式 CDC",把一致性窗口从小时缩到秒,但这按需推进,不盲目上 CDC。


尾声:原理长存,工具会换

DDIA 终章不教新技术,而是给前 11 章画一个方向坐标。最大的趋势是把数据库内部的技术(流、CDC、物化视图、端到端正确性)变成通用工具,让任何应用都能用上。端到端正确性将成为应用层的通用要求——unbundling 后跨系统没有事务兜底,催生工具和框架让应用层声明"数据应满足什么不变量"、系统自动校验。

导读补充观点:数据工具越来越易用,让非专家也能用,但底层原理的重要性不变——工具替你做了决策,你要懂原理才能判断工具的决策对不对。懂原理让你能快速评估新工具、判断它的取舍、预判它的坑。工具会换,原理长存——学 DDIA 的回报正是"工具换了一茬仍能快速评估取舍"。

DDIA 最后提到数据伦理与隐私:数据收集、使用、隐私、偏见。这不是纯技术,但作为数据基础设施工程师,要意识到数据的影响——数据从哪来、能否用、有什么影响。

工具会换(具体系统)

具体数据库版本

具体消息队列

具体调度器

具体批/流引擎

演进方向

原理长存(DDIA教的)

端到端正确性思维

存储引擎取舍(列存/LSM/B-Tree)

复制/分区/一致性原理

事务与隔离级别

数据集成纪律(契约+对账)

批→流(按需, 不盲目)

对账系统化(每个派生视图)

集成契约统一

unbundling组合能力


DDIA 12 章导读至此全部完成。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询