《Designing Data-Intensive Applications》(DDIA)是一本由 Martin Kleppmann 编写的书,主要关注如何设计和构建现代数据密集型应用。书中详细探讨了构建高性能、高可用和可扩展的分布式系统的核心理念和技术。接下来对书中的一些关键概念进行整理,方便后续查阅。

数据复制

写后读一致性#P155

读自己的写

  • 从主节点读取可能会被修改的内容。
  • 跟踪最近更新的时间,就从从节点读取,监控从节点落后程度。
  • 记录最近更新的时间戳,如果不够新,则从主节点读取。

跨设备的写后读一致性#P156

单调读一致性#P157

两次读取在不同节点,导致前一次读到了,后面一次读不到的情况。

  • 每个用户在固定的副本读取

前缀一致读#P158

事务在性能与可用性方面的代价过高#P160

多主处理写冲突#P163

  • 分配写ID,最后一个成功。
  • 合并请求。
  • 保留冲突信息,交给上层解决。

自动解决写冲突#P166

  • 无冲突的数据类型。
  • 可合并的数据结构。
  • 操作转化。

无主节点复制#P168

Quorum 一致性的局限性#P172

量化究竟何为“最终”的价值#P174

最后写入者获胜#P177

并发性,时间和相对性#P178

版本矢量#P178

数据分片

事务将应用程序的多i个读写操作捆绑在一起成为一个逻辑操作单元。

AICD 更像是一种市场营销用语#P213

  • 各家数据库实现的 AICD 不尽相同。

  • 围绕隔离性有很多模糊不清的概念。

  • 在多线程编程中,原子性意味着现场无法看到当前线程的中间状态,而 ACID 的原子性不关注多线程的并发性,这一点由隔离性保证。

  • ACID 的原子性意味着事务可以终止,数据库可以丢弃那些局部完成的修改(undolog)。

字母 C 只是为了使 ACID 缩略词读起来更顺口#P215

一致性非常重要,但它在不同场景有着不同的具体含义,例如:

  • 第 5 章我们讨论了副本一致性以及异步复制模型时,引出了最终一致性问题(参见第 5 章“复制滞后问题”)。
  • 一致性哈希则是某些系统用于动态分区再平衡的方法(参见第 6 章“一致性哈希”)。
  • CAP 理论中,一致性一词用来表示线性化(参见第 9 章“可线性化”)。
  • 而在 ACID 中,一致性主要指数据库处于应用程序所期待的“预期状态”。

ACID 中的一致性主要是指对数据有特定的预期状态,任何数据的更改都必须满足这种状态约束(或恒等条件)。例如一个账单系统,账户的贷款余额应和借款余额保持平衡。

原子性,隔离性和持久性是数据库自身的属性,而 ACID 中的一致性更多是应用层的属性。应用程序可能借助数据库提供的原子性和隔离性,以达到一致性,但一致性本身并不源于数据库。因此,字母C其实并不应该属于 ACID。

读提交的缺陷场景#P226

  • 备份场景
  • 分析查询场景
  • 完整性检查场景

MySQL/Innodb 的可重复读不支持检测更新丢失#P232

写倾斜#P234

PostgreSQL、MySQL、Oracle 都不支持检测写倾斜问题

快照隔离级别可以避免只读场景的幻读#P234

实例化冲突#P237

通用编程言存储过程#P241

Redis/Lua

两阶段加锁#P242

意向锁?

谓词锁#P244

索引区间锁#P245

next key locking

可串行化的快照隔离#P246

SSI 新增了相关算法来检测写入之间的串行化冲突,并决定中止那些事务

基于过期的条件做决定#P247

分布式系统的挑战

部分失效#P261

Clos 拓扑结构等分带宽#P261

网络分区#P265

同步和异步网络#P269

网络延迟与资源利用率#P271

墙上时钟与单调时钟#P272

时钟置信区间#P278

Fencing 令牌#P285

zk 租期?

拜占庭故障#P286

安全与活性#P290

一致性与共识

可线性化#P305

(原子一致性,强一致性)

严格来说,ZooKeeper和etcd提供可线性化的写操作,默认情况下,由于读操作可以在任何一个副本上执行,因此可能会读到过期值。如果需要,也可以激活线性化读,在etcd中称之为法定票数读取,在ZooKeeper中,则需要读取之前调用sync(),具体请参阅本章后面的“使用全序广播实现线性化存储”。

线性化与 Quorum#P314

CAP理论是否有用?#P317

因果排序,因果一致性#P321

Lamport 时间戳#P325

全域关系广播#P327

原子广播?ZAB?

分布式事务与共识#P330

事务协调者发生故障#P336

Exactly-once 消息处理#P338

启发式决策#P340

事务协调者是应用服务器一部分#P341

共识算法和全序广播#P344

VSR、Raft 和 Zab 都直接采取了全序关系广播,这比重复性的一轮共识只解决一个提议更加高效。而 Paxos 则有对应的优化版本称之为 Multi-Paxos。

Epoch 和 Quorum#P344

目前所讨论的所有共识协议在其内部都使用了某种形式的主节点,虽然主节点并不是固定的。相反,他们都采用了一种弱化的保证:协议定义了一个世代编号(epoch number,对应于 Paxos 中的 ballot number,VSP 中 view number,以及 Raft 中的 term number),并保证在每个世代里,主节点是唯一确定的。

共识算法的局限性#P346

同步算法的性能

需要多数节点才能运行

有一组固定参与投票的节点集

对网络敏感

ZK 成员与协调服务#P346

Zookeeper 的实现参考了了 Google 的 Chubby 服务,也进行了一些优化

  • 线性化的原子操作
  • 操作全序
  • 故障检测
  • 变更通知

解决主节点不可达的方法#P350

系统停止服务

人为介入

共识算法