diff --git a/requirements.txt b/requirements.txt index 09e81fda..08cfaf60 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -mkdocs == 1.4.3 +mkdocs == 1.5.3 mkdocs-material == 9.1.15 mkdocs-git-revision-date-localized-plugin == 1.2.0 diff --git a/src/feedback/site-reliability-workbook/postmortem-culture.md b/src/feedback/site-reliability-workbook/postmortem-culture.md index b744cec1..5e6cd142 100644 --- a/src/feedback/site-reliability-workbook/postmortem-culture.md +++ b/src/feedback/site-reliability-workbook/postmortem-culture.md @@ -4,9 +4,145 @@ tags: SRE-workbook # 事後析誤文化 -在本書中,事後析誤是一個非常重要的文化他們想要推行的。 -和新的概念是一個沒有責備的事後析誤文化,並且這個文化是可以達成的。 +在本書描述中,事後析誤是一個在 Google 中非常重要的文化(事後析誤並不是什麼新科技,而是文化)。 +其核心的概念是:析誤過程中不要帶著責備。 好的事後析誤文化,會讓失誤減少,工作更高效和快樂,並減少重複性錯誤,加快錯誤恢復。 +而本篇的重點則是要傳達一個訊息:推廣事後析誤文化是可行的! + +以下文章將分為三大塊: + +- 比較壞的和好的事後析誤文件 +- 建立強健的事後析誤文化和辨識一些可能造成破壞的跡象 +- 一個工具和樣板幫助開始建立 + +## 邊緣快取和代理器的失能 + +雖然 Google 大部分的伺服器都位於自己管理的資料中心,但仍會在一些地區使用租借的資料中心, +使用託管服務(Colocation centre)建立快取(cache)和代理器(proxy), +而這類的機器在 Google 內部,稱其為 *衛星*(*satellites*)。 + +Google 對於維運設備的運行,大部分都是依靠自動化的, +包括新機器的軟體安裝、退役、版本升級、流量洩流(drain)等等。 +其中退役時的自動化稱其為 *磁碟抹除*(*dsikerase*), +一旦機器被抹除,儲存的所有資料將無法再被獲取。 +而這端自動化的邏輯大致如下: + +```javascript +// 得到指定資料中心(satellite)的所有在線機器 +const machines = getActiveMachinesFrom(satellite); + +// 透過 `filter` 把該指定資料中心的機器(而非所有資料中心的所有機器)進行退役 +sendToDecom({ + candidates: getAllActiveMachines(), + filter: machines, +}); +``` + +當維運人員進行日常的退役工作時,自動化執行結果得知有錯(然而實際上卻已經正確進行退役), +這時維運人員為了除錯,再一次的執行這個自動化腳本: + +```javascript +// 因為上一次把所有機器都退役了,所以這裡會得到空的陣列 +const machines = getActiveMachinesFrom(satellite); + +// `filter` 收到空陣列後,會直接選用所有的 `candidates` 而非空陣列 +sendToDecom({ + candidates: getAllActiveMachines(), + filter: machines, +}); +``` + +由於 `filter` 是空陣列,全世界所有衛星內受託管的機器都被進行磁碟抹除, +因為衛星內的機器被判定為失能,全世界所有的流量都被導流進 Google 自己維護的資料中心。 + +幸虧當初的容量規劃讓 Google 有能力承載這些流量, +這次的事件雖然耗時了兩天才把所有資料中心的伺服器恢復正常,但只造成些微的潛時(latency)上升。 +並且在事後數週進行健全的監控和建立阻斷器, +並確保該自動化流程是冪等的(idempotent,重複執行不會互相影響)。 +三年後,類似的事件導致部分衛星的伺服器失能, +而三年前的整治手段大大降低了該事件的爆炸半徑和恢復時間。 + +接下來,我們就來撰寫看看這次事件的事後析誤文件,並比較兩個不同文件的差異。 + +### 壞的事後析誤文件 + +事件所有者:楊一@、李二@、陳三@、王四@ + +事件概要: + +> - 影響:所有衛星機器都被磁碟抹除,並導致所有 Google 的邊緣運算能力失效。 +> - 根因:王四@ 忽略執行後的檢查,直接重複執行自動化的操作,進而觸發錯誤。 + +狀況總結: + +> - 持續時間:40 分鐘。 +> - 影響產品:邊緣運算資源。 +> - 影響比例:所有邊緣運算。 +> - 使用者影響:所有經過邊緣運算的請求延時拉高。 +> - 收益影響:有些廣告因為延時拉高,沒有正確投放。 +> - 發現於:監控告警。 +> - 復原於:透過人工復原邊緣運算,持續導引流量。 + +背景:無。 + +影響: + +> - 使用者影響:延時拉高。 +> - 收益影響:有些廣告沒辦法投放。 + +根因和觸發點: + +> 叢集的自動化操作不是冪等的。 +> 程式碼本身有避免部分機制重新執行的限制,但是無法阻止使用者重複執行程式本身。 +> 沒有任何文件說明這個陷阱,導致團隊成員大部分都任何重複執行是可被接受的。 +> +> 這便是在執行日常退役時,發生的錯誤原因。 +> 我們正準備把機器進行替換時,王四@ 完全忽略了上一次操作已經正確執行, +> 因為他的不小心導致進一步觸發該陷阱。 + +復原操作:無 + +學到了什麼: + +> - 我們做對了:告警成功觸發、事件管理機制正確運行。 +> - 我們沒做好:團隊(特別是楊一@、李二@)竟然沒有撰寫文件告知大家不要重複執行程式碼。 +> - 我們沒做好:待命小組沒有成功阻止磁碟抹除的自動化腳本從單一叢集擴大到全部叢集, +> 並且已經不是第一次反應這麼慢了。 +> - 幸運的事:核心運算資源能正常處理全球的流量,我不敢置信我們成功的避免災難發生!! + +### 為什麼文件寫得是糟 + +災難的價值在於好的事後析誤,正因如此,我們花時間去撰寫這份文件,將變得至關重要。 +閱讀者在看這份文件時,應該要清楚事件的脈絡,更重要的是能從事件中學到些什麼。 + +接下來我們分析一下為什麼上一份文件寫得很爛。 + +#### 背景描述的匱乏 + +本次事件有幾個專有名詞, +例如 *衛星* 代表用來處理邊緣運算的機器、*磁碟抹除* 代表自動化運行的腳本。 +如果你需要提供一些背景知識,請額外增加一些段落來說明,例如「詞彙表」或「背景知識」。 + +一個缺乏清楚概絡的文件,不只會讓人看不懂, +甚至會讓人選擇忽略這份文件,進而把能從事件學到的東西直接歸零。 + +#### 關鍵細節的忽略 + +很多段落只有高層次的概觀,缺乏重要的細節,例如: + +狀況總結中,我們無法從這份文件得知事件的影響範圍,如果影響範圍是多個產品,請明確給出相關的數值。 +這份文件中只有持續時間是數字,如果沒有相關數值,請盡量給出個估計, +畢竟 **沒有正確的爆炸半徑,就無法正確評估是否修復完成**。 + +根因和觸發點是事後析誤文件中非常重要的一點。 +在這份文件中,只有看到一小段落,缺乏足夠細節讓人能夠有機會思考其中的改進點。 + +我們通常能在復原操作段落中找到發生了什麼,怎麼被緩解以及使用者是怎麼被影響的, +然而這份文件卻完全空白。 + +### 好的事後析誤文件 + +## 結論 歷程大致是: 從小的專案開始,