發生了什麼事
2011 年 4 月 21 日 UTC 8:15,Heroku 各處的監控警報響起:其網頁、快取與路由服務都出現逾時。觸發點在上游——根據 AWS 自己的說法,太平洋夏令時間凌晨 12:47,美東單一可用區的一次 AWS 網路變更,把主要 EBS 流量轉移到容量較低的複寫網路上,使 EBS 節點被隔離,並引發一場重新鏡像的風暴,導致該可用區 13% 的磁碟區卡住。
EC2 本身約 12 小時後恢復,但 EBS 的效能降級持續超過 80 小時。Heroku 把整個平台都跑在美東,資料庫也放在 EBS 上,因此無處可容錯移轉:它沒有第二個區域。大多數應用程式在 16 小時內恢復;跑在共用資料庫伺服器上的免費應用程式則花了長達三天。
Heroku 的事後檢討拒絕了顯而易見的藉口:「Heroku 對影響客戶的停機負起 100% 的責任。」它從中得出三個教訓:同一個區域內的可用區,並不會像團隊原本以為的那樣區隔風險;區塊儲存不是一種對雲端友善的技術;而一個承諾把基礎設施抽象化的平台,當該基礎設施故障時,就必須承擔後果。
代價是什麼
大多數應用程式在 16 小時內恢復;跑在共用資料庫上的免費應用程式停擺長達 3 天;美東的 EBS 效能降級超過 80 小時
為什麼會發生
整個平台都位於單一 AWS 區域,而其可用區後來被證明共享了 Heroku 原本以為已被區隔的故障模式。
有狀態的服務放在 EBS 上,而 EBS 在 EC2 恢復後很久仍持續故障——這是 Heroku 在事故期間既無法繞過、也無法替換的依賴。
標準的應變手冊——終止不健康的執行個體、替換它們、等待 AWS——假設停機只會持續一、兩個小時。這次卻持續了好幾天。
多區域多年來一直被降級處理,被視為一個對可用性幫助不大的大型專案。四月的停機在一個週末內就重新估算了它的價值。
教訓
同一個雲端區域內的可用區並不是備援。如果每個客戶都跑在同一個區域、同一種區塊儲存上,那麼上游的一次網路失誤就會變成所有人的停機。
後續發展
Heroku 表示會把多區域列為優先度高出許多的項目,並降低對 EBS 的依賴,同時開始進行架構變更,意在讓平台能挺過 IaaS 層級的故障。AWS 對這起事件的摘要,成為業界流傳最廣的故障分析之一,而「不要把所有東西都放在同一個區域」也成了標準的雲端建議。儘管如此,Heroku 在此後多年仍維持強烈的單一區域態勢,而它所辨識出的集中化問題,也在後續的事故中不斷重現。
追溯依據
參考來源
- Post-mortem on April 21 Outage Heroku Blog (Oren Teich) · heroku.com ·
- Heroku Status Incident #151 — full post-mortem of the April 2011 outage Heroku Status · web.archive.org
- Summary of the Amazon EC2 and Amazon RDS Service Disruption in the US East Region Amazon Web Services · aws.amazon.com ·