《SRE Google 運維解密》筆記

文章目錄


在這裏插入圖片描述

1. 主旨

之前有人問我這本書的中心思想是什麼?忘記了當時給出的答案了,但是讓我現在在回答一次的話,應該是——漫步 Google 運維,講述 Google 這個擁有海量數據、多數據中心的公司,是如果通過各種手段來保證它的可用性。接下來將會分爲四部分對該書進行總結:

  • 概覽——瞭解 SRE 的定義,以及該職位與傳統運維的區別
  • 指導思想——討論 SRE 的工作模式、行事方法,以及日常運維工作中關注的焦點
  • 具體實踐——理解 SRE 日常工作背後的理念,討論具體的構建與運維大型分佈式系統的實踐。
  • 管理——探索 Google 在培訓,內部溝通,以及在會議方面的最佳實踐。(ps 這篇筆記裏針對這部分是沒有描述的,感興趣建議自己閱讀

2. 概覽

2.1 提出 SRE 的動力?

很多公司開發部(Dev)和運維部(Ops)是分屬兩個不同部門的,這種 Dev/Ops 分離的團隊模型,無法避免的帶來兩類成本問題:

  • 直接成本:隨着系統複雜度的增加,部署規模的擴大,團隊的大小基本與系統負載成線性關係,共同增長。
  • 間接成本:研發團隊和運維團隊背景各異,技術能力和工具使用習慣上差距巨大,工作目標存在不可調和分歧點,而這些會嚴重影響產品的迭代。

但SRE 團隊的作爲解決上分歧點被提出來,在快速迭代與系統穩定性直接做了平衡。SRE 團隊的出現也大大節省了公司的開支。公司作爲盈利性組織,任何能夠節省公司開支的舉措都會被大力支持的,這纔是核心動力。

DevOps 這個名詞的核心思想是儘早的將 IT 相關的技術與產品設計和開發過程結合起來,着重強調自動化而不是人工操作,以及利用軟件工程手段執行運維任務等。可以認爲 DevOps 是 SRE 核心理念的普適版,SER 是 DevOps 模型在 Google 的具體實踐。

2.2 SRE 聚焦問題點

  • 確保長期關注研發工作:Google 將 SRE 團隊的運維工作限制在 50% 以內,剩餘的時間花在研發項目上。你需要擁有上帝視角,才能更好的解決問題。

  • 在保障服務 SLO 的前提下最大化迭代的速度:Dev 和 Ops 不可調和的矛盾點是迭代創新的速度與產品穩定程度之間的矛盾。 但是請記住,任何軟件都不應該一味地追求 100% 可靠,因爲大多數情況下 99.999% 和 100% 的可靠性是沒有實質區別的。所以你需要「錯誤預算」。

    你需要思考的是,花費巨大的精力將系統變爲 100% 可靠是否能爲用戶帶來實質意義上的好處?

    從用戶終端到服務器之間有很多中間系統(用戶終端、家庭 wifi、網絡提供商和輸電線路等)這些系統綜合起來的可靠性要遠遠低於 99.999%。

  • 監控系統:一個監控系統應該只有三類輸出:緊急警報、工單、日誌

    不論是如何優秀研發人員,過多的噪音,一定會影響你對事物的判斷。狼來的故事教育我們,你要在狼真的來的時候纔去呼救。

  • 應急事件處理:任何需要人工操作的事情都只會延長恢復時間。一個可以自動恢復的系統即使有更多的故障發生,也要比事事都需要人工干預的可用性更高。

  • 變更管理:制定符合自己公司的強管控的變更管理策略,會是一件很有趣、很有意義的事情。比如 Google 最佳實踐:

    • 採用漸進式的發佈機制
    • 迅速而準確的檢測到問題的發生(ps 目標是這個,手段因人而異
    • 當出現問題時,安全迅速地回退變更
  • 需求預測和容量規劃:這兩點是保障一個業務有足夠的容量和冗餘度去服務預測中的未來需求。一個盈利性公司的特點是業務不會停滯不前,所以用戶羣一定會增長,並且必然會增長。請爲你設計的系統預留這部分容量,如果不能預留,也請能發現增長的趨勢,及時作出應急舉措。

  • 資源部署:確保新上線的容量能夠正確地服務而用戶,你需要爲自己的系統設計合適的上線驗收策略。

  • 效率與性能:高效地利用各種資源是任何盈利性組織都要關心的。SRE 和產品研發團隊應該共同監控和優化整個系統的性能,這就相當於給服務增加了容量和提升了效率。從公司的角度看,雲產品的超賣策略不就是個很棒的 idea 嘛。

2.3 庖丁解牛

你看到的跟我看到的世界雖然是同一個,但是感受卻截然不同。

作爲用戶,我看到的只是一個可用的系統,這個系統能夠完成我需要的功能。我不需要知道背後的原理。

作爲研發,除了功能外,你需要做到能夠快速理解底層的實現。能夠看到截然不同的世界,我覺得這是很有趣的事情。

2.3.1 你看到了什麼?

  • 物理服務器:代表具體的硬件(有時候也代表一個 VM 虛擬機)
  • 軟件服務器:代表一個對外提供服務的軟件系統。

注:物理服務器上可以運行任何類型的軟件服務器。

2.3.2 如何管理你看到的?

管理物理服務器的系統管理軟件:

  • 管理物理服務器:Borg -> Kubernetes (Apache Mesos) 重新編排資源,以求達到最大化的資源利用率。
  • 存儲:熟悉各類存儲類型,瞭解目前公司支持的存儲類型,爲你的系統找到最合適的存儲。
  • 網絡:合理分配網絡帶寬,可以達到降低成本的目的。Google 使用 OpenFlow 協議的軟件定義網絡(SDN),是一種普通的非智能交換組件結合集中化的控制器連接方式。該控制器負責計算網絡中的最佳路徑。 這種中心化的路由計算,可以解決再分佈式路由模式下難以解決的流量遷移問題。 個人覺得這個設計思路的實踐可以看下這個 餓了麼異地多活技術實現(二)API-Router的設計與實現

所有好的技術都應該是從真實的業務場景中提煉出來的。「生命存在的價值應該是能夠創造更多的價值,技術亦是如此」,不要爲了使用而使用,而是你的業務場景真的需要它,比如系統軟件分佈式鎖服務、監控與報警系統。

Google 底層軟件基礎設施的設計目的是最高效的使用 Google 的硬件基礎設施。站在巨人的肩膀上的你,纔有可能看的更高,所以不要重複造輪子,而是學會基於輪子去造車。

2.3.3 能否站在全局視角上看問題?

一葉障目,不辯春秋。

你需要足夠熟悉自己負責的業務,但同時你也需要全局視角。可以看看這個 一個完整的 Web 請求到底發生了什麼

  • 用戶請求的處理過程:用戶 -> dns -> 反向代理(負載均衡)-> 網關(鑑權) -> 業務 -> 緩存 -> DB
  • 任務和數據的組織方式:發生未可知的故障的時候,你的系統是否仍能正常提供服務,你的冗餘度設計的是否合理。

在這裏插入圖片描述

3. 指導思想

3.1 學會擁抱風險

「過分追求穩定性不僅限制了新功能的開發、產品交付給用戶的速度,同時也很大程度的增加了成本。」

風險,定義爲遭受傷害或損失的可能性。

3.1.1 如何度量服務的風險?

  • 基於時間的可用性—— 可用性 = 系統正常運行時間 / (系統正常運行時間+停機時間)
  • 請求成功率——可用性 = 成功請求數 / 總請求數

在 Google 基於時間的可用性毫無意義,Google 所採用的故障隔離手段保證在任何時候,任何地方對於一個給定的服務,總是可以處理一定的用戶流量(ps 總結,有錢任性

請求成功率的計算需要注意一點:不是所有請求都是平等的,一個新的用戶註冊請求失敗和一個單純的後臺接口調用請求失敗是不同的

3.1.2 判斷服務風險的容忍度?

  • 用戶的容忍度:

    • 用戶可用性目標(是否是不可替代性服務,是否需要 100% 的可用性,是否是有償服務……
    • 用戶可接受的故障類型(持續低故障率或者偶爾發生的全網中斷哪一個更糟糕?
    • 其他服務指標(比如,廣告的投放是否會拖慢用戶的搜索體驗,這很重要
  • 服務自身對所依賴基礎設施的要求:

    • 瞭解所依賴基礎設施的可用性目標
    • 在基礎設施的故障時候,是否有逃逸策略
    • 嘗試優化基礎設施的成本

3.1.2 設計合適的「錯誤預算」

便利店收銀員在收銀的時候,公司會規定一個「收銀差異」,在差異內的誤差金額由公司承擔。而「錯誤預算」的作用和功能類似於「收銀差異」,它的使用使得討論發佈速率更容易,同時可有效的減少任何關於事故的討論。

爲發佈和穩定性之間設計一個平衡點,而這個點的體現就是「錯誤預算」。如果你的錯誤預算足夠的多,你可以快速迭代發佈新版本,反之,請保持基於「錯誤預算」的契約精神,謹慎對待每一次發佈。

3.2 服務質量目標

對於可靠的運維繫統來說,你需要了解系統中各種行爲的重要程度。Google 傾向於用不同的語義描述不同的行爲,服務質量指標(SLI)、服務質量目標(SLO)以及服務質量協議(SLA)。

  • 服務質量指標:請求延遲(處理請求所消耗的時間)、錯誤率(請求處理失敗的百分比)、系統吞吐量(每秒請求數量)、可用性。

  • 服務質量目標:服務某個服務質量指標的目標範圍值。比如,定義搜索請求的服務質量目標爲延遲小於 100ms。

    SLO 的選擇和公佈可以幫助設立用戶對於服務質量的預期,以及應對那些沒有根據抱怨「服務太慢了」的行爲。

  • 服務質量協議:指服務與用戶之間的一個明確的,或者不明確的協議,描述了在達到或者沒達到服務質量目標之後的後果。

3.2.1 指標在實踐中的應用

  • 運維人員和最終用戶各關係什麼: 只有理解用戶對系統的真實需求才能真正決定哪些指標是否有用,盲目將監控系統中的所有指標都定義爲 SLI 不是一個好方法

    • 用戶可見的服務系統 : 可用性
    • 存儲系統:延遲、可用性和數據持久性
    • 大數據系統:關係吞吐量和端到端的延遲
    • 所有系統:正確性
  • 指標的收集、彙總、標準化

    平均值 + 累計概率分佈是個好建議

3.2.2 目標在實踐中的應用

思考用戶關係的方面入手,而不是現在能度量什麼入手(如何正確做好,而非現在能做什麼

  • 目標定義:清晰具體爲上

  • 目標選擇:不要僅以目前的狀態爲基礎選擇目標、保持簡單、避免絕對值、SLO 越少越好、不要追求完美

  • 有效的控制手段:比較指標和目標,以決定是否執行什麼操作(突然想起切多活了……

  • 不要建立過高的用戶預期:留出一定的安全區、實際 SLO 也不要過高。

3.3 減少瑣事

3.3.1 定義瑣事

瑣事被定義爲手動性、重複性的、可以被自動化的、突發的、沒有持久價值的、與服務同步線性增長的。

3.3.2 正確理解工程工作的定義

工程工作(Engineering)是一種新型的,本質上需要主觀判斷的工作。典型的活動主要包括:

  • 軟件工程:編寫或修改代碼,以及所有其他相關的設計和文檔的工作。
  • 系統工程:配置生產系統、修改現有配置,或者用一種通過一次性工作產生持久的改進的方法來書寫系統文檔。
  • 瑣事:與運維服務相關的重複性的、手工的勞動。
  • 流程負擔:與運維服務不直接相關的行政負擔。

3.3.3 平衡

平衡瑣事的比重,Google 建議瑣事所佔有的比例要低於 50%。 「救火很重要,但是疲於一直救火,會阻止你去思考該如何從本質上去解決問題。」

在這裏插入圖片描述

3.4 分佈式系統的監控

如果你需要隨時隨地知道服務的運行狀況,那麼你需要構建一個適合自己業務的監控系統。知道服務運行狀況的最終目的是保證服務的穩定性,確保其能更好的服務用戶。

3.4.1 監控的 4 個黃金指標

  • 延遲:服務處理某個請求所需要的時間。能夠區分請求成功和失敗這點很重要。
  • 流量:使用系統中的某個高層次的指標針對系統負載進行度量。比如每秒 HTTP 請求數量等。
  • 錯誤:請求失敗的速率,顯示、隱式、或者是策略性導致的失敗。
  • 飽和度:系統中某種受限資源的具體度量,比如 CPU 、內存等。

度量指標不是目的,需要爲所度量指標設置合適的閾值,以期在指標不符合預期的時候,能迅速做出反應,縮小影響範圍,這纔是重點。

3.4.2 現象 vs 原因

你以爲你以爲的就是你以爲的嘛?並不是

現象:什麼東西出了故障

原因:爲什麼出了故障

例子:

  • 現象:返回 HTTP 500 或者 404 回覆速度很慢
  • 原因:數據庫服務器拒絕連接 or CPU 被某個排序操作佔滿,某根網線被壓在機櫃下面造成斷續的網絡丟包。

「在一切合理的答案都被邏輯排除後,剩下的那個因爲主觀,所以被貼上“不可能”的標籤的答案
即爲正解。」

3.4.3 降噪

過多監控會帶來負面效應,對比一天收到幾條和幾百條監控你的前後變化,會發現這是一件「被人忽略,但是收益很高」的事情。

3.5 Google 的自動化系統的演進

你會變老,反應也會變慢,但機器不會,機器永遠會按照你給的指令「周而復始,循環往復」的運行。

3.5.1 自動化的價值

  • 一致性:任何一個人或者一羣人執行數百次動作時,不可能保證每次都用同樣的方式進行,但機器可以。
  • 平臺性:平臺性的延伸價值意味着其通用性更高。
  • 修復速度更快:一個自治系統恢復的速度從概率上來說會小於手工接入使其恢復的速度。

3.5.2 可靠性

你要確保的第一要素是可靠性,系統能夠按照你預期的自動化方式運行,不能有分毫差距。大規模自動化運維的帶來的風險是,允許大規模故障的爆發。收益和風險的正相關關係,很重要。

3.5.3 痛苦是可以被表達的

如果在推動自動化的過程中受阻,請牢記以下兩點:

  • 一個不親自運行自動化的團隊是沒有動力去建設一個能夠很容易自動化的系統的,
  • 一個產品經理的時間表如果不受低質量的自動化影響,他永遠優先新功能的開發,而不是簡化和自動化

3.6 發佈工程

發佈工程是 Google 內部的一項具體工作。主要負責定義軟件發佈的全部步驟——包括軟件是如何存儲於源代碼倉庫,構建時是如何執行編譯的,如何測試、打包、最終部署。

Google 的體量之大,所以類似流水線的精細化分工會爲其帶來相應的收益。但對於體量相對較小的公司,發佈工程這部分工作常常由對應的研發人員或者運維人員所負責。所以我們可以借鑑 Google 在發佈工程中的設計哲學,減少發佈所帶來的穩定性問題。

3.6.1 發佈工程哲學

  • 自服務模型:開發工具,制定最佳實踐,讓產研團隊可以自己掌握和執行自己的發佈流程。
  • 追求速度:「面向用戶的軟件組件重新構建非常頻繁,因爲我們的目標是讓用戶可見的功能越快上線越好」。
  • 密閉性:構建工具必須確保一致性和可重複性。
  • 強調策略和流程:可回溯的歷史,能夠在系統發生問題的時候,讓你快速回退。

3.6.2 持續構建與部署

構建、分支、測試、打包、部署,請確保每個節點所做的事情符合預期。

3.7 簡單化

可靠性只有靠對最大程度的簡化不斷追求而得到。「凡是複雜的即爲易錯的」

3.7.1 系統的穩定性與靈活性

清楚地知道自己需要先探索以及失敗才能真正理解需要完成的任務。一個對於 SRE 管理系統方法的建議是:「始終在系統的靈活性和穩定性上維持平衡」。SRE 通過創造流程、實踐以及工具,來提高軟件的可靠性。同時,SRE 需要最小化這些工作對於開發人員的靈活性造成的影響。

3.7.2 乏味是一種美德

我們總是希望程序按照設計的進行執行,可預見性的完成目標,但是生產環境中的意外是 SRE 最大的敵人。

必要複雜度和意外複雜度:

  • 必要複雜度是一個給定的情況所固有的複雜度,不能從問題中移除。比如,編寫一個 Web 服務器需要處理快速提供 Web 頁面的必要複雜度。
  • 意外複雜度可以通過工程上的努力來解決。比如,我們使用 Java 編寫服務器代碼,試圖減少 GC 的影響。

3.7.3 我絕對不放棄我的代碼

因爲工程師也是人,他們經常對於自己編寫的代碼形成一種情感依附,這種衝突在大規模清理源代碼樹的時候並不常見。但是那些沒有使用的源代碼,會變成一顆顆會在未知時間引爆的炸彈,爲了世界和平,所以請深呼吸,然後刪除它。

3.7.4 「負代碼行」作爲一個指標

「軟件膨脹」用來描述軟件隨着時間的推移不停地增加新功能而變得更慢和更大的趨勢。這種趨勢從直觀上看就是不可取的,所以:

  • 要麼去複用你的代碼
  • 要麼去拆分你的服務
  • ……

最終讓你的代碼結構看起來清清爽爽,這是目的

3.7.5 最小 API

設計 API 請遵循這樣一個原則「不是在不能添加更多的時候,而是沒有什麼可以去掉的時候,才能達到完美」。

3.7.6 模塊化 + 發佈簡單

很多年以後,你會明白解耦合你的代碼,確保「高內聚,底耦合」,是多麼樸實但是又有深意的一句話。

在這裏插入圖片描述

4. 具體實踐

這本書還是挺良心的,告訴了你思想是什麼,同時又告訴了你基於這些思想,Google 是如何實踐的。具體包含書中 10 - 27 章,將會被分爲以下 7 個部分進行介紹:

  • 監控:10 章
  • 應急事件的處理:11 - 14 章
  • 事後總結和問題根源分析:15 - 16 章
  • 測試:17 章
  • 容量規劃:18 - 22 章
  • 軟件研發:23 - 26 章
  • 產品設計:27 章

4.1 基於時間序列數據進行有效的報警

離開監控系統,我們就沒有能力辨別一個服務是不是在正常提供服務。Google 的監控系統不僅要分析一些簡單的系統指標(比如某一臺在歐洲 Web 服務器的平均響應時間),還要分析更高抽象級別的指標(比如整個歐洲地區 Web 服務器的響應時間分佈情況)。

4.1.1 監控系統是什麼?

監控系統從本質上來說就是一個可編程的計算器。並且加入了一些語法糖,從而可以讓它產生報警信息。通常由數據收集、數據存儲、數據分析三個部分。

4.1.1.1 數據收集

在數據收集部分需要解決的問題是:

  • 需要針對什麼指標進行收集?
  • 收集的時間範圍是多久?
  • 精細化收集的粒度需要多高?
4.1.1.2 數據存儲

從單臺機器上收集到的數據,需要彙總處理,那麼數據如何存儲,纔會更好分析?

  • 一般選擇的都是基於時間序列的數據庫,從回溯歷史和硬件讀寫的角度,該類型的數據庫都合適。
4.1.1.3 數據分析

彙總全部的數據,針對服務質量指標(SLI)設置閾值,不滿足閾值的時候,通知對應負責人,人工介入解決問題。

4.1.2 報警

從日常生活中來看,我們報警,是因爲遇到了需要警察幫忙才能解決的問題,系統的報警也應該如此。頻繁報假警的會被處罰,對於一個具有仲裁機制的監控系統來說也應該如此,對於那種多次發出報警但是沒有人響應的報警,刪除它或許不是一件壞事情。

「提升專注力是一件好事情,可有可無的東西請統統忽視它。」

4.2 應急事件的處理

4.2.1 on-call 輪值

on-call 是一種手段,目的是爲了保障服務的可靠性和可用性。爲了 on-call 的工程師能夠快速的解決問題,平衡 on-call 工作是一個很好的建議。

  • 從數量上平衡:SRE 團隊 50% 的時間花在軟件工程上,在其餘的時間中,不超過 25% 的時間用來 on-call
  • 從質量上平衡:每 12 個小時的輪值最多隻能處理兩個緊急事件。

避免「過度聯想」和「習慣性思維」。

事物的本質很少呈現表象上。脫脂牛奶也可以假裝護膚霜。

4.2.2 有效的故障排查手段

系統正常,只是該系統無數異常情況下的一種特例。 —— John Allspaw (ps 這句話和「倖存者偏差」理論都很讓我震驚

4.2.2.1 理論

故障排障過程被定義爲反覆採取假設-排除手段的過程。大致就是通過觀察系統的監測指標和日誌信息瞭解系統目前的狀態。再結合我們對於系統構建的原理、運行機制,以及失敗模型的瞭解,提出一些可能的失敗原因。

4.2.2.2 實踐

書寫系統的故障報告是個好習慣,系統故障報告裏要寫清楚:

  • 系統預期是什麼
  • 系統實際的結果是什麼
  • 如何重新故障
  • 如何修復故障等

定位 -> 檢查 -> 診斷 -> 測試和修復 這個一個完整排障的鏈路。

定位問題的過程中,最重要的不是排障,是如何盡最大可能讓系統恢復服務。

4.2.3 緊急事件響應

東西早晚要壞的,這就是生活。

4.2.3.1 當系統出現問題時怎麼辦?
  • 測試導致的緊急事故:停止測試,恢復數據
  • 變更部署帶來的緊急事故:回滾
  • 流程導致的嚴重事故:終止流程

所有系統不但一定會出問題,而且會以沒有人能想到的方式出現問題。Google 從這些中學到的最關鍵的一課是,所有的問題都會有對應的解決方案。

4.2.3.2 向過去學習,而不是重複它

爲事故保留記錄,歷史就是學習其他人曾經犯過的錯。

4.2.4 緊急事故的管理

管理要素:

  • 嵌套式職責分離:事件總控、事件處理團隊、發言人、規劃負責人
  • 通知中心:受到事故影響的部門或者負責人需要實時跟事故總控負責人聯繫
  • 實時事故狀態文檔:確保關聯的每個人知道事故的進展
  • 明確公開的職責交接文檔:確保後續處理的人能夠最快投入處理
4.2.4.1 認錯

害怕犯錯是人類的本性,如果不小心犯了錯,那麼請一定記得要認錯。

先宣佈事故的發生,隨後找到一個簡單解決方案,然後宣佈事故結束,要比事故已經在持續了幾個小時以後纔想起來流程管控更好。如果事故滿足以下任何一條標準,建議及時宣佈:

  • 是否需要引入第二個團隊來幫助處理問題?
  • 這次事故是否正在影響到最終用戶?
  • 在集中分析了一個小時候,這個問題是否依然沒有得到解決?

在這裏插入圖片描述

4.3 事後總結和問題根源分析

4.3.1 事後總結:從失敗中學習

Google 事後總結的哲學:協作和知識共享,建立事後總結文化。

事後總結的主要目的是爲了保證事件被記錄下來,理清所有的根源性問題,同時關鍵的是,確保實施有效的措施使得未來重現的機率和影響得到降低,甚至避免重現。

「對事不對人」的事後總結不應該簡單地指責或者抱怨某個團隊,而應該確實提出服務如何能夠獲得進步。

4.3.2 跟蹤故障

提高可靠性的唯一方法論是建立一個基線(baseline),同時不斷跟蹤改變,Google 使用 Outalator——一個故障跟蹤分析工具來做這件事情。

該系統可以獲得如下信息:

  • 每次 on-call 輪值發生的報警次數是多少
  • 上個季度中可操作的報警和不可執行的報警的比例是多少
  • 哪個消耗的人工最多等

能夠對歷史數據進行定量的分析,找出可優化的方向,這些是將來可改進的基本點 。

4.4 測試

4.4.1 測試可靠性

如果你還沒有親自試過某件東西,那麼就假設它是壞的。

測試,是一個用來證明變更前後系統的某些領域相等性的手段,其目的是維持系統的穩定性。軟件測試的類型:

  • 傳統測試:單元測試、集成測試、系統測試(包括冒煙測試、性能測試、迴歸測試)。
  • 生產測試:配置測試、壓力測試、金絲雀測試等。
4.4.1.1 創造一個構建和測試環境

測試重點集中在「用最小的力氣得到最大收益的地方」。所以在測試一個系統的時候,請從以下方面開始思考:

  • 能否將源代碼按照重要程度區分出優先級
  • 是否某些函數或者類是非常關鍵的,或者對業務運營極爲重要
  • 哪些 API 是其他團隊需要集成使用的
4.4.1.2 大規模測試
  • 測試大規模測試使用的工具(確保你的工具是正確的
  • 針對災難的測試
  • 確保測試的準確率
  • 生產環境和測試環境分離(分離會帶來不一致的問題,導致你沒有辦法在測試環境穩定重新問題,但是危險總是不可能完全消除的,你需要做取捨
  • 允許測試失敗(縮短反饋週期
  • 集成(針對配置文件集成測試也很重要
  • 生產環境探針(監控和測試並不能完美的刻畫出一個正在運行的實時變化的系統,所以你需要探針,總覺得跟古代試毒的操作很像……

在這裏插入圖片描述

4.5 容量規劃

4.5.1 SRE 部門中的軟件工程實踐

SRE 開發的工具也是一個完整的軟件工程項目,它打破了團隊大小與用戶服務規模成比例增長的關係。

4.5.1.1 Auxon 工具的實踐

Auxon 是 SRE 內部開發的一個自動化容量規劃工具。因爲傳統的容量規劃方法,不可靠、耗時巨大,同時不夠精確。所以提出了設計並開發了基於意圖的自動化容量規劃工具。自動化所帶來的附加價值是,能夠更快速的應對容量規劃的變更。「意圖是服務服務責任人對如何運維該服務的理性表達。」

基於意圖的容量規劃:列出你的要求,而不要拘泥於具體的實現細節。

用戶不需要關係存儲的數據在哪個區域、哪個機房、哪個機櫃,哪個磁盤上,他需要你確保的是存儲的數據一定不會丟失。同理,能夠提供滿足用戶意圖的自動化容量規劃工具也應該被設計的如此。

A:我需要 50 個 CPU 的資源,必須在集羣 X、Y、Z 中,爲服務 Foo 使用

B:我想要滿足 Foo 在每個地理區域的需求增長,同時保障 N+2 的冗餘度

很明顯 B 的意圖更加清晰,表達產品意圖的先決條件是:

  • 依賴關係
  • 性能指標
  • 優先級
4.5.1.2 推動你的工具
  • 持續的和完整的推廣方案
  • 用戶的擁護
  • 資深工程和管理層的支持,前提是你的項目是有實力潛力的

不要過於關注完美和解決方案的純粹性,尤其是當解決問題的邊界不夠清晰的時候。我們應該更快速的發佈和迭代。

4.5.2 前端服務器的負載均衡

4.5.2.1 有的時候硬件並不能解決問題

用戶流量負載均衡系統是用來決定數據中心中的這些機器中的哪一個用來處理用戶的某個請求的。理想情況下,用戶流量應該最優地分佈於多條網絡鏈路上、多個數據中心中,以及多臺服務器上。

問題是:如何理解最優的分佈?

  • 邏輯層(是在全局還是在局部)
  • 技術層(硬件還是軟件)
  • 用戶流量的天然屬性

以簡單的搜索請求和視頻上傳場景來考慮最優問題。搜索系統用戶最關心的是「延遲」而視頻上傳系統用戶關心的則是「吞吐」。所以在最優化負載的時候:

  • 搜索請求將會被髮往最近的、可用的數據中心。判斷條件是包的 RTT。
  • 視頻上傳流則會選擇——目前帶寬沒有佔滿的鏈路,來達到最大化網絡吞吐量。
4.5.2.2 負載均衡
  • 基於 DNS 進行負載均衡
  • 基於 VIP 進行負載均衡(虛擬 VIP 不是綁定在某一個特定的網絡接口上的,它是由很多設備共享的

4.5.3 數據中心內部的負載均衡策略

包括將請求路由給某個具體服務器的應用級別策略。

4.5.3.1 健康管理
  • 如果某個後端任務過載了,請求處理開始變慢,負載均衡應該能自動避開這個後端,從而將任務分配給其他的後端。
  • 需要正確識別跛腳鴨狀態——後端服務正在監聽端口,並且可以服務請求,但是已經明確要求客戶端停止發送請求。
4.5.3.2 劃分集羣
  • 雞蛋不要放在一個籃子裏一直都很好的建議。

  • 在後端任務滾動重啓的操作,需要對客戶端透明,同時連接的變動最少(一致性 hash 是個好方案。)

4.5.3.3 負載均衡策略

簡單輪詢算法、最閒輪詢策略、加權輪詢策略等。

在這裏插入圖片描述

4.5.4 應對過載

避免過載,是負載均衡策略的一個重要目標。構建能良好處理資源限制的客戶端和對應的後端任務是最好的:在可能的情況下重定向請求,在必要時返回降級回覆,同時在最差的情況下,能夠妥善地處理資源受限而導致的錯誤。

  • 以可用資源來衡量可用容量
  • 給每個用戶設置限制:當全局過載情況真的發生時,使服務只針對某些「異常」客戶返回錯誤是非常關鍵的,這樣其他用戶則不受影響。
  • 客戶端側節流:當某個客戶端檢測到最近的請求錯誤中大部分都是由於「配額不足」錯誤導致時,該客戶端可以開始自行限制請求速度。
  • 基於重要程度給請求打標籤:最重要的、重要、可丟棄的
  • 資源利用率信號:隨着資源利用率的上升,可以根據請求的重要性來拒絕一些請求(最重要的請求對應最高的閾值)
  • 處理過載:區分是全局過載還是局部過載,局部過載重試則有一定概率會成功,全局過載重試則會加重過載問題。
  • 連接造成的負載:定期檢查連接資源(批量代理任務,隨機斷連接

4.5.5 處理連鎖故障

「爲什麼人們總是忘記增加一點點抖動因素呢?」 —— Ade Oshineye,Google 開發者佈道師

連鎖故障是由於正反饋循環導致的不斷擴大規模的故障。比如,服務的一個實例由於過載而出現故障,導致其他實例負載升高,從而導致這些實例像多米諾骨牌一樣一個一個全部出現故障。

4.5.5.1 防止軟件服務器過載
  • 隊列管理:隊列 + 線程池的方案(隊列中排隊的個數建議小於線程數
  • 流量拋棄和優雅降級:學會避免處理那些不值得處理的請求
  • 重試:基於指數型 + 抖動因子
  • 請求延遲和超時時間:任何時候設置超時是個好習慣,google GRPC 框架的第一個參數是 context ,應該是因爲這個
4.5.5.2 連鎖故障的觸發條件
  • 進程崩潰、進程更新、新的發佈、自然增長、計劃中或計劃外的不可用
4.5.5.3 解決連鎖故障的步驟
  • 增加資源、停止健康檢查導致的任務死亡、重啓軟件服務器、丟棄流量、進入降級模式、消除批處理負載、消除有害的流量。

在這裏插入圖片描述

4.6 軟件研發

4.6.1 管理關鍵狀態:利用分佈式共識來提高可靠性

分佈式共識系統主要解決:在不穩定的通信環境下一組進程之間對某項事情達成一致的問題。

4.6.1.1 使用共識算法的動力

分佈式系統系統協調失敗,產生腦裂問題或者需要人工干預災備切換。

4.6.1.2 分佈式共識的系統架構模式

分佈式共識算法很底層,很原始,它們僅僅可以讓一組節點一次共同接收一個值。

  • 可靠的複製狀態機(RSM):複製狀態機是實現在共識算法邏輯層之上的一個系統。
  • 可靠的配置數據存儲和配置存儲:複製數據存儲是複製狀態機的一個應用。
  • 使用領頭人選舉機制實現高可用的處理系統:複製多份系統並使用一個唯一的領頭人來進行某種類型的工作是很常見的設計。唯一的領頭人是一種保證粗粒度互斥的方法。
  • 分佈式協調和鎖服務:屏障(barrier)在分佈式計算機中是一種原語,可以用來阻擋一組進程繼續工作,,直到某種條件被滿足。
  • 可靠的分佈式隊列和消息傳遞
4.6.1.3 分佈式共識系統的性能問題

世界上沒有某個性能「最優」的分佈式共識和狀態機複製算法,因爲算法的性能通常取決於系統負載有關的多個因子,以及系統性能的目標和系統的部署情況。

  • 應對大量的讀操作:複製數據存儲的優勢在於數據同時在多個地點可用,如果不是所有的讀請求都需要強一致,數據就可以從任意一個副本來讀取。
  • 分佈式共識系統的性能與網絡延遲:
    • 共識系統在局域網中的性能和主從模式類似。 然而,分佈式共識系統通常需要副本運行在「較遠」距離上,這樣可以保障副本處於多個不同的故障域中
4.6.1.4 分佈式共識系統的部署
  • 副本的數量
  • 副本的位置
  • 容量規劃和負載均衡

大體量公司的煩惱也很多啊,如果只有一個機房的話,這些問題對於你來說根本就不存在……

4.6.2 分佈式週期性任務系統

問題:Cron 系統不可能知道要執行任務是否具有冪等性?比如垃圾回收操作或者批量發送 E-mil 通知的操作。系統設計的實現需要在跳過這次任務的執行和執行兩次之間做取捨。

答案:一般情況下都會選擇跳過這次任務的執行。

分佈式 Cron 系統的核心是 Paxos 協議,一個在分佈式不可靠系統達成一致的算法。

在這裏插入圖片描述

4.6.3 數據處理流水線

週期性的數據流水線是很有價值的,但是如果一個數據處理問題本身是持續性的,或者會自然增長爲持續性的,那麼就不要採用週期性的設計方式,而是採用一種類似 Workflow 的設計特點的系統。這樣一個系統能夠週期性地提供用戶所依賴的結果,並且是一個非常可靠且穩定的可運維繫統。

Workflow 通過將工作進程進一步劃分爲更小的任務組,而將流水線的「深度」隨意增加。每個任務組負責處理該階段執行的數據,可以對謀一小塊數據進行任意操作(比如 Mapping、Shuffing、排序、分割以及合併等操作。

本質理解的不是很好,後面有空需要重新回顧下。

4.6.4 數據完整性:讀寫一致性

數據完整性:是指數據存儲爲了提供一個合理的服務質量,在可訪問性和準確性方面必須達到的一個度量標準。

保障超高數據完整性的手段是主動探測和快速修復的能力。沒有人真的想要備份數據,他們只是想恢復數據。所以交付一個恢復系統,而非備份系統。

4.6.4.1 造成數據丟失的事故類型

根源問題:用戶行爲、管理員的錯誤、應用程序的 Bug、基礎設施中的問題、硬件故障和部署區的大型事故。

影響範圍:全部用戶 or 局部用戶

發生速度:瞬間 or 緩慢持續進行

4.6.4.2 Google SRE 保障數據完整性的手段

SRE 假設任何一種數據保護機制都可能在最不合適的時間出現問題,同時沒有一種銀彈可以同時保護所有事故類型,所以需要分級進行。

  • 用戶刪除:使用軟刪除策略,用戶可以自主還原數據,預防用戶錯誤。
  • 應用程序刪除數據:使用被備份策略,可以被用戶支持團隊或者應用程序管理員恢復,預防應用程序 Bug 和服務管理員錯誤。
  • 數據被摧毀:使用備份策略,無法還原需要使用備份,備份可以爲這個和其他所有場景提供保護。

Google 在 2012 年 3 月 Google Music 被意外刪除事件中,使用基於磁帶的備份,恢復了用戶被誤刪除的數據。嗯,是真的。

完美的理論不代表實現也是完美的。

在這裏插入圖片描述

4.7 產品設計

4.7.1 可靠地進行產品的大規模發佈

還記得前面說過的發佈工程師嘛?嗯,我覺得除了像 Google 這麼大體量的公司以外,很多公司應該都沒有這個崗位吧…… ( ps 突然想起了全局架構組,感覺好像有點類似的樣子

4.7.1.1 起草一個發佈檢查列表
  • 架構與基礎設施的依賴
  • 容量規劃:容量規劃與冗餘度和可用性都有直接關係
  • 故障模式:是否是單點,依賴服務不可用如何處理
  • 客戶端行爲:客戶端的濫用行爲是否會影響到服務的穩定性
  • 流程與自動化:流程文檔應該能夠做到使任何一個團隊成員都可以在緊急事故中處理問題
  • 開發流程:代碼的版本控制
  • 外部依賴:是否依賴三方代碼,是否有合作伙伴依賴你的服務,發佈時是否周知他們等
  • 發佈計劃
4.7.1.2 可靠發佈所需要的方法論
  • 灰度和階段性發布:任何改動都具有一定的危險性,而任何危險性都應該被最小化,這樣才能保障系統的可靠性。
  • 功能開發框架:創建一個可控更新的機制允許我們在真實負載情況下觀察系統的整體行爲。用工程的力量和時間換取一些可靠性的保障是很划算的。
  • 應對客戶端濫用行爲:服務器端控制客戶端行爲的能力是一個很重的功能。
  • 過載行爲和壓力測試:你的服務在未來的使用中會遭受最壞的處境時,仍能夠符合你的預期是很好的。

在這裏插入圖片描述

5. 碎碎念

因爲 14 天的隔離期還沒有過去,所以有很多的空閒時間。把一直沒有塗完的油畫塗好了,刷了一直想看但是沒時間看的電視劇《你好,舊時光》,還把《SRE Google 運維解密》大致看了一遍。其實讀書很多時候,第一遍可能不知道它寫的到底是什麼意思,索性做份筆記吧,這個筆記真長……。(ps 希望每個人都平安喜樂,萬事勝意
在這裏插入圖片描述
被種草了《梨泰院 class》不會劇荒啦,重要寫完了,撒花慶祝下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章