首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >CRDTs原理:像拼乐高一样合并分布式数据

CRDTs原理:像拼乐高一样合并分布式数据

作者头像
用户9773796
发布2026-06-23 20:48:45
发布2026-06-23 20:48:45
220
举报

当三份购物车数据“吵架”时,谁来当裁判?

想象一个场景:你在手机上往购物车加了“牛奶”,同事在电脑上添加了“面包”,朋友用平板加了“鸡蛋”——但因为网络延迟,这三份操作被存在了不同服务器上。当网络恢复时,系统该怎么合并这些数据?总不能让你看到三个不一样的购物车吧?

这就是分布式系统的经典难题:如何让“各执一词”的数据自动达成共识。强一致性系统会让所有操作排队执行(像交通信号灯),但弱一致性系统需要更灵活的方案。而CRDTs(冲突无关复制数据类型)就像一位“超级和事佬”——它设计了一种特殊的数据结构,不管操作顺序多乱,最终总能合并出相同结果。

拼乐高的三大秘诀:交换律、结合律、幂等律

CRDTs能“化冲突为和谐”,全靠数学赋予的三大“超能力”。这些听起来高深的术语,其实就藏在你每天玩的乐高积木里:

1. 交换律:先放哪块积木都一样

把乐高积木A和B拼在一起,先放A再放B,和先放B再放A,结果完全相同——这就是交换律(a+b = b+a) 。CRDTs的操作也如此,比如两个用户同时给商品点赞,不管谁先谁后,最终点赞数都是2。

生活例子:微信群里发红包,你抢了10元,我抢了5元,不管系统先处理你的还是我的请求,总金额都是15元。

2. 结合律:怎么分组拼都不影响结果

把三块积木A、B、C拼起来,(A+B)+C和A+(B+C)的结果一样——这是结合律(a+(b+c) = (a+b)+c) 。CRDTs支持多节点数据分片合并,比如北京、上海、广州的服务器分别处理部分订单,最终合并后总数不变。

技术实例:Google Docs的实时协作,多个用户同时编辑文档不同段落,系统会先按用户分组合并,再汇总成最终版本,过程中不会出现“段落消失”的bug。

3. 幂等律:重复拼同一块积木不会变多

同一块乐高积木重复拼10次,结果还是一块——这是幂等律(a+a = a) 。CRDTs不怕操作重复,比如用户手抖点了10次“添加购物车”,系统最终只会存一份商品。

真实场景:支付宝转账时,若网络波动导致请求重复发送,CRDTs会自动忽略重复操作,避免你多转钱。

常见CRDTs:给数据“定制性格”

就像乐高有不同形状的积木,CRDTs也针对不同场景设计了“专用数据类型”。以下是最常用的几种:

1. G-Counter(增长计数器):只能加不能减的“点赞数”

特点:像微信公众号的点赞数,只能增加,不能减少。每个节点记录自己的增量,合并时取总和。例子:3个服务器分别记录点赞数为2、3、5,合并后总点赞数=2+3+5=10。适用场景:视频播放量、微博转发数等“只增不减”的数据。

2. G-Set(增长集合):只能添加不能删除的“标签墙”

特点:像知乎回答的标签,添加后就不能删除。合并时取所有节点的标签 union(并集)。例子:A节点添加“科技”“互联网”,B节点添加“分布式”,合并后标签为{科技, 互联网, 分布式}。局限:无法删除错误标签,适合“一旦添加就永久有效”的场景。

3. 2P-Set(两阶段集合):能删但有“后悔药”的“黑名单”

特点:分“添加集”和“删除集”,删除时需先在添加集存在。合并时,最终集合 = 添加集 - 删除集。例子:A节点添加用户“小明”,B节点删除“小明”,合并后“小明”被移除;若B节点删除“小红”(从未添加),则删除无效。企业案例:Discord的用户禁言功能,确保只有已加入服务器的用户才能被禁言。

4. LWW-Register(最后写入者获胜寄存器):用时间戳“定胜负”的“昵称设置”

特点:像游戏角色昵称,多个用户同时修改时,时间戳最新的修改会覆盖旧的。例子:用户在手机(时间戳10:00)和电脑(时间戳10:01)修改昵称,合并后取电脑端的新昵称。风险:若设备时间不同步,可能出现“旧数据覆盖新数据”,需搭配NTP时间同步使用。

为什么微信不直接用CRDTs做聊天记录?

CRDTs虽强大,但并非万能药。它的“超能力”建立在数据类型受限存储成本高的基础上:

  • 不适合“强事务”场景:转账、库存扣减等需要“原子性”的操作(要么全成,要么全败),CRDTs无法保证,因为它允许暂时不一致。
  • 存储开销大:每个操作都要记录元数据(如时间戳、节点ID),G-Counter的向量时钟会随节点数增长,可能占用大量内存。
  • 部分类型功能有限:比如2P-Set删除后无法重新添加,LWW-Register可能丢失并发修改(除非返回所有版本给用户选择)。

因此,CRDTs更适合实时协作工具(如Notion、Figma)分布式缓存(如Redis Cluster)物联网传感器数据(只增不减的读数) 等场景。而微信聊天记录需要保证“消息不丢且有序”,目前更多用“最终一致性+本地缓存”方案。

从CRDTs看分布式系统的终极哲学

CRDTs的本质,是用数学确定性解决物理不确定性。当网络延迟、节点故障成为常态,我们不再强求“实时一致”,而是设计“不管中间多乱,最终一定对”的规则——就像拼乐高时,哪怕孩子先拼腿再拼头,最终仍能组成完整模型。

思考问题:如果设计一个多人实时编辑的在线文档系统,你会选择CRDTs还是传统的强一致性协议(如Paxos)?为什么?

下一篇,我们将揭开最后一块拼图:CALM定理如何让代码像“朋友圈动态”一样,不用严格排序也能最终一致?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 专业造轮子 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 当三份购物车数据“吵架”时,谁来当裁判?
  • 拼乐高的三大秘诀:交换律、结合律、幂等律
    • 1. 交换律:先放哪块积木都一样
    • 2. 结合律:怎么分组拼都不影响结果
    • 3. 幂等律:重复拼同一块积木不会变多
  • 常见CRDTs:给数据“定制性格”
    • 1. G-Counter(增长计数器):只能加不能减的“点赞数”
    • 2. G-Set(增长集合):只能添加不能删除的“标签墙”
    • 3. 2P-Set(两阶段集合):能删但有“后悔药”的“黑名单”
    • 4. LWW-Register(最后写入者获胜寄存器):用时间戳“定胜负”的“昵称设置”
  • 为什么微信不直接用CRDTs做聊天记录?
  • 从CRDTs看分布式系统的终极哲学
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档