以可靠的方式運維大型分散式系統:我在Uber學到的實踐 - Gergely Orosz

banq發表於2019-07-18

在過去的幾年裡,我一直在構建和運營一個大型分散式系統:優步支付系統。在此期間,我學到了很多關於分散式架構概念的知識,並親眼目睹了高負載和高可用性系統不僅要構建還要執行的挑戰。構建系統本身是一項有趣的工作。規劃系統如何處理10x / 100x流量的增加,確保資料持久,面對硬體故障處理等等,這些都需要智慧。不管怎樣,運維大型分散式系統對我來說是一次令人大開眼界的體驗。

系統越大,墨菲的“什麼可能出錯,就會出錯”的定律就越會體現。對於頻繁部署情況、以及許多開發人員部署程式碼時,還有涉及多個資料中心以及系統被大量使用者全域性使用時,這種出錯概率越大。在過去的幾年裡,我經歷過各種各樣的系統故障,其中很多讓我感到驚訝。有些都來自可預測的事情,有些如硬體故障或生產中無名的錯誤,包括連線資料中心的網路電纜或同時發生的多個級聯故障。我經歷了數十次中斷,系統的某些部分無法正常工作,從而導致巨大的業務影響。

這篇文章是我在Uber工作時可以有效地運維大型系統的實踐的集合。我的經驗並不是獨一無二的 - 在類似規模的系統上工作的人也經歷了類似的旅程。我與Google,Facebook和Netflix的工程師進行了交談,他們分享了類似的經驗和解決方案。這裡列出的許多想法和流程應該適用於類似規模的系統,無論是在自己的資料中心(如Uber大多數情況下)上執行,還是在雲上執行(Uber 有時可以擴充套件到)。但是,對於規模較小或較少關鍵任務的系統而言,這些做法可能過於苛刻。

banq注:下圖是Uber的微服務圖:

以可靠的方式運維大型分散式系統:我在Uber學到的實踐 - Gergely Orosz

監控

要知道系統是否健康,我們需要回答“我的系統是否正常工作”的問題?為此,收集系統關鍵部分的資料至關重要。對於在多臺計算機和資料中心上執行多個服務的分散式系統,可能很難確定哪些關鍵事項確實需要監控。

1. 基礎設施健康監測 如果一個或多個計算機/虛擬機器過載,則分散式系統的某些部分可能會降級。服務執行的計算機的執行狀況統計資訊 - CPU利用率,記憶體使用情況 - 是值得監控的基礎知識。有些平臺可以開箱即用地處理這種監控和自動擴充套件例項。在優步,我們擁有一支優秀的核心基礎設施團隊,提供開箱即用的基礎設施監控和警報。無論如何實現,都要知道什麼時候事情是紅色的,或者服務的基礎設施是必須的資訊。

2.服務執行狀況監控:流量,錯誤,延遲。這是用於回答問題“這個後端服務是否健康?”。觀察訪問端點的請求流量、錯誤率和端點延遲等事項都可以提供有關服務健康狀況的有價值資訊。我更喜歡將這些都顯示在儀表板上。在構建新服務時,通過使用正確的HTTP響應對映並監視相關程式碼可以對系統有很多瞭解。因此,確保客戶端錯誤能返回4XX,以及如果伺服器錯誤則返回5xx,這種監控易於構建且易於解釋。

監測延遲值得再考慮一下。對於生產服務,目標是讓大多數終端使用者獲得良好的體驗。事實證明,測量平均延遲並不是一個很好的指標,因為這個平均值可以隱藏一小部分高延遲請求。測量p95,p99或p999 - 第95百分位,第99百分位或第99.9百分位的請求所經歷的延遲 - 是一個更好的指標。這些數字有助於回答諸如“99%的人的請求有多快?”之類的問題。(p99)或“至少1000人中有一人要求的速度有多慢?” (p999)。

對於那些對這個主題更感興趣的人,這篇延遲入門文章很好進一步閱讀。

圍繞監控和可觀察性有很多深度。值得一讀的兩個資源是Google的SRE書和關於分散式系統監控的四個黃金訊號的部分。他們建議,如果您只能測量面向使用者的系統的四個指標,請關注流量,錯誤,延遲和飽和度。

