23.4 向量时钟

一句话

向量时钟给每个节点一个 “计数器向量”,从而能区分 “因果先后” 与 “并发”:比较两个向量就能判定 a → b、b → a 或 a ∥ b;代价是元数据随节点数线性增长(O(N))。

比较规则

关系 判据
a → b(a 因果先于 b) 对所有 i,a[i] ≤ b[i],且存在 i 使 a[i] < b[i]
b → a 对称
并发 a ∥ b 存在 i 使 a[i] > b[i],且存在 j 使 a[j] < b[j]

实测:并发能被识别

p1 有 a、b;b 发消息给 p2 产生 c、d;p3 有 e:

事件 向量 Lamport
a [1,0,0] 1
b [2,0,0] 2
c [2,1,0] 3
d [2,2,0] 4
e [0,0,1] 1
判断 向量时钟 Lamport
b → c(因果) ✅([2,0,0] < [2,1,0]) ✅(2 < 3)
a ∥ e(并发) ✅ 识别为并发 ❌(都是 1)
d ∥ e(并发) ✅ 识别为并发 ❌(4 vs 1 看似有先后)

这就是 “向量时钟能检测冲突” 的原因:两个并发写 → 向量不可比 → 需要合并/仲裁。

func happensBefore(a, b []int) bool {
    less := false
    for i := range a {
        if a[i] > b[i] { return false }
        if a[i] < b[i] { less = true }
    }
    return less
}
func concurrent(a, b []int) bool { return !happensBefore(a,b) && !happensBefore(b,a) }

代价与适用

项 说明
元数据 每事件 O(N);N=100 时每条消息带 100 个整数
动态成员 节点加入/离开要扩缩向量,历史数据难对齐
适用 小规模、强冲突检测(协作编辑、多主复制、离线同步)
不适用 大规模集群、每条消息都要带元数据的场景

反模式

反模式 后果
大集群(N>50)用向量时钟 元数据超过数据本身,带宽与存储爆炸
动态扩缩容不做向量迁移 历史事件无法比较,冲突检测失效
用向量时钟做 “全序”(如选主) 并发事件不可比,无法给出唯一顺序
只存向量不存 “冲突解决策略” 检测到冲突却不知道怎么办
把向量当时钟展示给用户 用户看不懂 [2,1,0]
忽略 “向量裁剪” 长期运行后向量越来越长

三条铁律

🔑 向量时钟回答 “是否并发”;全序请用 Lamport/共识。

🔑 元数据 O(N);大集群要换 HLC 或按分片隔离。

🔑 检测到并发必须配解决策略(LWW/合并/人工)。

自检

Q1 为什么向量时钟能判断并发,而 Lamport 不能?

▸ 答案:因为向量记录了 “每个节点各自知道多少”:并发写会让两个向量在不同分量上互有大小(不可比),而 Lamport 只有一个数,丢失了 “谁在哪个节点上看到什么” 的信息,无法区分 “并发” 与 “同值”。

Q2 两个向量 “不可比” 意味着什么?

▸ 答案:意味着两个事件并发(无因果关系):各自都不知道对方的存在。此时不能自动判定谁赢,必须由业务策略决定(LWW、合并、CRDT、人工仲裁)。

Q3 为什么大集群不适合向量时钟?

▸ 答案:因为每条消息都要带 N 个整数:N=100 时元数据就是 100 个数,远超很多消息本身;而且节点动态变化时向量长度要调整,历史数据无法对齐。大集群通常用 HLC(O(1))或按分片缩小 N。

Q4 向量时钟能替代 “共识算法” 吗?

▸ 答案:不能:共识要解决 “在故障下达成唯一决定”,向量时钟只解决 “判断因果与并发”。它能帮你发现冲突,但不能帮你选出一个所有副本都同意的值——后者需要 quorum/共识。

Q5 动态成员变更时向量时钟怎么办?

▸ 答案:两种做法:固定成员集(不轻易扩缩,扩缩时做一次全量对齐)、带版本的分量映射(节点 id → 分量,变更时保留历史映射)。无论哪种,都要保证 “历史事件仍可比较”,否则冲突检测会出现假阴性。

Q6 向量时钟与 CRDT 的关系?

▸ 答案:CRDT 处理 “并发可合并” 的结构(如计数器、集合),内部常用向量时钟/版本向量来判断 “是否需要合并”;但 CRDT 的合并规则是数学定义的(交换/结合/幂等),向量时钟只负责 “发现并发”。

Q7 实际系统里还有谁在用向量时钟?

▸ 答案:协作编辑(OT/CRDT 的因果检测)、多主数据库(如 Riak 的 dotted version vector)、离线同步(移动端/边缘)。它们共同点是 “节点数有限、冲突必须被检测到”,而不是 “大规模全序”。

关联