知识卡片
无主复制靠读写法定人数在故障中维持可用与新鲜度
内容
无主复制里没有故障切换概念:客户端把写请求并行发给所有n个副本,只要有w个副本 确认就认为写入成功(少数不可用副本被简单忽略);不可用节点重新上线后可能返回陈旧 值,因此读请求也并行发给多个节点,用版本号识别新旧,客户端并行读r个节点。让离线 节点补上错过的写入靠两种机制:读修复(客户端并行读时发现某副本返回陈旧值,顺手把 新值写回去,适合频繁被读的数据)和反熵过程(后台持续比对副本间差异、把缺失数据 从一个副本复制到另一个,不保证顺序也可能有明显延迟,不是所有系统都实现,没有反熵 时很少被读的值可能长期丢失新数据)。核心的数学约束是法定人数条件w+r>n:只要每次 写入至少被w个副本确认,就意味着最多有n-w个副本可能是陈旧的;只要每次读取至少查 r个副本,w+r>n就保证读到的r个副本里至少有一个拥有最新数据——这就是quorum读写。 常见配置是让n为奇数、w=r=(n+1)/2向上取整,比如n=3,w=2,r=2能容忍1个节点不可用, n=5,w=3,r=3能容忍2个节点不可用。w、r也可以调小(w+r≤n,不满足法定人数条件), 换来更低延迟和更高可用性,代价是更容易读到陈旧数据;只有当可达副本数低于w或r时, 数据库才对写或读整体不可用。这套机制是无主复制在没有主库、没有故障切换概念的情况 下,依然能对不可用节点保持容错的核心手段。
结构图:
flowchart TD
A[客户端写请求] --> B[并行发给全部n个副本]
B --> C[至少w个确认即视为写入成功]
D[客户端读请求] --> E[并行查r个副本]
E --> F[按版本号取最新值]
C -.w+r大于n: 读写节点集合必有重叠.-> F
G[节点离线错过写入] --> H[读修复: 读到陈旧值时顺手写回]
G --> I[反熵过程: 后台持续同步差异]
参考来源
- 位置:《数据密集型应用系统设计》第五章《复制》"当节点故障时写入数据库""读修复
和反熵""读写的法定人数"(源文件:_epub-src/ch5_split_004.html)
- 结论依据:原文说明无主复制下写入并行发给n个副本、w个确认即成功,读取并行查
r个副本、按版本号取新值,用读修复和反熵机制补齐离线节点错过的数据,并给出
法定人数条件w+r>n及常见配置(n=3,w=2,r=2容忍1节点故障),直接支撑本卡片的结构
梳理。
- 原始内容:客户端并行发送写入到所有三个副本……假设三个副本中的两个承认写入是
足够的……读请求也被并行地发送到多个节点……如果我们知道,每个成功的写操作意味着
在三个副本中至少有两个出现……只要w+r>n,我们期望在读取时获得最新的值。