簡短的閱讀是來自Cindy Sridharan分散式系統可觀察性電子書,它涉及其他有用的工具,如事件日誌,指標和跟蹤最佳實踐。

3. 業務指標監控。雖然監控服務告訴我們很多關於服務看起來如何正常工作,但它沒有說明它是否按預期工作,是否“照常營業”。在支付系統,一個關鍵問題是,“人們可以使用特定的支付方式進行支付業務嗎?”。識別服務啟用和監控這些業務事件的業務事件是最重要的監控步驟之一。

業務指標監控是我的團隊在遭到因我們無法檢測到的中斷而受到傷害後建立的。我們所有的服務看起來都在正常執行,但關鍵功能卻在服務中出現問題。這種監控對我們的組織和領域來說非常有用。因此,我們必須在Uber可觀察性技術堆疊的基礎上,為自己定製這種型別的監控做了大量的思考和努力。

Oncall,異常檢測和警報

監控是人們檢查系統當前狀態的一個很好的工具。但它實際上只是一個自動檢測出現問題的絆腳石,並提出人們可以採取行動的警報。

Oncall本身就是一個廣泛的話題 - “增量”雜誌在On-Call問題上做了很多方面的工作。我強烈希望將oncall視為“你建立它,擁有它”思想的後續行動。建立服務的團隊擁有他們,也擁有oncall。我的團隊為我們建立的支付服務擁有oncall。因此,每當警報觸發時,呼叫工程師都會響應並檢視詳細資訊。但是我們如何從監控到警報呢?

從監控資料中檢測異常是一項艱鉅的挑戰,也是機器學習可以發揮作用的領域。有許多第三方服務可以提供異常檢測。我的團隊再次幸運,我們有一個內部機器學習團隊,他們為Uber用例量身定製了他們的解決方案。紐約的Observability團隊撰寫了一篇有關異常檢測如何在Uber工作的有用文章。從我的團隊的角度來看,我們將監控資料推送到該團隊的管道,並獲得各自置信水平的警報。然後我們決定是否應該尋找工程師。

何時發出警報是一個有趣的問題。警報太少可能意味著缺少有影響力的中斷。太多可能會導致不眠之夜並將人們燒掉。在調整警報系統時,跟蹤和分類警報以及測量訊雜比至關重要。通過警報和標記它們是否可操作,然後採取措施減少不可操作的警報是實現可持續的隨叫隨到輪換的一個很好的一步。

位於維爾紐斯的Uber開發人員工具團隊構建了整齊的隨叫隨到的工具,我們用它來註釋警報並視覺化上傳排程。我們的團隊每週都會對最後一次呼叫班次進行審查,分析痛點並花一些時間來改善呼叫體驗,一週又一週。

停電和事故管理流程

想象一下:你是本週的工程師。尋呼機警報會在半夜喚醒你。您調查是否發生了生產中斷。哦,哦。似乎系統的一部分已關閉。怎麼辦?監控和警報變得非常真實。

對於小型系統而言,停電可能不是那麼重要,因為呼叫工程師可以瞭解正在發生的事情以及原因。它們通常很容易理解並且易於緩解。對於具有多個(微)服務的複雜系統,許多工程師將程式碼推向生產,僅僅為了確定潛在問題發生的位置就具有足夠的挑戰性。有一些標準流程可以幫助解決這個問題,這會帶來巨大的變化。

附加到警報的Runbook,描述簡單的緩解步驟是第一道防線。對於具有良好Runbook的團隊,如果工程師oncall不深入瞭解系統,則很少會出現問題。Runbook需要隨時更新,更新並重新處理新型別的緩解措施。

