Skip to content

SRE: How Google Runs Production Systems 讀書筆記(四)

  • Ops

on-call

關鍵是「數量」跟「品質」的平衡:

  • 數量:不超過 25% 時間 on-call
  • 品質:須要有充足的時間處理(含分析、debug、事後檢討,一個事件約須花 6 小時完成)

幾分鐘內要回應?

回應時間與服務水準、可靠性有關,例如面向使用者的服務須在 5 分鐘內回應,非敏感業務通常是 30 分鐘

維運負擔過大怎麼辦?

事件 / 警報比例應接近 1:1,避免重複警報導致維運壓力、調派有經驗的 SRE 協助、與研發團隊一起分擔維運

系統太穩定怎麼辦?

維運壓力不夠會導致自信過度或自信不足,每個工程師每季應至少參與一次 on-call,公司可定期舉辦災害演練

故障排除技巧

故障排除是一連串的「假設」+「排除」,這個技能是可以教學相長的,如果能做好事後檢討、紀錄負面結果(negative result),故障排除會是學習一套系統很有效的方法

小心避免以下陷阱:不理解現象(方向錯誤)、假設是對的,但測試假設的方法錯誤、過早下結論、被巧合/偽相關誤導

「緊急情況下,飛行員的首要任務是保持飛機飛行及安全登陸,故障定位和排除只是次要目標。」

Google 用什麼追蹤工具?

每個系統用的工具可能不同,文中提到的 Dapper 是 Google 內部很廣泛應用的工具,特別看了一下文獻整理幾個重點

在分散式系統,跨服務請求很常見,例如發出一個 requestX,在下游會發出額外數個請求 —— 攤開看就是一個 Tree(巢狀的 RPCs)

這個請求/響應歷程的樹狀結構稱為一個 Trace,當中的節點就是單一請求/響應,稱為 Span,裡面會紀錄時間戳、traceID、parentID、host 等詳細資訊。Span 是以本地文檔的方式建立和寫入的,再透過 Dapper daemon 去拉取並儲存到後端 —— BigTable, Trace 存成 row,Span 存到其對應的 sparse column

可以把 Span 視為是一種 Log,除了運行在伺服器上的 Dapper daemon,應用程式也可以透過函式庫發送 Span、加標籤或自訂的額外訊息等,這個重要功能稱為 annotation

Dapper 設計上很重視的理念是「低成本」,包含本地檔案的讀寫、後端儲存、網路頻寬(只佔小部份),因此採用取樣 (sampling) ,經驗上顯示取樣不只可以大幅降低延遲,也能讓資料得以保存更久,Dapper 的預設取樣率是 1/1024——對數據密集型系統而言,不會造成分析上的盲點

Dapper 原本只是一個追蹤工具(黑箱的),但後來演化成一個大型的監控平台,有強大的界面可以幫助分析,甚至到後來,發現可以應用的層面更廣:系統的依賴關係(dependency)分析、網路狀態分析、在共享儲存的基礎上區分服務、長尾延遲的分析、錯誤報告分析等

緊急事件的流程管理

職責分離很重要:

  • 指揮 (incident command):掌握事故基本資訊、負責組織處理團隊、分配/協調工作
  • 維運 (operational work):做系統修改(只有維運團隊能「動手」)
  • 發言 (communication):對外發言、擬稿、定時發送通知給所有相關的人員
  • 計畫 (planning):支援一般事務、紀錄交接及處理過程

用什麼方式溝通?

除了 E-mail ,溝通的方式推薦 IRC(internet relay chat):可靠、可完整紀錄

即時狀態紀錄範本

用 Google Docs(可多人線上編輯),以條列式紀錄事件概要、組織架構、待辦事項及時間軸

什麼時候宣佈事件?

取決於「是否須跨團隊」、「服務性質是否直接面向使用者」、「無法在一小時內解決」

事後檢討(Postmortem)

核心是「釐清根源性問題,避免未來再度發生」

要導入事後檢討,必須先定義標準和條件,例如「當機時間超過 SLO」、「有任何形式的 data-loss」

Best Practices

  • 對事不對人:事後檢討不是懲罰,而是整個公司的學習機會
  • 寫完後要審查:找資深工程師評估(例如影響評估是否完整、處理的優先順序是否合理)
  • 公開獎勵:可透過分享每週最佳事後檢討、發獎金來建立由工程師自主驅動的文化
  • 收集回饋

事後檢討範本

用 Google Docs,除了條列的事實陳述,還加上「反省」的部份,時間軸可以從即時狀態紀錄直接延伸

事件追蹤

從前面的章節可以知道,警報是從最細的 log 加上定義好的條件式得來的,可以視為 log 的彙總。而過多的重複警報是不好的(雖然觸發條件不同,但來自於同一個根源),因此警報也需要加以彙總,稱為「事件(event)」

一個好的警報系統有這些功能:

  • 可以分組、彙總
  • 可以添加標籤
  • 如果超時未處理,可以自動升級(escalation),例如通知副 on-call 工程師
  • 可以整合郵件服務,例如選擇一系列故障發給下一位 on-call 工程師

測試可靠性

當服務每做一次變更,可靠性都會降低(尤其是短時間做大量變更)。這時候我們可以提高測試數量(或覆蓋率)來降低「不確定性」跟可能影響可靠性的因子

有哪幾種測試?

  • 單元測試(unit test):只考慮最小的軟體單元,不考慮整體
  • 整合測試(intergration test):考慮多個相關的的獨立元件,透過 mock 模擬一方行為
  • 系統測試:可理解為測試站環境,可以測試點對點(end to end)功能
    • 冒煙測試(smoke test/sanity test):最基本、最優先做的基本功能測試
    • 效能測試(performance test):測試隨著時間變長系統效能跟資源要求的變化
    • 回歸測試(regression test):曾經發生過的 bug 重複拿來測試
  • 量產測試(production test / black-box test):可以以黑箱監控來理解,在正式環境上做測試(可配合小部份循序變更的發行步驟)
  • 組態測試(configuration test):測試參數組合、與正式環境使用的設定檔做交叉比對
  • 壓力測試:找出系統的效能邊界
  • 金絲雀測試:透過循序的小部份升級(常見標準從 0.1% 開始,每 24 小時增長 10 倍),監控使用情況判斷功能是否正常、是否該停止升級

怎麼評估金絲雀測試出現的錯誤?

哪些測試先寫?

  • 冒煙測試
  • 考慮元件的重要程度
  • 考慮元件中的重要的功能,例如購物車
  • 其他團隊會用到的功能或 API

怎麼計算測試覆蓋率?

很多工具可以計算測試對程式的覆蓋率,但重點是怎麼從一堆數字看出重點,例如「哪個模組才是最需要補測試的」,因此會須要可視化,例如畫成 TreeMap


最後筆記幾個有關測試的重點:

  • 最終一致(eventual consistent)不等同從頭到尾都一致,資料庫的 transaction 常需要考慮這點
  • 測試多執行幾次可能會有幫助
  • 須關注測試環境跟正式環境的不一致
  • 設定檔應該跟程式碼分開看待,設定檔的修改頻率比程式碼低很多
  • 使用直譯式語言如 Python 寫設定檔會有風險,因為不知道執行起來會花多少時間/資源
  • 正式環境的探針(probe)其實也是一種測試

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *