本页目录

故障检测

在异步网络里,一个节点不回复消息——它真死了还是只是慢?φ-accrual 故障检测器不回答"是或否",而是输出一个"它已死的概率",让上层协议根据业务敏感度自己做决策。SWIM 把这个概率计算和 gossip 成员传播合二为一。

为什么故障检测难

在异步网络中(没有同步时钟、没有消息延迟上界),⁠不可能完美区分"节点 crash"和"网络慢"。任何基于超时的检测都可能误判。故障检测器必须在这种不确定性下给出"最合理"的怀疑。

简单 Heartbeat

每 T 秒: 节点 A 发 heartbeat → node B
  如果 B 在 timeout (如 3T) 内没收到 → 标记 A 为 dead

问题:固定超时太死板。网络抖动 → 误判。超时被调大 → 真实 crash 的检测延迟增加。

φ-accrual Failure Detector

不输出二值 alive/dead,而是输出 φ: suspicion level——当前假设节点存活的可能性有多低。上层应用可以自己决定"多大的 φ 值需要触发 failover"。

原理

记录历史心跳到达间隔的分布(mean μ, variance σ²)。每次延迟到达(当前时刻 - 上次心跳到达时刻 = t),计算 φ:

φ = -log10(P(到达间隔 > t | 分布))

如果心跳通常在 100ms 内到达,但这次等了 500ms——非常不可能 → φ 很大。如果是 150ms——可能只是抖动 → φ 小。

优势:

  • 自适应:根据实际网络条件(不是固定的"3 次超时")来做判断
  • 可配置:不同的服务可用不同的 φ 阈值。低延迟关键服务 → φ=5 就 failover。后台服务 → φ=10

应用:Akka (JVM actor framework), Cassandra (PhiConvictAdaptive failure detector)。

SWIM (Scalable Weakly-consistent Infection-style Membership)

当前最广泛使用的故障检测 + 成员发现协议(Consul, Serf, Tailscale 底层)。

协议

每个 member 独立运行:

每 T₁ 秒 (如 1s):
  1. 随机选一个 member P
  2. 发 PING → P
  3. 如果 P 在 T₂ (如 500ms) 内没回复 ACK:
     → indirect ping: 随机选 K 个 members (如 3 个), 请它们去 ping P
     → 如果这 K 个都收到 ACK → P 活着
     → 如果这 K 个也没有收到 → P 被 suspected

  4. 启动 gossip:
     - 如果 P 被 suspected: 选 M 个随机 members, 发 gossip message: P is suspected
     - gossip receiver: 存储此信息。如果自己成功 ping P → refute suspicion (发 alive message)

SWIM vs Heartbeat

  • Heartbeat: O(N) 消息每秒 (每个 member 向所有其他 member 发)
  • SWIM: O(1) ping per member per period + gossip = 极低的带宽, 支持数千节点
  • SWIM 的 indirect ping 显著降低了误判: member 到 member 的直连可能因网络局部故障而丢包,但从多个其他节点都能 ping 通 → 不是 dead

超时策略

TCP connect 超时, RPC deadline, gossip suspicion timeout——都是同一个问题。设计原则:

  1. 根据 p99.9 延迟设定⁠: 超时必须 > p99.9 延迟,否则误判率不可接受
  2. 区分 timeout 和 deadline: timeout = 网络/RPC 的等待上限; deadline = 整个操作的截止时间(多次重试后)
  3. 重试加指数退避 + jitter: 防止 thundering herd → 所有等待的 clients 同时重试 → 放倒刚恢复的服务
  4. 预算 timeout: 整个请求链(A→B→C→D)的总超时分配给各环节 → 快速失败不拖累整个链

参考

  • 论文⁠: "The φ Accrual Failure Detector" (Hayashibara et al, 2004)
  • 论文⁠: "SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol" (Das et al, 2002)
  • Serf: serf.io (HashiCorp, SWIM 实现)

Keywords: heartbeat, φ-accrual, SWIM, indirect ping, gossip, failure detector, membership protocol