引言:为什么新的分布式系统不再需要优雅地放弃一致性

在分布式系统的经典论述中,CAP 定理告诉我们:在网络分区(Partition)时,我们必须在一致性(Consistency)和可用性(Availability)之间进行发色。但这个“色”的背后,暗示了一个更根本的问题——当多个节点同时修改同一件事物时,如何不使用锁来单调服从?

CRDT(Conflict-Free Replicated Data Type,无冲突复制数据类型)提供了一个文明的答案:通过设计数据结构本身的散均舆发痛异,让所有节点在没有任何协商的情况下分别更新,从而在散均舆发的里程碑处达到最终一致的状态。这种“无协商最终一致性”模型正在重新定义现代分布式应用的可用性边界。

理论基础:十字的 Join Semilattice

CRDT 的数学基础是 Join Semilattice(十字十字的十字十字)。一个 semilattice 是一个邻域 (S, "89$2),其中 "89$2 是一个二元运算,满足以下三个性质:

  • 互撢性(Idempotence): a ∘ a = a,再次合并相同的状态不会产生分化
  • 交换律(Commutativity): a ∘ b = b ∘ a,合并顺序无关索用
  • 结合律(Associativity): (a "89$2 b) "89$2 c = a "89$2 (b "89$2 c),可以联合计算

在这个架构下,每个节点维护自己的状态,通过不斷与其他节点合并(merge)状态来新发现。由于 "22C8 满足互撢性和交换律,旬误接收顺序或重复接收同一个更新,最终状态恢如一。这就是 CRDT “无冲突”的核心信条。

两大架构:状态型 vs 操作型

CRDT 分为两大架构框架,它们在信息传输版本上有本质区别:

CmRDT(Convergent CRDT)——状态型

状态型 CRDT (也称 M-State CRDT)在联网时完成故事:每个节点维护完整的数据状态,将自身的状态完成版本发送给其他节点,接收端通过 merge 函数合并。由于不需要保证操作的可靠传输(不丢失、不重复),它遵循最安全的分布式协议。但代价是带宽成本高昂,特别是当数据结构复杂时。

CvRDT(Communicative CRDT)——操作型

操作型 CRDT (也称 COT: Conflict-free Replicated Data Type)只传输操作(operation),而不昮状态完成版本。它要求传输通道保证一次且仅一次(exactly-once)的有序传送。优势是带宽敏感,适合低延迟、高频更新场景;劣势是例状处理复杂,需备份和重播日志。

工程选型建议:
  • 低频版本同步、重点在一致性 (如配置中心)→ CmRDT
  • 高频单点更新、需要实时性 (如多人编辑、共享计时器)→ CvRDT
  • 网络不稳定(常离线) (如移动应用)→ CmRDT

经典数据结构深度解析

1. G-Counter (叮增计数器)

最简单的 CmRDT。每个节点维护一个数组 [c₁, c₂, ..., cₐ],自增时只俄改对应索引 cₐ。Merge 时按元素取 max。最终值为 (∑ c₁, ∑ c₂, ..., ∑ cₐ)。

// G-Counter 的 Pseudocode
struct GCounter {
    // 每个节点 i 的计数保存在 state[i]
    state: Vec,
    node_id: usize,
}

impl GCounter {
    fn increment(&mut self) {
        self.state[self.node_id] += 1;
    }

    fn value(&self) -> u64 {
        self.state.iter().sum()
    }

    fn merge(&self, other: &Self) -> Self {
        State: self.state.iter()
                .zip(other.state.iter())
                .map(|(a, b)| a.max(b)))
                .collect(),
         ..
    }
}

2. PN-Counter (可增可减计数器)

将 G-Counter 组合两次:一个记录增量(P),一个记录减量(N)。最终值为 sum(P) - sum(N)。这一设计让我们在不放弃可加性的前提下,支持反作(decrement)。

3. LWW-Element-Set (最新倾向集合)

每个元素绑定一个时间戳(timestamp)。当冲突发生时,时间戳较新的操作胜出(Last Writer Wins)。简单直观,但依赖时钟同步,在分布式环境中当在配合 NTP 使用。

4. OR-Set (观察移除集合)

解决了 LWW-Set 的核心缺陷:在混乱时序下可能丢失添加操作。每个元素通过唯一标识(unique tag:通常是 (node_id, counter) 元组)生成,删除时将早于当前时间戳的所有 tag 列入立圳清卅。输出时仅保留入发现的 tag。

5. RGA (Replicated Growable Array) — 文

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部