故事

光绪年间,直隶有十三家镖局,各自占着一条道。单家走单镖,十趟里总要丢两三趟——土匪不抢你抢谁。后来总镖头们坐下来喝了一顿酒,定了个规矩:任何一趟镖,至少三家同走,货分三份,各保一份;到了目的地,收货人要见到至少两份,才认这趟镖算数

规矩写在红纸上,叫"十三张投名状",贴在各家的堂口。

有人问:三家走,两份到,这数怎么定的?总镖头说:十三家镖局,最坏的情况是有六家被土匪买通或打残,剩下七家还清白。三家同走,土匪最多吃掉其中一家,还剩两份;收货人见两份,就知道"至少有一家清白的镖局把货送到了"。要是只派两家,土匪吃掉一家,剩一份,收货人没法判断"是另一家被吃了"还是"那一家本身就不清白";要是收货人只认一份,土匪自己凑一份假的送来,他也分不出来。

这规矩的根子在一个不等式上:派出的镖局数(W)加上收货人要见的份数(R),得比总数(N)大。三家走、两份到,3+2=5,比任何可能勾结的土匪联盟(6家)都大,所以清白的镖局和收货人之间必有交集——至少有一家镖局,既参与了护送,又被收货人信任。

有个新开的第十四家镖局想入伙,总镖头们改规矩:十四家时,W 和 R 得调到多少?有人拍脑袋说"四家走、三份到",4+3=7,刚好比半数大。老账房摇头:不行,土匪联盟要是膨胀到八家,7 不大于 8。最后定成"四家走、四份到",4+4=8,比 14 的一半大,才保住那个"清白交集"不变。

后来有个跑洋货的商人嫌慢,说"我急,派两家、收两份行不行?"老账房说行啊,但 N 得降到 3——三家镖局的小圈子,2+2=4>3,规矩还立得住。可商人又不干了:三家圈子太小,土匪买通两家就过半。这就是速度和安全之间的硬约束:你要快,圈子就得小;圈子小,抗勾结的能力就弱。没有两边都占的便宜。

最精妙的用法是"读写分治"。有些货是字画瓷器,走一趟不容易,但查验简单——收货人看一眼封条完整就行,这种货 R 可以小,W 保持大,叫"重护送、轻验收"。有些货是金银细软,护送不难,但怕调包,收货人得逐件核对,这种货 R 要大,W 可以小,叫"轻护送、重验收"。老账房管这叫"货性定数":不是规矩死板,是规矩跟着货走,但那条 3+2>5 的底线不能破。

有一家镖局叫"顺风腿",总镖头贪心,想独吞一条线。他耍了个花招:跟土匪串通好,每次三家同走,顺风腿故意落后,让土匪吃掉另外两家,自己"独存"的那份送到收货人手里。收货人见了一份,按规矩该拒收——可顺风腿私下塞钱,让收货人睁一只眼闭一只眼。规矩从"收货人"这端漏了。

老账房发现后,没罚顺风腿,改了一条规矩:收货人认货之前,得随机抽一家参与护送的镖局,问它"你保的那份封条上写的什么字"。顺风腿那份封条上写的字,和另外两家被吃掉的那份该一样——可顺风腿根本没见到另外两家那份,答不上来。这就是见证校验:收货人不光数份数,还要验证"送到的这份和没送到的那些份之间,有没有真实的关联"。

概念解析

Quorum 交集是分布式系统里多数派机制的几何基础。W 个节点写入、R 个节点读取,R+W>N 保证读写两个集合必有重叠——至少有一个节点既参与了写、又被读采样到,从而确保读到的是最新写入的数据,而非过时的副本。

Paxos 的 Quorum。 提案阶段(Prepare)和提交阶段(Accept)各自需要多数派确认,两个多数派的交集至少有一个节点。这个节点见证了"前一个提案已经被承诺",从而阻止冲突提案的交叉通过——和老账房的"见证校验"是同构的。

Raft 的 Quorum。 日志复制和领导者选举都依赖半数以上,新旧配置联合共识时([✓#47 换班令]),双多数的设计把交集从"同一配置内"扩展到"跨配置之间",数学本质仍是 R+W>N 的变体。

Dynamo 的 Quorum。 亚马逊的分布式键值存储把读写 Quorum 做成可调参数(R, W, N),允许"货性定数"——读多写少的负载调大 R 小 W,写多读少的负载调大 W 小 R。但 R+W>N 的底线保证最终一致性向强一致性滑动时有数学支撑。

与 2PC 的区别。 2PC([✓#20 悬心])要求所有参与者确认,是"全写全读";Quorum 只要求重叠的多数,是"写一部分、读一部分,但两部分必相交"。前者追求绝对一致,代价是阻塞;后者接受概率性的新鲜度保证,换取可用性和分区容忍。

几何直觉的本质。 N 个节点画成一个圆,W 个写入节点和 R 个读取节点是两个弧段。R+W>N 意味着两段弧必重叠——不是"大概率重叠",是拓扑上的必然重叠。这个不等式把分布式系统的一致性保证从"相信多数人是诚实的"转化为"就算不知道谁是诚实的,诚实者和见证者之间必有交集"。