系统与故障假设
超时是某个参与者的观测,不是对整个系统状态的判决。
消失的回执
客户端超时了,写入究竟发生了吗?
正在加载互动… 交互需要 JavaScript;正文仍可直接阅读。
学习目标
写清系统假设,区分安全性和活性,说明一次故障实验究竟能够支持什么结论。
前置:了解进程、文件和请求响应编程;无需先学共识算法。
先把约定说清
设三个服务保存同一个配置值。客户端发送 write(1) 后等待。三种执行对等待者可能完全一样:请求还没送到;服务已经提交,但响应被延迟;服务在提交前崩溃。客户端设置一个截止时间,并不能区分这三种情况。
客户端 服务端
发送 ───── 延迟 ─────► 尚未收到
发送 ────────────────► 提交 ─── 响应延迟
发送 ────────────────► 提交前崩溃
到达截止时间:客户端看到的都只是超时本课程的基本模型是非恶意节点、可带持久化存储重启的进程,以及可能延迟的消息。协议层面不讨论伪造身份;实际学习运行时使用回环地址上的明文连接与合成数据,不是生产部署模板。进程暂停代表该参与者暂不执行步骤,不能覆盖所有网络分区行为。
两种不同的承诺
安全性:禁止的事情不会发生。例如已完成的操作必须能放进对象约定的顺序中;在允许的 Leader 崩溃范围内,已提交配置不会消失。在算法故障假设内,任意延迟也不应破坏安全规则。
活性:期待的事情最终发生。例如足够节点可以通信、进程得到调度、存储能推进时,请求最终完成。一次有限实验可以展示这次完成或这次错过截止时间,无法证明所有调度下的“最终”。
完全异步模型没有已知的消息与处理延迟上界,因此慢节点与崩溃节点不可区分。FLP 结论限制了可能发生崩溃时、该模型下确定性共识的终止保证;它没有说实用共识系统无法存在。工程协议依赖一段有利的时序来推进,同时在不利时序下遵守安全规则。
动手:写一张故障卡
执行前列出:哪些进程会故障、磁盘是否保留、客户端连哪些端点、截止时间和不变量。对照多数派实验:杀死一个 etcd Leader,保留它的数据目录,另两个投票节点继续运行。先预测:已收到成功响应的写会不会消失?在途请求是否已知成功或失败?
注入:SIGKILL 一个自己创建的进程
保留:它的 WAL 目录、另两个投票节点
检查:旧的已确认值、新写入、原节点重启后的追赶
不检查:磁盘毁坏、拜占庭消息、多主机停电解释:新写成功说明这次执行中选主后恢复了推进;超时只说明该调用者在窗口内没有收到成功确认。
自测
把超时时间增大,就能证明对方已死吗?
不能。没有延迟上界时,对方总可能比所选阈值更慢。超时可以触发恢复策略,不能证明旧参与者不再行动。
为什么必须说明磁盘是否保留?
保留 WAL 的崩溃恢复,与保存记录的所有副本永久丢失,保证不同。“成功重启”不能代替备份还原测试。
原始资料
- Fischer、Lynch、Paterson:单故障进程下分布式共识的不可能性:模型和终止边界。
- etcd 3.6 故障模式:实际选主和多数派行为。
- MIT 6.5840:后续系统学习路线。
对照 MIT 6.5840 学习
Lecture 2: Threads and RPC · Lecture 6: Fault Tolerance: Raft (1)
分类观测,不把超时转换成回滚。
python3 scripts/learning_exercises.py assumptions本 Lab 可运行练习为独立原创,不是所链接 MIT 作业的解答。安装方法见复现页;不代表注册、评分或认证。
检索已核验课程地图 →