故障模型与部分失效

01-基础与模型 核心 约 15 分钟 #故障模型#拜占庭#崩溃恢复#部分失效 更新 2026-10-02
当前状态:未学
本文基于模型知识整理(生成时未联网核对),关键结论建议对照经典文献复核。

一句话定义

故障模型按"坏得多离谱"给节点与链路的行为分级——从最温和的崩溃停机,到消息丢失/乱序,再到任意作恶的拜占庭行为——模型越强,能在其下保证正确性的算法越少、成本越高。

为什么重要

一切分布式协议的正确性都是相对于故障模型而言的:Raft 只容忍崩溃,PBFT 才容忍拜占庭。工程上选错模型有两个方向都致命的代价:按拜占庭设计会白白付出 3–10 倍开销;按理想网络设计则会在真实的乱序/丢包下悄悄出错。故障建模是容错设计的第一步。

前置知识

kp-001(部分失效概念)。

核心概念

按严重程度递增的常见模型:

  • crash-stop(崩溃即停):节点要么正常,要么彻底停止响应且不再恢复。
  • crash-recovery(崩溃恢复):节点崩溃后可重启,但易失内存状态丢失,需依赖持久化日志恢复——最贴近现实服务器的模型。
  • 遗漏故障(omission):消息发出但丢失,或节点未执行某些步骤。
  • 时序故障(timing failure):响应太晚(在异步模型中通常等价于"不知道是不是故障",见 kp-006)。
  • 拜占庭故障(byzantine):节点行为任意——返回错误数据、对不同节点说不同的话、假装多个身份。硬件位翻转、有 bug 的固件、被入侵的节点都可能近似于此。

链路侧对应:消息可丢失、重复、乱序、无限延迟。

原理与机制

检测的不可能性:在异步网络中,"节点崩溃"与"网络很慢"在观察上不可区分——你只能设置超时然后猜测(kp-006)。因此容错协议不假设"能准确知道谁死了",只假设"失效检测终将收敛"(最终完美故障检测器)。

容忍度与冗余的定量关系:

  • 崩溃故障下,2f+1 个节点可容忍 f 个崩溃(多数派:f+1 > f)。
  • 拜占庭故障下,需要 3f+1 个节点才能容忍 f 个作恶者(PBFT 结论,见 kp-022),且消息复杂度高得多。
  • f 的现实含义:不是"同时坏几个"那么简单——所有副本共享的故障(同一机架断电、同一配置错误、同一依赖故障)在协议眼里算一个故障。相关性失效是容错估计普遍偏乐观的根源。

图示

温和 ◄────────────────────────────► 恶意
crash-stop → crash-recovery → omission → timing → byzantine
  2f+1 冗余可容 f …………………………… 3f+1 冗余才容 f

直观类比

团队协作里的"成员失联"谱系:有人休假了(crash-stop,工位清空);有人电脑坏了重装(crash-recovery,草稿丢失,靠存档恢复);有人邮件发丢了(omission);有人回消息特别慢(timing);有人故意发假情报(byzantine)。防"休假"和防"内鬼"需要的制度完全不同。

实例或案例

  • crash-recovery 的现实性:Raft 假设节点重启后从持久化日志恢复(kp-019),因此要求 term/vote/log 持久化落盘顺序严格正确——FSYNC 语义错误是 Raft 实现的经典 bug 源。
  • 拜占庭的现实来源:2011 年亚马逊 EC2 的云端"幽灵心跳"(脑裂社区公告)让部分 ZooKeeper 集群认为节点已死而实际存活;NASA 与军工领域则因宇宙射线位翻转长期采用三模冗余。
  • 相关性失效:2017 年 S3 大故障源于一条输错参数的运维命令同时作用于大量服务器——副本再多也一起倒,是"算一个故障"的绝佳注脚。

常见误区

  • 误区一:"副本数 3 就能容 3-1=2 个故障"。崩溃模型下 3 副本只容忍 1 个(写多数派需要 2);数字关系必须结合协议推导,不能直觉相减。
  • 误区二:"被入侵才会拜占庭"。任意数据损坏(位翻转、坏盘返回脏数据、bug 导致的状态不一致)在协议视角同样是拜占庭行为。
  • 误区三:"故障检测器是准的"。它只是超时启发式,且失效检测的输出本质上永远是猜测。

与其他知识点的关系

  • kp-006:网络侧不可靠性是故障不可判定性的直接原因。
  • kp-017:FLP 定理刻画了在何种故障模型下共识根本不可解。
  • kp-022:拜占庭模型下的共识(PBFT)。
  • kp-012:CAP 中的 P 指的就是网络分区这一故障形态。

自测题

  1. crash-recovery 比 crash-stop 多了什么麻烦?

答:重启后易失状态丢失,协议必须依赖持久化日志重建状态,且崩溃瞬间"日志写了没"的不确定性要靠 fsync 语义处理。

  1. 为什么拜占庭容错需要 3f+1 个节点?

答:要保证诚实节点多数(2f+1)在存在 f 个作恶者时仍能形成多数派并且还能容忍其中 f 个同时变慢/失联,2f+1 不够,PBFT 证明 3f+1 是下界。

  1. 三个副本部署在同一机架上,容错数怎么算?

答:机架级故障(断电/交换机故障)同时打掉三者,协议视角只等于 1 个(强相关的)故障——副本必须考虑故障域隔离。

延伸阅读

  • Martin Kleppmann《DDIA》第 8 章"Faults and Partial Failures"。
  • Nancy Lynch 的分布式算法教材(Distributed Algorithms)关于故障模型分级。
  • Marc-André的中肯综述与 Jepsen 对真实系统故障假设的检验(见 kp-033)。