ARC 2选择正确的一致性语义第 5–9 章
第 7 章 —— Lease:有期限的所有权
本章目标: 本章完成后,开发者能够用 acquire、renew、transfer、release 与 fencing token 表达有期限的分片所有权。
学习目标
- 区分「当前值」和「当前有权执行者」。
- 理解 TTL、epoch 与 fencing token 的不同职责。
- 解释续租、转移、释放和过期。
- 让外部资源拒绝旧持有者。
前置条件
- 已理解 Register 冲突裁决。
- 知道进程暂停、网络分区和时钟推进会造成旧 owner 继续运行。
案例进度
履约 worker 需要领取 orders-17
分片。只有有效持有者可以提交该分片的调度结果;所有权需要过期,转移后旧
worker 需要被挡在外部写入之前。
生命周期与护栏
lease.acquire("orders-17", acquireOptions).join();
lease.renew("orders-17", renewOptions).join();
lease.transfer("orders-17", "worker-b", transferOptions).join();
lease.release("orders-17", releaseOptions).join();TTL 回答「所有权何时失效」,fencing token 回答「外部系统如何识别旧持有者」。一次成功转移产生更高 token;数据库、对象存储或下游执行器需要保存最后接受的 token,并拒绝更小的值。
如果外部资源完全忽略 token,旧 worker 即使租约已过期仍可能写入。这不是 DSM 多复制一次就能修复的问题。
稳定成员视图为什么重要
Lease 是高风险协调动作。成员视图不稳定时,盲目重新分配可能让两个 worker 各自相信自己拥有分片。当前实现和测试的具体拒绝/模式边界应按 API 与运行信号判断,业务层不能只看一个本地 boolean。
反例与故障注入
让 worker A 获得 token 7 后暂停;租约转给 B,token 变成 8;A
恢复并继续写。如果外部执行器不比较 token,它会接受旧
owner。正确实验应同时验证租约状态和 FencingExecutor 对
token 7 的拒绝。
实验
cd submodule/dsm
mvn -q -pl dsm-integration-test -am \
-Dtest=RuntimeIntegrationTest#fencingExecutorRejectsStaleHolderAfterLeaseTransfer \
-Dsurefire.failIfNoSpecifiedTests=false test测试除检查 holder 名称外,还要在转移后让旧 holder 带旧 token 执行,以确认外部边界能够拒绝旧持有者。
实验验收卡
| 字段 | 内容 |
|---|---|
| 运行命令 | 上述 RuntimeIntegrationTest 聚焦命令 |
| 输入或故障 | A 持有后转移给 B;A 用旧 token 再执行 |
| 可观察结果 | B 获得更高 token;旧 token 被 fencing executor 拒绝 |
| 证据等级 | E2:单 Runtime 的集成行为测试 |
| 本实验未证明 | 真实成员分裂、跨进程暂停、所有外部存储都正确校验 token |
回顾
- Lease 表达有期限的执行权,不是普通最新值。
- TTL 终止时间窗口,fencing token 保护外部副作用边界。
- 转移需要让 token 单调前进;旧持有者可能仍活着。
- 没有外部 token 校验,就没有完整的 fencing 保证。
下一步
第 8 章允许所有节点都本地更新计数,不选唯一 owner,而是设计可以安全合并的状态。