只要有多個團隊部署服務,就必須在整個組織內進行通訊中斷:在我工作的環境中,成千上萬的工程師在他們認為合適的時候將他們工作的服務部署到生產中,從而導致每小時數百次部署。在一個服務上看似無關的部署可能會影響另一個服務。在這裡,標準化的中斷廣播和通訊渠道有很大的不同。我有多個案例,警報不像我以前見過的任何事情 - 並且意識到其他團隊中的其他人也看到了同樣奇怪的事情。作為中斷聊天組的中斷,我們確定了導致中斷的服務,並迅速緩解了問題。我們這樣做的速度要快得多,作為一個團體比我們自己做的任何人都要快。

 當下是緩解,明天才調查。在當機期間,我常常想要解決出錯的“腎上腺素衝動”。通常根本原因是程式碼部署不好,程式碼更改中存在明顯的錯誤。在過去,我會跳過修復錯誤,推送修復程式並關閉停止而不僅僅是回滾程式碼更改。但是,在當機中解決造成當機的根本原因是一個可怕的想法,通過前瞻性修復,幾乎沒有什麼可以收穫,單會有很多損失。必須快速完成新的修復,因此必須在生產中進行測試。搞清楚哪個是在現有錯誤之上引入第二個錯誤,只需先專注於減輕當前當機壓力,同時抵制對造成當機的根本原因的調查和修復的衝動。詳細的調查可以等到下一個工作日。

事後審查與持續改進的文化

正確完成的事後處理是強大系統的基石。是否可能花費大量精力進行後續工作,停止產品工作以進行系統級修復?優步事後模板隨著時間的推移不斷髮展,包括事件摘要,影響概述,事件發展時間表,根本原因分析,經驗教訓以及詳細的後續專案清單。

良好的事後調查深入挖掘根本原因並提出改進措施,以便更快地預防,檢測或減輕所有類似的中斷。深入挖掘“5 Whys”探索技術,深入挖掘,得出更有意義的結論。舉個例子:

  • 問題為什麼會發生?- >作為程式碼的一部分提交了一個錯誤。
  • 為什麼Bug不會被其他人抓住?- >程式碼審查員沒有注意到程式碼更改可能導致此類問題。
  • 為什麼我們只依賴程式碼審查員來捕獲這個bug?--->因為我們沒有針對此用例的自動測試。
  • “為什麼我們不對這個用例進行自動化測試?” - >因為沒有測試帳戶很難測試。
  • 為什麼我們沒有測試帳戶? - >因為這個系統還不支援它們
  • 結論:這個問題指出了沒有測試帳戶的系統性問題。建議為系統新增測試帳戶支援。在此之後,為所有未來類似的程式碼更改編寫自動化測試。

事件審查是事後審查的重要附帶工具。雖然許多團隊在事後進行徹底的工作,但其他團隊可以從額外的投入中受益,並受到預防性改進的挑戰。團隊也必須承擔責任並有權執行他們提出的系統級改進。

對於那些認真對待可靠性的組織而言,最嚴重的事件會得到經驗豐富的工程師的稽核和挑戰。還應該提供組織級工程管理,以提供授權以完成修復 - 特別是當這些修復非常耗時並阻止其他工作時。強大的系統不是一夜之間構建的:它們是通過連續迭代構建的。在從事故中學習之後,來自組織範圍內的持續改進文化的迭代。

故障轉移演習,計劃停機和容量規劃以及Blackbox測試

有一些常規活動需要大量投資,但對於保持大型分散式系統的正常執行至關重要。這些是我第一次在優步遇到的概念 - 在以前的公司,我們不需要使用這些,因為我們的規模和基礎設施沒有促使我們這樣做。

資料中心故障轉移機制是我認為是沉悶的東西,直到我觀察到它們中的一些好處。

我觀察到的最常見的故障情況是,在故障轉移的情況下,新資料中心中沒有足夠資源來處理全域性流量的服務。想象一下,ServiceA和ServiceB分別從兩個資料中心執行。讓我們假設資源的利用率為60% - 每個DC中執行數十或數百個VM - 並且警報設定為觸發70%。現在讓我們進行故障轉移,將所有流量從DataCenterA引導到DataCenterB。如果沒有配置新機器,DataCenterB突然無法應對負載。供應可能需要足夠長的時間才能使請求堆積起來並開始下降。此阻塞可能開始影響其他服務,導致其他系統上的級聯故障,甚至不是此故障轉移的一部分。

