Skip to content

第十二章:数据系统的未来

一、 数据集成与分拆数据库 (Data Integration & Unbundling)

1. 复杂应用的数据现状

在复杂的现代应用中,单一数据库无法胜任所有工作。通常需要组合多种工具: * 记录系统(System of Record):数据的权威来源(如 PostgreSQL)。 * 衍生数据系统(Derived Data Systems):为了特定访问模式而从记录系统生成的视图(如 Elasticsearch, Redis 缓存, 数据仓库)。

2. 分拆数据库(Database Unbundling)

这是本章的核心隐喻。作者建议将数据库的内部机制“由内而外”地翻转出来。

  • 传统数据库 vs. Unix哲学
    • 传统数据库:高度集成,提供SQL、事务、索引、持久化,像一个黑盒。
    • Unix / 分拆架构:由多个只做一件事的小工具组成,通过管道(Pipes)连接。
    • 新架构愿景:使用类似Unix管道的方式(流处理)连接不同的存储和处理引擎。
  • 关键概念:
    • 联合数据库 (Federated Databases / Polystore)统一读取。提供一个统一的查询接口来访问底层的异构存储。
    • 分拆数据库 (Unbundled Databases)统一写入。这是作者推崇的方向。通过变更数据捕获 (CDC)事件日志,确保数据写入一个地方后,能可靠地同步到所有衍生的存储系统中。

深度拓展:Lambda 架构 vs. Kappa 架构 * Lambda 架构:文中提到的一种过渡方案,同时维护批处理(保证准确性)和流处理(保证低延迟)两套代码路径。 * 统一方案(类似 Kappa):作者认为未来在于统一批处理和流处理。流处理引擎(如 Flink, Kafka Streams)越来越成熟,能够同时处理历史数据(重放日志)和实时数据,且保证“恰好一次”语义,从而消除了维护两套系统的复杂性。


二、 围绕数据流设计应用

1. 应用程序即衍生函数

  • 核心理念:将应用程序逻辑视为一个确定性函数
    • 输入:不可变的事件流(Event Log)。
    • 转换:应用代码(流算子)。
    • 输出:衍生数据(搜索索引、缓存、物化视图)。
  • 优势
    • 可演化性:当需求变更(如修改索引结构)时,只需重放历史事件日志,即可重建新的衍生视图,而无需进行高风险的数据迁移。
    • 容错性:基于日志的恢复比传统数据库的崩溃恢复更灵活。

2. 读写路径的权衡 (Read vs. Write Path)

任何数据系统都在做读写路径的平衡: * 写路径(预计算/Eager):在写入时做更多工作(如生成索引、更新缓存)。读取时快,写入时慢。 * 读路径(惰性/Lazy):在读取时做更多工作(如全表扫描、复杂计算)。写入时快,读取时慢。 * 应用场景:通过流处理,可以将复杂的查询逻辑(如多表Join、聚合)移到写路径上,预先生成物化视图,从而极大地加速读取。

3. 将状态推送到客户端

  • 现状:Web应用通常是无状态的(Stateless),状态在数据库中。
  • 未来(在线/离线协同)
    • 客户端(浏览器/手机)应被视为一种有状态的衍生数据系统
    • 服务器通过流(Server-Sent Events, WebSocket)将变更推送给客户端,而不是让客户端轮询。
    • 离线优先(Offline-first):客户端本地存储数据,离线可操作,上线后通过事件流同步。这需要解决冲突(类似 Git 或 CRDTs)。

三、 正确性:摆脱对 ACID 的盲目依赖

在分布式和异构系统中,实现传统的分布式事务(如两阶段提交 2PC/XA)代价极高且脆弱。作者提出了一种基于端到端原则的替代方案。

1. 端到端原则 (End-to-End Argument)

  • 原理:低层级的可靠性机制(如TCP校验和、数据库事务)不足以保证高层级(应用层)的正确性。
  • 案例:即使用户的请求在数据库层面是原子的,但如果网络超时导致客户端重试,仍可能导致重复扣款。
  • 解决方案:必须在应用层实现幂等性(Idempotence)。通过操作ID(Operation ID)在全链路进行去重。

2. 及时性与完整性的分离

作者将“一致性”拆解为两个维度: * 及时性 (Timeliness):用户能多快看到最新数据?(对应线性一致性)。延迟会导致“过时”,但通常可容忍。 * 完整性 (Integrity):数据是否丢失、损坏或矛盾?(对应原子性/持久性)。完整性是不可妥协的。 * 结论:在基于流的系统中,我们可以接受最终一致性(牺牲及时性),但通过恰好一次(Exactly-once)语义和幂等处理,严格保证完整性。这比分布式事务更具可扩展性。

3. 宽松的约束处理

  • 强约束:如“账户余额不能为负”、“用户名唯一”。传统上需要强一致性(共识算法),会降低可用性。
  • 补救性流程(Apologies/Compensations)
    • 现实世界中,许多约束是可以被临时打破的(如机票超售)。
    • 处理方式:先记录操作,事后检查。如果违反约束(如超卖),则触发补偿事务(如退款、道歉、提供优惠券)。
    • 这种无协调(Coordination-avoiding)系统性能更高。

四、 信任但验证 (Trust but Verify)

1. 软硬件并非完美

  • 硬件可能会发生比特翻转(Bit flips),软件会有Bug。仅仅依赖数据库的承诺(ACID)是不够的。
  • 数据损坏往往是悄无声息的。

2. 可审计性 (Audibility)

  • 不可变事件日志提供了极佳的可审计性。
  • 验证机制
    • 自我验证系统:后台持续运行检查程序,对比记录系统和衍生视图的数据一致性。
    • 密码学证明:利用 Merkle Trees(默克尔树)来验证数据的完整性,确保历史记录未被篡改(类似区块链或证书透明度 Certificate Transparency 的原理)。