在西域的两座哨所之间,隔着三天的沙漠——东哨所守着商路入口,西哨所守着商路出口。两边共同的任务,是在一张巨大的沙盘地图上,标出这条商路沿线新发现的每一口水井,好让往来的商队知道该在哪儿补水。
沙漠里没有电报,两座哨所之间唯一的联络方式,是骆驼信使。信使带着一张写着”某处发现水井”的羊皮纸,穿越沙漠,把消息送到对面。可这沙漠残酷得很:信使有时会在沙暴里迷路,绕远路,消息比预期晚了五天才到;有时同一口井的消息,因为两拨商队都上报了,会被两个信使分别送出,对方哨所收到两份一模一样的羊皮纸;还有时几个信使前后脚出发,却因为沙丘绕行路线不同,抵达顺序和出发顺序完全颠倒——后发的信使反而先到。
按理说,这么混乱的信使系统,两座哨所的地图迟早会对不上。可两位哨长很早就立下一条死规矩,让这套系统怎么折腾都出不了岔子。
规矩第一条:地图上的水井标记只能添,不能撤。哪怕后来发现某口井其实已经干涸,也绝不把标记从沙盘上抠掉——顶多在旁边另加一个”已干涸”的标记,同样只加不减。
规矩第二条:同一口井收到几份羊皮纸,结果跟收到一份一模一样。哨兵往沙盘上插的是井的坐标,不是”插旗”这个动作本身——同一个坐标,插一次和插十次,沙盘上看起来毫无分别。
规矩第三条:不管信使抵达的顺序如何、消息积压多久才一起补上,只要最终两边收到的羊皮纸内容凑齐了,两张沙盘就必然长成一模一样。哨长们试过把某一批消息故意打乱顺序念给誊写员听、也试过把某些消息重复念两遍——誊写完的沙盘,每次都和别人按正常顺序誊写出来的一样。
有一年沙暴格外凶,足足三个月两座哨所音信断绝,信使全被扣在半路。三个月后信使们几乎同一天涌进两座哨所,一股脑把积压的羊皮纸全倒了出来——有的重复、有的顺序颠倒得离谱。两位哨长谁都没派人去对方那边核对”你到底收到了什么、顺序是什么”,他们只是照老规矩,把所有羊皮纸不管三七二十一地一张张誊到沙盘上。等尘埃落定,两张沙盘并排一比——分毫不差,连一口井的位置都没差。
——到这儿你大概已经认出来了:这两座哨所维护地图的规矩,讲的其实是 CRDT(Conflict-free Replicated Data Type,无冲突可复制数据类型)如何在没有协调者、没有顺序保证、消息可能丢失重复的情况下,依然保证 eventual consistency(最终一致性)。
概念解释 CRDT 是一类专门设计出来的数据结构,让多个副本可以完全独立地各自更新,不需要事先协商、不需要锁、不需要像 quorum 那样等待多数派确认,最后只靠一个数学上很讲究的”合并函数”把各副本拼到一起,保证结果永远收敛到同一个状态。这份保证来自三条性质:合并操作必须是 commutative(谁先合并、谁后合并顺序不影响结果,对应故事里”信使到达顺序颠倒也没关系”)、associative(先两两合并再合起来,还是一次性全合,结果一样,对应”消息积压三个月一起补上”)、idempotent(同一条更新重复应用多次,效果跟应用一次相同,对应”同一口井收到两份羊皮纸不会出岔子”)。凡是满足这三条的合并规则,都能保证:只要两个副本最终看到了同一组更新(不论顺序、不论重复),必然收敛到同一状态——这正是 CRDT 意义上的 strong eventual consistency,比一般意义上的”最终一致性”更强,因为它不依赖任何冲突解决的额外协商,合并本身就自动无冲突。故事里”只增不减、用另一个标记表示删除”的手法,对应现实中最常见的一类 CRDT——G-Set / OR-Set(只增集合 / 支持删除的观察-移除集合,用墓碑 tombstone 代替真删除)。这也是为什么 Redis 的 CRDT 模式、Riak、Automerge/Yjs 这类协同编辑引擎、以及许多 multi-region active-active 数据库,都用 CRDT 来实现”多个地区可以各自离线写入,过后自动合并,不需要谁等谁”。
隐喻对应表
- 两座哨所各自维护的沙盘地图 → 两个副本(replica)各自保存的数据状态
- 骆驼信使传递的羊皮纸 → 副本之间同步的更新消息(update / operation)
- 信使可能绕路迟到 → 消息延迟到达(无需保证及时性)
- 两份一模一样的羊皮纸 → 重复消息(duplicate delivery)
- 信使抵达顺序和出发顺序颠倒 → 消息乱序到达(out-of-order delivery)
- “只加不撤,干涸就另加标记” → grow-only 语义 + tombstone 表示删除(对应 OR-Set 一类 CRDT)
- “重复插旗和插一次看起来一样” → idempotent(合并操作的幂等性)
- “打乱顺序念、重复念,结果都一样” → commutative + associative(合并操作与顺序、分组方式无关)
- 三个月后一次性把积压消息全部誊写、两张沙盘依然分毫不差 → strong eventual consistency:只要收到同一组更新,无论顺序/重复,必然收敛到相同状态
- 全程没有派人去对方那边协商核对 → CRDT 无需协调者、无需锁、无需 quorum,合并本身自动无冲突
In the western desert, two outposts stood three days’ journey apart — the East Post guarding the entrance to the trade road, the West Post guarding its exit. Together they shared one job: mark every newly discovered well along the road on a great sand-table map, so caravans would know where to refill their water.
There was no telegraph in the desert. The only link between the two outposts was camel messengers, each carrying a scrap of parchment reading “a well was found at such-and-such a spot.” The desert was merciless to these messengers: sometimes a sandstorm sent one wandering off course, and a message arrived five days late. Sometimes the same well got reported by two different caravans, so two messengers were dispatched independently, and the receiving outpost ended up with two identical parchments for the same well. And sometimes several messengers left one after another, only to arrive in an order completely scrambled from the order they’d departed — a later starter beating an earlier one home.
By all rights, a courier system this chaotic should eventually have left the two outposts’ maps hopelessly out of sync. But the two post commanders had, long ago, agreed on a set of rules strict enough that no amount of chaos could break them.
Rule one: marks on the map can only be added, never removed. Even when a well was later found to have dried up, no one scratched its mark off the sand table — at most, a second mark went up beside it reading “dried up,” itself only ever added, never removed.
Rule two: receiving several parchments about the same well produces exactly the same result as receiving one. What a sentry planted on the sand table was the well’s coordinates — not the act of planting itself. Whether that coordinate got marked once or ten times, the sand table looked identical either way.
Rule three: no matter what order the messengers arrived in, no matter how long messages piled up before being caught up on all at once, as long as both sides eventually received the same set of parchments, the two sand tables were guaranteed to end up identical. The commanders tested this deliberately — reading a batch of messages to the scribe in scrambled order, reading some twice — and the sand table that came out the other end was always the same as one transcribed in ordinary order.
One year a sandstorm season was especially brutal. The two outposts lost contact entirely for three months, with messengers stranded somewhere in between. When the storms finally broke, the messengers arrived at both outposts nearly on the same day, dumping the backlog all at once — duplicates, wild reorderings, all of it. Neither commander sent anyone to the other post to compare notes on what exactly had been received or in what order. They simply transcribed every parchment onto the sand table, rule in hand, no questions asked. When the dust settled and the two maps were laid side by side, they matched — down to the position of every last well.
——By now you’ve probably recognized it: the rules these two outposts used to maintain their map are describing CRDTs (Conflict-free Replicated Data Types) — and how they guarantee eventual consistency even with no coordinator, no ordering guarantees, and messages that can be lost, duplicated, or delivered out of order.
What this concept is A CRDT is a class of data structure purpose-built so that multiple replicas can be updated completely independently — no advance negotiation, no locks, no waiting for a quorum’s majority to confirm — and still be guaranteed to converge to the same state, purely through a mathematically well-behaved merge function. That guarantee rests on three properties: the merge operation must be commutative (the order in which updates are merged doesn’t affect the result — the story’s messengers arriving in scrambled order), associative (merging two-at-a-time versus merging everything in one batch gives the same outcome — the three months of backlog caught up all at once), and idempotent (applying the same update multiple times has the same effect as applying it once — receiving two parchments about the same well causing no trouble). Any merge rule satisfying these three properties guarantees that as long as two replicas eventually see the same set of updates — regardless of order or duplication — they converge to the same state. This is strong eventual consistency, a stronger guarantee than the usual sense of “eventual consistency,” because it requires no additional conflict-resolution negotiation at all — the merge itself is automatically conflict-free. The story’s technique of “only ever adding, and marking deletion with another addition” corresponds to one of the most common real-world CRDT families — the G-Set / OR-Set (grow-only set / observed-remove set, which uses tombstones instead of true deletion). This is exactly why Redis’s CRDT-based replication mode, Riak, collaborative-editing engines like Automerge and Yjs, and many multi-region active-active databases all rely on CRDTs: so that multiple regions can write independently, even offline, and merge automatically afterward — with nobody having to wait on anybody else.
Metaphor mapping
- The sand-table map each outpost maintains → each replica’s local data state
- The parchments carried by camel messengers → update/operation messages synced between replicas
- A messenger wandering off course → delayed message delivery (no timeliness guarantee needed)
- Two identical parchments about the same well → duplicate message delivery
- Messengers arriving in an order scrambled from their departure order → out-of-order delivery
- “Only add, mark drying-up with another addition” → grow-only semantics plus tombstones for deletion (as in OR-Set-style CRDTs)
- “Planting the same flag twice looks the same as once” → idempotence of the merge operation
- “Reading messages out of order or twice still gives the same result” → commutativity and associativity of the merge operation
- Three months of backlog transcribed all at once, and the two sand tables still matched exactly → strong eventual consistency: given the same set of updates, regardless of order or duplication, convergence is guaranteed
- No one from either post went to compare notes with the other → CRDTs need no coordinator, no locks, no quorum — the merge itself is inherently conflict-free