其他常見故障情況涉及路由級別問題,網路容量問題或背壓故障點。資料中心故障轉移是任何可靠的分散式系統應該能夠執行的演習,而不會對使用者造成任何影響。我強調應該 - 這次演習是測試分散式系統網路可靠性的最有用的練習之一。

計劃的服務停機時間是測試整個系統彈性的絕佳方法。這些也是發現特定系統的隱藏依賴關係或不適當/意外使用的好方法。雖然可以使用面向客戶端且幾乎沒有已知依賴關係的服務相對容易地完成此練習,但對於需要高正常執行時間和/或許多其他系統所依賴的關鍵系統來說,這樣做並不那麼簡單。但是有一天這個關鍵系統將無法使用時會發生什麼?最好通過受控挖掘驗證答案,所有團隊都意識到並準備就緒,以防止意外停機。

黑盒測試是一種測量系統正確性的方法,它接近終端使用者看到的條件。這種型別的測試類似於端到端測試。除了對大多數產品而言,進行適當的黑盒測試需要他們自己的投資。關鍵使用者流程和最常見的面向使用者的測試場景是很好的“黑盒子可測試”:以可以隨時觸發它們的方式執行此操作,以檢查系統是否正常工作。

以Uber為例,一個明顯的黑盒測試是檢查乘客流量是否在城市一級執行。也就是說,特定城市的乘客是否可以請求優步服務,搭乘駕駛員的車?一旦此方案自動化,就可以定期執行此測試,模擬不同的城市。擁有強大的黑盒測試系統可以更輕鬆地驗證系統(或系統的某些部分)是否正常工作。它對故障轉移練習也有很大幫助:獲得故障轉移反饋的最快方法是執行黑盒測試。

容量規劃對於大型分散式系統同樣重要。從大到大,我的意思是計算和儲存的成本每月數十或數十萬美元。在這種規模下,具有固定數量的部署可能比使用自擴充套件雲解決方案更便宜。至少,固定部署應該處理“一切照常”的流量,併為峰值負載進行自動縮放。但是下個月應該執行的最小例項數是多少?接下來的三個月?下一年?

預測成熟且具有良好歷史資料的系統的未來流量模式並不困難。然而,對於預算,選擇供應商或鎖定雲提供商的折扣都很重要。如果您的服務有大筆賬單而您沒有考慮容量規劃,那麼您就錯過了一種簡單的方法來降低和控制成本。

SLO,SLA和報告他們

SL0代表服務水平目標 - 系統可用性的數字目標。對於每個獨立服務,定義服務級SLO(如容量,延遲,準確性和可用性目標)都是很好的做法。然後,這些SLO可用作警報的觸發器。示例服務級SLO可能如下所示:

容量 最小吞吐量    500 req / sec
   最大預期吞吐量  2,500 req / sec
延遲 預期的中響應時間  50-90ms
    預期的p99響應時間 500-800ms
準確性 最大錯誤率    0.5%
可用性 保證正常執行時間 99.9%​​​​​​​

業務級SLO或功能SLO是服務之上的抽象。它們將涵蓋面向使用者或面向業務的指標。例如,業務級SLO可能是這樣的:期望在旅行完成後1分鐘內傳送99.99%的電子郵件收據。此SLO可能對映到服務級別的SLO(例如,支付和電子郵件收據系統的延遲),或者可能需要以不同方式進行測量。

SLA - 服務水平協議 - 是服務提供商和服務消費者之間更廣泛的協議。通常,多個SLO構成SLA。例如,99.99%可用的支付系統可以是SLA,它可以分解為每個支援系統的特定SLO。

在定義SLO之後,下一步是測量這些並報告它們。自動監控和報告SLA和SLO通常是一個複雜的專案,很容易為工程團隊和業務確定優先順序。工程團隊不會那麼感興趣,他們已經有各種級別的監控來實時檢測中斷。另一方面,該業務寧願優先提供功能而不是投資於不會對業務產生直接影響的複雜專案。

