Quorum NWR 模型是什么?如何保证读写一致性?
简化版
Quorum NWR 是多副本系统里的读写投票模型:N 是副本总数,W 是写成功需要确认的副本数,R 是读成功需要读取的副本数。当 R + W > N 时,读集合与某次成功写集合必有交集;若系统使用严格 quorum、可比较版本并正确合并结果,读请求才有条件选出最新已完成写。这个不等式本身并不自动提供线性一致性。
详细版
NWR 三个参数:
| 参数 | 含义 |
|---|---|
| N | 数据副本数量 |
| W | 一次写入至少写成功多少个副本才返回成功 |
| R | 一次读取至少读多少个副本并合并结果 |
关键条件:
- W > N/2:任意两个成功写集合一定相交,但“相交”只提供观察或协调冲突的条件,不会自动串行化并发写。
- R + W > N:读集合和某次成功写集合一定相交;能否据此返回最新值,还取决于 quorum 是否严格、版本比较及并发写处理。
例如 N=3,W=2,R=2,写入成功至少落到 2 个副本;读取也读 2 个副本;两个集合必有交集。读协调者仍需收齐约定的 R 个响应、比较版本,并处理并发版本与故障切换,不能把“有交集”直接等同为线性一致。读到多个版本时,还需要读修复或反熵让副本收敛。
完整版教学
一、为什么需要 Quorum
多副本系统要在性能、可用性和一致性之间平衡。如果每次写都等所有副本成功,写延迟高,而且任意一个副本故障都会影响写可用性。如果只写一个副本就返回,速度快,但其他副本落后,读请求可能读到旧数据。
Quorum 的思路是折中:不要求所有副本都参与,但要求达到一个“法定数量”。只要读写集合有交集,读的时候就有机会接触到最新写入的副本。
二、用 N=3, W=2, R=2 看交集
假设三个副本 A、B、C。一次写成功要求写到任意两个,比如 A、B。一次读要求读任意两个。如果读 A、C,就读到了 A 上的新值;如果读 B、C,也读到了 B 上的新值;如果读 A、B,更不用说。因为任意两个副本集合和另一个两个副本集合必然相交。
这就是 R + W > N 的直觉:两个集合总大小超过全集大小,必然有重叠。若某次写已经完成后读才开始,交集里至少有一个副本见过该写;读协调者还必须等待足够响应并比较版本。若存在并发写、部分写或 sloppy quorum,交集不能单独证明哪个业务版本应当获胜。
三、Quorum 不等于自动强一致
很多面试会挖这个坑。R + W > N 只是保证读集合和写集合有交集,但还需要几个前提:写入版本能正确比较;读请求会合并多个副本结果;旧副本会被修复;并发写冲突能处理。如果系统只是随便读一个副本,或者没有版本机制,Quorum 条件也发挥不了作用。
另外,如果发生并发写,两个写都达到 W,也可能产生兄弟版本。普通整数版本只有在单一权威方分配时才有全序;多主写入常需向量时钟、混合逻辑时钟或业务合并。单纯使用客户端物理时间戳会受时钟偏差影响。
四、R 和 W 怎么调
N=3、W=2、R=2 是常见平衡。写能容忍一个副本失败,读也能容忍一个副本失败,读写都有交集。
如果读多写少,可以设置 W=2、R=1 提高读性能,但 R + W = 3 不大于 N=3,普通读可能读到旧值,需要接受最终一致或做特殊读。若设置 W=1、R=3,协调者确认快、读取慢,而且在异步复制完成前丢失已确认副本可能丢写;这不等同于数据最终只有一个副本。若 W=3、R=1,写入要等待全部三个副本,任一副本不可用都会影响写成功。
还要区分 strict quorum 与 sloppy quorum。Dynamo 风格系统为提高可用性,目标副本不可达时可能把数据暂存到其他节点,再通过 hinted handoff 送回;此时形式上的 R、W 响应未必来自同一组 home replicas,不能只套 R + W > N 就宣称读到最新值。
参数没有绝对正确,取决于读写比例、延迟要求、故障容忍和一致性要求。
| N/W/R | 读写交集 | 主要收益 | 主要边界 |
|---|---|---|---|
| 3/2/2 | 有 | 读写较均衡 | 仍需版本与并发冲突处理 |
| 3/2/1 | 无严格保证 | 单副本读延迟低 | 可能读到旧值 |
| 3/1/3 | 有 | 写确认快 | 已确认副本丢失前可能尚未复制 |
| 3/3/1 | 有 | 全副本确认后单读快 | 任一副本不可用会阻断写 |
五、读修复与反熵
Quorum 系统常配合读修复:读请求发现 A 是新版本、C 是旧版本,就把新版本写回 C。还有反熵机制:后台定期比较副本差异并修复。这样即使写入时某个副本落后,系统也能逐渐收敛。
没有读修复和反熵,落后副本可能长期落后,最终一致的“最终”就没有保障。
六、Quorum 和共识算法的区别
Quorum NWR 是副本读写投票模型,常见于 Dynamo 风格系统,用于在可用性和一致性间调参。Raft/Paxos 这类共识算法也使用多数派,但目标更强:它们要让多个节点对同一条日志顺序达成一致,通常提供更强的一致性语义。不要把 NWR 简单等同于 Raft。
七、常见误区与追问
N=5,W=3,R=3
最坏情况下读写交集下界 = R + W - N = 1 个副本
但若两个客户端并发写出不可比较版本 vA、vB,
读到交集只能发现冲突,仍需业务合并,不能凭集合公式选赢家。
易错点:
R + W > N是交集证明,不是完整的一致性协议;成员集合、版本规则和并发写语义缺一不可。
- 误区:R+W>N 就绝对强一致。 还要有版本比较、冲突解决和正确的读修复,否则只保证集合有交集。
- 误区:W 越大越好。 W 大会降低写可用性和写延迟,需按业务取舍。
- 误区:NWR 只用于数据库。 副本读写、对象存储、分布式 KV 都可能用类似思想。
- 追问:N=3 W=1 R=1 是什么特点? 可用性和低延迟高,但可能读到旧值。
- 追问:如何提升读一致性? 增大 R、读主、读修复、版本号比较。
- 追问:写冲突怎么办? 用版本向量、时间戳、业务合并或最后写入胜出,但要知道代价。
八、加强记忆
NWR 记住三个数:N 副本总数,W 写确认数,R 读响应数。R + W > N 证明严格副本集合必有交集,W > N/2 证明两个写集合也会相交;两者都只是集合条件,不是线性一致性的完整证明。还要追问副本集合是否固定、版本能否比较、并发写如何合并、部分写如何清理,再讨论读写延迟与故障可用性的取舍。