不可靠的網路與故障偵測 (Unreliable Networks)

★★★★★Draft

FromDDIADatabase Internals

📚 From the Books

不可靠的網路與故障偵測 (Unreliable Networks)Distributed Troubles

單機軟體要嘛全對、要嘛整台當掉——行為是確定性的。一旦跨網路,就冒出第三種狀態:部分失敗 (partial failure)——有些節點好、有些壞,而且非確定性:同樣操作有時成、有時敗,你甚至不知道它到底成沒成。這一頁講的所有麻煩,都是這個第三種狀態的後果。

🧠 Intuition

TIP

資料中心與網際網路都是非同步封包網路 (asynchronous packet network):送一個封包出去,網路不保證它何時到、甚至是否會到。於是有一個問題你永遠無法從外部區分:對方是掛了,還是只是慢?——本頁一半的難題都出自這一句。

⚖️ Tradeoffs

偵測故障:明確訊號不可靠,最後只能等逾時
  • 有時有明確回饋:OS 還活著但程式崩了,會回 TCP 的 RST / FIN;路由器判定 IP 不可達會回 ICMP Destination Unreachable
  • 不能依賴它們:即使 TCP 確認封包已送達,應用程式也可能在處理前就崩潰。
  • 結果:多數時候只能等逾時 (timeout) 到了,才宣告一個節點死亡。
逾時的兩難:無界延遲讓公式失效
  • 設太長:故障偵測慢,使用者苦等。設太短:容易誤判,把只是變慢的節點宣告死亡(假性故障)。
  • 誤判的代價:把它的工作移給別人 → 增加他人負載 → 系統本就吃緊時觸發級聯失敗 (cascading failure),極端下所有節點互相判對方死。
  • 理想公式是 2d + r(網路最大延遲 d + 節點最大處理時間 r),但現實網路是無界延遲 (unbounded delay)、多數伺服器也不保證最大處理時間——公式的前提根本不成立。
延遲從哪來:排隊 (queueing) 與同步 vs 非同步網路
  • 延遲變異主要來自排隊:多節點同時送到同一目標,交換器要排隊、滿了就丟包;目標 CPU 忙就在 OS 排隊;VM 被暫停數十毫秒期間收不了封包;TCP 流量控制又在發送端加一層排隊。多租戶雲上還有吵雜鄰居 (noisy neighbor)
  • 對比傳統電話網:它建電路 (circuit)、預留固定頻寬,延遲有上界 (bounded delay)——這是同步網路
  • 資料中心選封包交換 (packet switching) 是因為流量是突發性的,動態共享頻寬能把利用率與成本壓下來,代價就是排隊與無界延遲。延遲不可預測不是自然定律,而是成本/效益的取捨
  • 務實做法:持續量測回應時間與抖動 (jitter)、自動調整逾時——這正是 Phi Accrual 故障偵測器(見下)的做法。
故障偵測器:從二元判死到 φ 疑似度
  • 完整性 (completeness) vs 準確性 (accuracy) 是根本取捨:偵測更快通常更不準、更準通常更慢——非同步系統裡兩者無法兼得。
  • Heartbeat / Ping:週期性互報存活;每個節點對其他節點維護「存活 / 死亡 / 可疑 (suspected)」三態,久未回應先標可疑而非直接判死;但確認訊息一延遲就可能誤報 (false positive)。
  • φ-accrual 故障偵測器:不吐 boolean,而給一個連續的疑似度 φ——用最近心跳到達時間的滑動視窗動態估計「此刻它故障的可能性」。被 Cassandra、Akka 採用。
  • SWIM / 間接偵測:P1 ping 不到 P2 時,委託幾個隨機節點代 ping P2(outsourced heartbeat),綜合直接與間接可達性,降低單點誤判。
  • Gossip 式偵測:心跳計數器在節點間擴散、聚合多方觀點,能抓到「沒有任何人連得上」的節點,比單點判斷可靠。

🔑 Takeaways

✍️ My Notes

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

📖 Further Reading

🔗 Dive Deeper