這將我們帶到下一個主題:運營大型分散式系統的組織遲早需要投入專門的人員來確保這些系統的可靠性。我們來談談網站可靠性工程團隊。

SRE作為獨立團隊

網站可靠性工程起源於Google,從2003年左右開始 - 至今已有超過1,500名SRE工程師。隨著生產環境的運營變得越來越複雜,需要越來越多的自動化,這項工作很快就會成為一項全職工作。當公司認識到他們的工程師在生產自動化中接近全職工作時,情況會有所不同:這些系統越關鍵,他們的失敗越多,發生的時間就越早。

快速發展的科技公司通常會在早期建立一個SRE團隊,他們會制定自己的路線圖。在優步,SRE團隊成立於2015年,其使命是隨著時間的推移管理系統複雜性。其他公司可能會在建立專用基礎架構團隊時開始組建這樣的團隊。當一家公司發展到可靠性時,跨團隊的工作需要花費不少工程師的時間,現在是時候為此建立一個專門的團隊。

有了SRE團隊,該團隊可以讓所有工程師更輕鬆地保持大型分散式系統的運營。SRE團隊可能擁有標準的監控和警報工具。他們可能購買或構建oncall工具,並且是oncall最佳實踐的goto團隊。它們可以促進事件審查和構建系統,以便更容易地檢測,減輕和預防中斷。它們肯定有助於故障轉移演習,通常推動黑盒測試,並參與容量規劃。他們推動選擇,定製或構建標準工具,以定義和衡量SLO並對其進行報告。

鑑於公司有不同的痛苦領域他們尋求解決SRE,SRE組織在各公司之間是不同的。該名稱通常也是其他名稱:它可以稱為運維,平臺工程或基礎結構。谷歌釋出了兩本關於網站可靠性的必讀書籍,這些書籍是免費提供的,並且是深入瞭解SRE的絕佳讀物。

作為持續投資的可靠性

在構建任何產品時,構建第一個版本只是一個開始。在v1之後,將在迭代中新增新功能。如果產品成功並帶來業務成果,那麼工作就會繼續。

分散式系統具有類似的生命週期,除了它們需要更多投資,不僅僅是新功能,而是要跟上擴充套件規模。隨著系統開始承受更多負載,儲存更多資料,有更多工程師在其上工作,需要持續關注以保持平穩執行。許多人第一次構建分散式系統時假設這個系統就像一輛汽車:一旦建成,它每隔幾個月就只需要必要的維護。這種比較無法進一步說明這些系統如何運作。

我喜歡考慮執行分散式系統的努力,類似於運營像醫院這樣的大型組織。為了確保醫院運作良好,需要持續驗證和檢查(監測,警報,黑盒測試)。新員工和裝置(新工程師和新服務)需要始終加入。隨著人數和服務數量的增長,舊的做事方式變得低效:就像農村的一個小診所與大都市的大醫院不同。提出更有效的工作方式成為一項全職工作,衡量和報告效率變得非常重要。就像大醫院有更多的支援人員,如財務,人力資源或安全; 運營較大的分散式系統同樣依賴於支援團隊,如基礎設施和SRE。

對於執行可靠分散式系統的團隊,組織需要持續投資於這些系統的執行以及它們所構建的平臺。

進一步推薦閱讀

雖然這篇文章的內容很冗長,但它仍然只涉及表面。為了深入瞭解操作分散式系統,我建議使用以下資源:

圖書

  • Google SRE Book - 來自Google的優秀免費圖書。該監控分散式系統包機是為這個職位尤為重要。
  • 分散式系統觀測辛迪Sridharan說,另一個優秀且免費的書監測分散式系統大點。
  • Martin Kleppmann博士[url=https://www.amazon.com/gp/product/1449373321/ref=as_li_tl?ie=UTF8&tag=gregdoesit-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=1449373321&linkId=adc1dc62fd3463b173cfd92dbe4ed821]設計資料密集型應用程式[/url] - 迄今為止我發現的關於分散式系統概念的最實用的書籍。但是,本書並沒有涉及帖子中討論的操作方面。

線上資源

請參閱有關Hacker News的這篇文章的評論

相關文章