第 14 章 —— 收敛边界与已经发生的业务响应
本章目标: 本章完成后,开发者能够画出分区窗口中的局部成功与恢复后收敛,并判断哪些业务承诺不能交给最终一致状态处理。
学习目标
- 区分响应语义、当前可见状态和最终收敛状态。
- 解释 autonomous 与 quorum 协调在分区中的取舍。
- 识别 repair 无法撤销的外部副作用。
- 为 route hint、Lease、计数器和订单事实划定一致性边界。
前置条件
- 已完成第 6 章并发冲突与第 7 章 Lease。
- 已理解在线 delta、repair 和 ChangeStream 漏失。
- 能把「最后收敛为一个值」与「过程中只成功一次」分开。
案例进度
网络把 node-a 与 node-b 隔开。两端都更新
route hint,并分别向调用方返回 OK。恢复后 resolver 选出一个
winner。运维看到副本一致了,却发现两个调用方都已经基于各自的 OK
执行后续动作。
收敛不等于撤销过去
在 T2,两个局部成功都是真实发生过的响应。T3 的 delta/repair 可以让 T4 的当前可见值收敛,却不能让客户端忘记其中一个 OK,更不能自动补偿已经触发的邮件、扣款、发货或外部写入。
因此要分别写三份合同:
| 合同 | 要回答的问题 | DSM 能否独立保证 |
|---|---|---|
| 本地操作合同 | put/acquire/increment 在何时返回 |
能说明本地集合结果 |
| 收敛合同 | 分区恢复后副本如何得到兼容状态 | Register/Lease/CRDT 各自负责 |
| 业务承诺合同 | 已返回的成功能否重试、撤销、对账 | 需要事务、幂等、fencing 或补偿 |
三类集合在分区中的不同表现
Register:两个 OK,一个最终 winner
Register 允许两个节点各自接受候选值,恢复后用元数据和 resolver 选择一个当前值。它适合 route hint,因为失败的候选可以被覆盖且权威健康源可重新发布;它不适合把两个订单状态写入后假设 loser 从未发生。
Lease:availability 与独占性的明确取舍
AUTONOMOUS 模式可能在分区两侧产生 holder,依赖外部 fencing token 拒绝旧 owner。QUORUM 模式在成员不稳定或多数不可见时拒绝 acquire,从而用可用性换取更强的发放约束。无论哪种模式,下游都需要校验 token;内存中的 holder 判断不能约束已经离线的旧进程。
CRDT:合并安全不等于业务合法
请求计数可在两端本地增加,恢复后合并贡献。这个性质适合指标,却不能证明库存扣减不会超卖:数学上可合并的两个 decrement,不一定满足库存业务下限和审计要求。
一张拒绝清单
以下状态不能因为最终会收敛就直接放入 DSM 作为权威事实:
- 订单状态迁移和不可逆审批;
- 库存扣减与额度消耗;
- 支付、退款与账务分录;
- 需要完整、不可遗漏历史的业务事件;
- 需要给调用方单一确定结果的跨资源事务。
DSM 可以缓存或协调这些系统周围的可重建状态,但权威结果仍由事务事实源、幂等协议和审计系统承担。
反例与故障注入
ChaosIntegrationTest 同时展示两种 Lease 选择:
- autonomous Lease 在分区中可能出现 dual holders;
- quorum Lease 在失去多数时拒绝 acquire,恢复并重新稳定后才允许。
这个对照没有宣布一种模式普遍优于另一种。它迫使业务 Owner 回答:暂停工作和短暂双执行,哪个风险更可接受?外部副作用是否有 fencing/幂等保护?
实验
cd submodule/dsm
mvn -q -pl dsm-integration-test -am \
-Dtest=ChaosIntegrationTest \
-Dsurefire.failIfNoSpecifiedTests=false test再审阅 partition-contract.json。每个状态都需要写
localResponse、partitionBehavior、healedState
与
externalGuard;任何一栏写「由最终一致保证」都不合格。
实验验收卡
| 字段 | 内容 |
|---|---|
| 运行命令 | 上述 Maven chaos
测试;node --test tests/chapter-assets.test.mjs |
| 输入或故障 | 网络分区、双端本地操作、网络恢复与 anti-entropy |
| 可观察结果 | Register/repair 最终收敛;autonomous Lease 可双 holder;quorum Lease fail closed |
| 证据等级 | E3:多节点 chaos 行为测试 |
| 本实验未证明 | 业务副作用已经被补偿、跨资源事务成立、生产网络参数合适 |
回顾
- 最终一个 winner 不会撤销分区期间已经返回的两个 OK。
- 集合语义解决当前协同状态,不替代业务承诺协议。
- Lease 模式是在可用性与发放约束之间做显式选择。
- 订单、库存、支付与事件历史继续留在各自权威系统中。
下一步
第四篇开始把这些边界带进真实工程。第 15 章先建立领域端口,让业务代码说「发布路由、领取分片、记录请求」,而不是散落 DSM API。