事件經過
2010 年 9 月,Facebook 停擺約兩個半小時。該公司工程團隊在軟體工程總監 Robert Johnson 同日發布的罕見公開事後報告中,稱這是網站四年多來最嚴重的一次斷線。每一位訪客、每一個頁面都遇到錯誤,直到網站恢復為止。
根本原因是一套旨在維持設定值健康的自動化系統:它會將快取值與持久化儲存進行比對,並替換任何它判定為無效的內容。當天,一次變更在持久化儲存本身留下了一個錯誤值。每個用戶端都看到這個「無效」值並試圖修復它,而由於修復意味著查詢資料庫叢集,該叢集每秒遭到數十萬次查詢衝擊。
錯誤處理讓情況更糟。當用戶端的查詢失敗時,它把失敗解讀為「值仍然無效」,並刪除對應的快取鍵——因而產生又一次修復查詢。即使原始錯誤值已被修正,這個迴圈仍持續自我餵養。唯一的出路是停止所有送往該資料庫叢集的流量,這意味著要將整個網站關閉、讓資料庫恢復,然後再讓使用者慢慢回流。
代價
整個網站停擺約 2.5 小時——Facebook 自家工程師稱這是四年多來最嚴重的一次斷線
為何發生
驗證器假設持久化儲存永遠正確;當它存有錯誤值時,每個用戶端都收到同樣被污染的修復指令。
錯誤處理將「資料庫過載」與「值無效」混為一談,因此每次失敗都產生更多負載——形成放大的回饋迴圈。
出錯時刪除快取鍵,等於移除了唯一可能吸收重試風暴的層級。
用戶端與叢集之間沒有斷路器,因此僅剩的槓桿就是全面關閉網站。
教訓
把每個錯誤都當成「去修復它」的自我修復程式碼,會放大故障而非吸收故障。應限制每個用戶端的重試次數、抑制回饋迴圈,並保留一個不必全面關站就能動用的復原槓桿。
後續
Facebook 同日關閉了自我修正設定系統,並表示正圍繞能容忍短暫尖峰與回饋迴圈的模式重新設計它。服務於當天完全恢復,這家當時全球最大的社交網路公司在數小時內公布了技術細節。這起事件至今仍被引為教科書案例,說明錯誤處理如何將一個小故障變成自我維持的風暴。
追溯依據
參考來源
- More Details on Today's Outage Facebook Engineering (Wayback Machine snapshot of the original note) · web.archive.org ·
- How Facebook fixed the site: they turned it off and on again. Literally The Guardian · theguardian.com ·
- Massive Facebook outage caused by improper error handling, not improper Facebook flirting as previously feared Engadget · engadget.com ·