I3.11.3merge granularity tradeoff设计
合并粒度越细,自动合并成功率越高但实现与展示复杂度也越高
别名: 合并粒度 · 越细越复杂 · grain vs complexity · 字符级
概念解释
把冲突单位从整份文档收到记录、字段、列表元素、再收到字符,自动合并成功率会上升:两边改动落在同一单位里的机会变小。同一条路上,实现要维护的身份、变换、界面要画的差异层数也上升。这是一条要显式选择的权衡,不是「越细越好」的进步叙事。
成功率是「不用人插手就收敛的比例」。复杂度是协议、存储、以及人看懂差异的成本。两边都要进账。
机制
细粒度把地址空间切开,可交换写入变多,这是成功率的来源。切开之后,每个地址都要有稳定 ID:字段名、列表项 ID、段落 ID、直到字符在 CRDT 里的位点。ID 的生命周期(插入、删除、移动、撤销)构成一套自己的状态机,bug 从「偶尔丢一段」变成「偶尔丢一个字符、错位一个列表项」。测试空间随地址数目组合爆炸。
展示跟着粒度走。记录级冲突是一张卡变红;字段级是几个格子;字符级是一行里的红绿交错。人的对比在字符级会失去句子,只看见碎片。于是产品常在存储上用细粒度、在界面上聚合成句或段——聚合层又是一笔复杂度,聚合错了会把已自动并的字符重新显示成冲突,或把该冲突的字藏进一段「已合并」里。
边界
协作人数少、离线短、数据高度结构化,中等粒度(字段)往往够用,再往下投入不回本。实时共同编辑散文的产品,字符级几乎是门票,复杂度被编辑器内核吃掉,界面仍应按句或按段呈现冲突。移动端小屏画不了字符级差异,即使存储是细的,展示也必须聚合。监管要求可解释的合并(谁的哪一笔进了最终版)时,过细的粒度会让解释变成字符审计,对人不可用,需要一层业务语义的说明。性能上也有拐点:每个按键都同步一个位点,电量和流量会先于成功率把产品拖死。
怎么落地
- 先为每类对象选一个默认粒度:任务卡用字段,正文用段落或句,标签用元素。写进实现与界面,两边同一张表。
- 存储可以比界面更细,但界面聚合规则要可测:自动并的单位在界面上不得再显示为冲突。
- 把成功率指标和「人看懂一次冲突的时间」一起看。只优化前者会把粒度推到无法阅读。
- 验证:同一组并发编辑,分别按记录、字段、段落三种粒度各跑一遍。记下自动并比例、代码路径数、以及被试指出「哪边改了什么」的时间。若更细一档的成功率几乎不涨、指出时间明显变长,粒度已经过线。不要用 LWW 的「总是有一份结果」来冒充这一档的成功率。