故障偵測 (Failure Detection)

★★★★Draft

FromDatabase Internals

📚 From the Books

故障偵測 (Failure Detection)Distributed Troubles

系統要對故障做出反應,前提是先及時偵測到故障。但在非同步系統裡這件事極難——沒有任何時間假設時,你無法判斷一個程序是已經崩潰只是慢、還是需要很久才回應。故障偵測器就是那個負責替演算法「判死」的本地子系統:把不可達的程序排除掉,同時盡量守住 liveness 與 safety。這一頁只談一件事——怎麼判定一個節點死了

🧠 Intuition

TIP

故障偵測器 (failure detector) 是每個節點本地的一個子系統,負責辨識「哪些程序故障或不可達」並把它們踢出演算法。它天生做不到完美,因為「慢」與「死」在非同步系統裡無法確切區分——所以務實的偵測器不追求「判對」,而是在偵測得夠快別誤判之間取一個平衡。

⚖️ Tradeoffs

Heartbeat vs Ping — 誰主動、看不到全貌
  • Ping:由監控方主動發訊息、等確認;Heartbeat:由被監控方主動週期性報平安。兩者都是週期性機制。
  • 每個程序對其他程序維護「存活 / 死亡 / 可疑」三態,並記錄最後回應時間;逾時未回應先進可疑狀態。
  • 侷限:這類方案的精確度完全取決於 ping 頻率與 timeout 的挑選,而且它只看得到「我到對方」這一條邊——捕捉不到其他程序眼中對方的可見性
逾時調參 — completeness 完整性 vs accuracy 準確性
  • 這是故障偵測的根本取捨:completeness(真的故障都要被抓到)與 accuracy(別把活著的判成死)無法兼得。
  • 更高效(偵測更快、更積極判死)的演算法往往不夠精確更精確的演算法通常效率較低(判得慢)。
  • 逾時設短 → 偵測快但誤判多;設長 → 少誤判但故障拖著沒被發現。挑 ping 頻率與 timeout,本質就是在這條線上選一個點。
Phi-Accrual — 不判是非,輸出連續的疑似度
  • 與把節點故障當成二元問題(活/死)不同,φ-accrual 用一條連續刻度來表達「此刻它崩潰的機率」。
  • 機制:維護一個滑動視窗收集最近 heartbeat 的到達時間,據此算出 suspicion level φ——代表在目前網路條件下,偵測器對「它故障了」有多大把握。
  • 好處是自適應:把「多晚算晚」交給實際觀測到的抵達分佈決定,而不是寫死一個 timeout;由 JAIST 的研究者提出,Cassandra、Akka 都在用。
Outsourced Heartbeats(SWIM)— 借別人的眼睛間接確認
  • SWIM(Scalable Weakly-consistent Infection-style process group Membership)用外包心跳提升可靠度:P1 ping 不到 P2 時,不急著判死。
  • 流程:P1 隨機挑幾個成員(如 P3、P4),委託它們代為 ping P2;只要 P2 對其中任何一個有回應,確認就轉發回 P1。
  • 價值:綜合直接與間接可達性、把判斷責任分散出去,壓低單一路徑抖動造成的誤判;而且節點不需認識網路上所有人,只要知道自己已連接的 peers 子集。
Gossip 式偵測 — 用多方聚合取代單一觀點
  • 為了不依賴單一節點的視角,gossip-style 偵測讓每個成員維護一張含其他成員 heartbeat 計數器與 timestamp 的清單。
  • 流程:每個成員週期性地把自己的計數器 +1,並把整張清單散播給隨機鄰居;收到的鄰居把它與自己的合併、取較新的計數。若某節點的計數器在夠長時間內都沒被更新,就視為故障。
  • 因為叢集的判斷是多節點觀點的聚合,它不只抓得到崩潰的節點,還能抓到那種「沒有任何人連得上」的節點。
反向思路(FUSE)— 把「沉默」當成傳播故障的訊號
  • FUSE 專注於可靠且低成本地傳播故障,即使網路分割也能運作:把所有活躍程序編成群組,一個成員不可用就讓全群組都偵測到。
  • 機制:群組內成員互相週期性 ping;一旦某成員無法回應,發起 ping 的成員自己也跟著停止回應——故障就從源頭一路擴散。
  • 巧思在於利用「通訊的缺失」本身當傳播手段:每個成員都保證會得知群組故障並據以反應,把單點故障轉化為 group failure。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading

🔗 Dive Deeper