ARC 6证明边界并完成毕业项目第 23–26 章

第 25 章 —— 识别不适合 DSM 的状态

本章目标: 本章完成后,开发者能够从业务不变量、失败后果和证据要求反选技术,不因低延迟、分布式或「共享」三个词默认选择 DSM。

学习目标

  1. 先判断状态是否可修复,再讨论集合类型。
  2. 区分事实源、缓存、历史日志、共识协调与 DSM。
  3. 为采用或拒绝 DSM 写出可审查理由。
  4. 识别双写、无限状态和不可观测修复三类反模式。

前置条件

  • 已完成三类集合、分区边界、容量和 federation。
  • 能写出状态丢失、重复、乱序和分歧的业务后果。
  • 愿意把「不用 DSM」视为成功的设计结论。

案例进度

履约团队重新评审订单、库存扣减、route hint、shard owner、request counter 和审计事件。评审目标是确认每种状态的正确责任边界,不以扩大 DSM 覆盖范围为成果。

先反选,再选集合

DSM 反选决策树

需求 首选责任 为什么不是 DSM 的主责任
订单、余额、库存扣减等权威事实 事务数据库或事实服务 已确认事务不能被最终收敛重写
完整、可重放的发生历史 事件日志或流平台 DSM 以当前协同状态为中心,不承诺完整历史
跨节点线性化配置、选主或强 CAS 共识协调服务 DSM 分区下可能允许局部成功
只需低延迟读且可从事实源重建 缓存 不需要引入领域合并、repair 与协议身份
小规模、可修复、领域语义明确的协同状态 DSM 候选 可用 Register、Lease、CRDT 表达不变量

「候选」还不是批准。仍需回答状态规模、TTL/清理、schema 演进、失败可观测性、repair 成本、安全、容量和团队运维能力。

三个应当直接拒绝的信号

  1. 把 DSM 和数据库都当 writer:没有单一权威和补偿协议的双写,只会制造另一层分歧。
  2. 状态无界增长:把完整订单历史、日志或分析明细塞进内存集合,生命周期与容量不可控。
  3. 无法解释失败窗口:只说 eventual consistency,却说不出两个 OK、旧 token、丢 delta 或慢消费者的业务处理。

贯穿案例的最终边界

  • route-hints:Register 候选;事实来源仍是健康检查/服务管理系统。
  • shard-owners:Lease 候选;外部写入需要校验 fencing token。
  • request-counter:PN-Counter 候选;用于可合并观测,不用于财务结算。
  • 订单与库存:拒绝 DSM 作为事实源。
  • 审计事件:进入不可变历史系统,不能只依赖 ChangeStream。

反例与故障注入

  • 把库存余额改为 Register,并制造分区双写;说明收敛后的 winner 仍会丢失业务扣减。
  • 把 ChangeStream 当审计日志,触发 overflow;指出观察事件可丢与历史完整性的冲突。
  • 把 CRDT counter 当账单金额,说明重复来源、撤销和法律记录无法由局部 merge 自动解决。
  • 为纯缓存数据增加自定义 resolver,比较它与从事实源重建的复杂度。

实验

npm test -- --test-name-pattern="phase 6 assets"

在 technology-selection-review.json 中对八类状态逐项写出 invariant、failure cost、source of truth、选择与反证条件。

实验验收卡

字段 内容
运行命令 书籍静态决策资产测试
输入或故障 事实、历史、强协调、缓存、可修复协同状态
可观察结果 每项都有采用/拒绝理由和改变决定的反事实条件
证据等级 E1:设计评审;需与目标系统运行证据结合
本实验未证明 某个替代产品已经满足 SLA、安全、成本或团队能力

回顾

  • 先问失败是否可修复,再问用哪种集合。
  • DSM 不拥有订单事实、完整历史或全局线性化承诺。
  • 可从事实源重建的低延迟读取问题通常先按缓存需求评估,不能仅因涉及多个实例就引入一致性框架。
  • 拒绝 DSM 需要像采用一样给出可复核理由。

下一步

第 26 章把全书方法收敛成一个可运行、可故障注入、可观察且边界诚实的毕业项目。

证据链接