[技術思考]分佈式存儲系統的雪崩效應

mythmgn(筆者)是此篇舊文的做者, 曾發佈在其餘平臺, 從本月開始在博客園連載本身的技術文章和思考 (以爲 markdown 的支持好用!) . 轉載請註明出處, 謝謝.算法

歡迎你們左側關注個人公號, 一塊兒在技術領域互動和討論.後端

一 分佈式存儲系統背景

副本是分佈式存儲系統中的常見概念:將必定大小的數據按照必定的冗餘策略存儲,以保障系統在局部故障狀況下的可用性。安全

副本間的冗餘複製方式有多種,比較經常使用有兩類:服務器

  • Pipeline:像個管道,a->b->c,經過管道的方式進行數據的複製。該方式吞吐較高,但有慢節點問題,某一節點出現擁塞,整個過程都會受影響
  • 分發:client -> a  client ->b client ->c。系統總體吞吐較低,但無慢節點問題

對於冗餘副本數目,本文選擇常見的三副本方案。markdown

分佈式存儲系統通常擁有自動恢復副本的功能,在局部存儲節點出錯時,其餘節點(數據副本的主控節點或者client節點,依副本複製協議而定)自動發起副本修復,將該宕機存儲節點上的數據副本恢復到其餘健康節點上。在少許宕機狀況下,集羣的副本自動修復策略會正常運行。但依照大規模存儲服務運維經驗,月百分之X的磁盤故障率和月千分之X的交換機故障率有很大的可能性致使一年當中出現幾回機器數目較多的宕機。另外,批量升級過程當中若出現了升級bug,集羣按照宕機處理須要進行副本修復,致使本來正常時間內能夠完成的升級時間延長,也容易出現數目較多的宕機事件。網絡

二 雪崩效應的產生

在一段時間內數目較多的宕機事件有較大可能性誘發系統的大規模副本補全策略。目前的分佈式存儲系統的兩個特色致使這個大規模副本補全策略容易讓系統產生雪崩效應:併發

a. 集羣總體的free空間較小:一般總體<=30%, 局部機器小於<=20% 甚至10%負載均衡

b. 應用混布:不一樣的應用部署在同一臺物理/虛擬機器上以最大化利用硬件資源運維

今年火起來的各類網盤、雲盤類服務就是a的典型狀況。在各大公司拼我的存儲容量到1T的背後,其實也在拼運營成本、運維成本。現有的雲存儲大多隻增不減、或者根據數據冷熱程度作數據分級(相似Facebook的數據分級項目)。雲存儲總量大,但增量相對小,爲了減小存儲資源和帶寬資源浪費,新建立的文件若原有的存儲數據中已有相同的md5或者sha1簽名則當作已有文件作內部連接,再也不進行新文件的建立。但即便這樣,總體的數據量仍是很大。分佈式

目前雲存儲相關業務未有明顯的收入來源,每一年卻有數萬每臺的服務器成本,爲運營成本的考慮,後端分佈式存儲系統的空閒率很低。而瞬間的批量宕機會帶來大量的副本修復,大量的副本修復頗有可能繼而打滿本來就接近存儲quota的其餘存活機器,繼而讓該機器處於宕機或者只讀狀態。如此繼續,整個集羣可能雪崩,系統殘廢。

三 預防雪崩

本節主要討論如何在系統內部的邏輯處理上防止系統總體雪崩的發生。預防的重要性大於事故以後的處理,預測集羣狀態、提早進行優化也成爲預防雪崩的一個方向。

下面選取曾經發生過的幾個實際場景與你們分享。

1. 跨機架副本選擇算法和機器資源、用戶邏輯隔離

現場還原:

某天運維同窗發現某集羣幾十臺機器瞬間失聯,負責觸發修復副本的主控節點開始進行瘋狂的副本修復。大量用戶開始反饋集羣變慢,讀寫夯住。

現場應對:

優先解決——副本修復量過大形成的集羣總體受影響。

a. 處理的工程師當機立斷,gdb到進程更改修復副本的條件爲副本<2,而非本來的3(replicas_num),讓主控節點這個時候僅修復副本數小於2個的文件,即保證未丟失的文件有至少一個冗餘副本,防止只有一個副本的數據因可能再次發生的掛機形成文件丟失。

b. 緊急解決這批機器失聯問題,發現是交換機問題,a.b.c.d ip網段的c網段機器批量故障。催促網絡組儘快修復。

c. 副本修復到>=2以後,Gdb更改檢測副本不足週期,將幾十秒的檢測時間推遲到1天。等待網絡組解決交換機問題。

d. 網絡恢復,原有的機器從新加入集羣。大量2副本文件從新變爲3副本,部分3副本全丟失文件找回。

e. 恢復主控節點到正常參數設置狀態,系統開始正常修復。

改進措施:

在改進措施前,先分析下此次事件暴露的系統不足:

1) Master參數不支持熱修正,Gdb線上進程風險過大。

2) 必定數量但局域性的機器故障影響了總體集羣(幾十臺相對一個大集羣仍屬於局域性故障)。如上所述,月千分之幾的故障率總有機會讓你的存儲系統經歷一次交換機故障帶來的集羣影響。

案例分析後的改進措施出爐:

1)  Master支持熱修正功能排期提早,儘早支持核心參數的熱修改。

熱修改在上線後的效果可觀,後續規避過數次線上問題。

2) 在選擇數據副本存儲宿主機器的pickup算法中加入跨交換機(機架位)策略,強制——或者儘可能保證——副本選擇時跨機架位。這種算法底下的副本,至少有1個副本與其餘兩個副本處於不一樣的交換機下(IP a.b.c.d的c段)。該措施同時做用於新的存儲數據副本選擇和副本缺失後的副本補全策略,能在副本宿主選擇上保證系統不會由於交換機的宕機而出現數據丟失,進而避免一直處於副本補全隊列/列表的大量的丟失副本節點加劇主控節點負載。

3) 機器按region劃分隔離功能提上日程;用戶存儲位置按照region進行邏輯劃分功能提上日程;Pickup算法加入跨region提上日程。

a) 機器按照物理位置劃分region、用戶按照region進行邏輯存儲位置劃分,能讓集羣在局部故障的狀況下僅影響被邏輯劃分進使用這部分機器的用戶。

這樣一來,最壞狀況無非是這個region不可用,致使擁有這個region讀寫權限的用戶受影響。Pickup算法跨region的設計進一步保證被劃分region的用戶不會由於一個region不可用而出現數據丟失,由於其餘副本存到其餘region上了。因而,核心交換機故障致使一個region數百臺機器的宕機也不會對集羣形成範圍過大的影響了。

b) 增長region可信度概念,將機器的穩定性因素加入到副本冗餘算法中。

當集羣規模達到必定量後,會出現機器穩定性不一樣的問題(通常來講,同一批上線的機器穩定性一致)。經過標記region的穩定性,能強制在選擇數據副本的時候將至少一個副本至於穩定副本中,減小所有副本丟失的機率。

c) Region劃分須要綜合考慮用戶操做響應時間SLA、物理機器穩定狀況、地理位置等信息。

合理的region劃分對提高系統穩定性、提高操做相應時間、預防系統崩潰都有益處。精巧的劃分規則會帶來總體的穩定性提高,但也增長了系統的複雜度。這塊如何取捨,留給讀者朋友深刻思考了。

2. 讓集羣流控起來

流控方面有個通用且符合分佈式存儲系統特色的原則:任何操做都不該佔用過多的處理時間。這裏的「任何操做」包含了在系統出現流量激增、局部達到必定數量的機器宕機時進行的操做。只有平滑且成功的處理這些操做,才能保證系統不由於異常而出現總體受影響,甚至雪崩。

現場還原:

1) 場景1 某天運維同窗發現,集羣寫操做在某段時間大增。經過觀察某個存儲節點,發現不只是寫、並且是隨機寫!某些產品線的總體吞吐降低了。

2) 場景2 某集羣存儲大戶須要進行業務調整,原有的數據作變動,大量數據須要刪除。

運維同窗發現,a. 整個集羣總體上處於瘋狂gc垃圾回收階段 b. 集羣響應速度明顯變慢,特別是涉及到meta元信息更新的操做。

3) 場景3 某天運維同窗忽然發現集羣併發量激增,單一用戶xyz進行了大量的併發操做,按照原有的用戶調研,該用戶不該該擁有如此規模的使用場景。

此類集羣某些操做預期外的激增還有不少,再也不累述。

現場應對:

1) 馬上電聯相關用戶,瞭解操做激增緣由,不合理的激增須要馬上處理。

咱們發現過以下不合理的激增:

a. 場景1類:經過Review代碼發現,大量的操做進行了隨機讀寫更改。建議用戶將隨機讀寫轉換爲讀取後更改+寫新文件+刪除舊文件,轉換隨機讀寫爲順序讀寫。

b. 場景3類:某產品線在線上進行了性能測試。運維同窗馬上通知該產品線中止了相關操做。全部公有集羣再次發經過郵件強調,不可用於性能測試。若有須要,聯繫相關人員在獨佔集羣進行性能場景測試。

2) 推進設計和實現集羣各個環節的流控機制功能並上線。

改進措施:

1) 用戶操做流控

a. 對用戶操做進行流控限制

可經過系統內部設計實現,也可經過外部的網絡限流等方式實現,對單用戶作必定的流控限制,防止單個用戶佔用過多整個集羣的資源。

b. 存儲節點操做流控

可按照對集羣的資源消耗高低分爲High – Medium – Low三層,每層實現相似於搶token的設計,每層token數目在集羣實踐後調整爲比較適合的值。這樣能防止某類操做過多消耗集羣負載。若某類操做過多消耗負載,其餘操做類的請求有較大delay可能,繼而引起timeout後的重試、小範圍的崩潰,有必定概率蔓延到整個集羣併產生總體崩潰。

c. 垃圾回收gc單獨作流控處理。刪除操做在分佈式存儲系統裏面經常使用設計是:接收到用戶刪除操做時,標記刪除內容的meta信息,直接回返,後續進行策略控制,限流的刪除,防止大量的gc操做消耗過多單機存儲節點的磁盤處理能力。具體的限流策略和token值設置須要根據集羣特色進行實踐並得出較優設置。

2) 流控黑名單

用戶由於對線上作測試類的場景能夠經過人爲制度約束,但沒法避免線上用戶bug致使效果等同於線上測試規模的場景。這類的場景通常在短期內操做數嚴重超過限流上限。

對此類場景可進行流控黑名單設置,當某用戶短期內(e.g. 1小時)嚴重超過設置的上限時,將該用戶加入黑名單,暫時阻塞操做。外圍的監控會通知運維組同窗緊急處理。

3) 存儲節點併發修復、建立副本流控

大量的數據副本修復操做或者副本建立操做若是不加以速度限制,將佔用存儲節點的帶寬和CPU、內存等資源,影響正常的讀寫服務,出現大量的延遲。而大量的延遲可能引起重試,加劇集羣的繁忙程度。

同一個數據宿主進程須要限制併發副本修復、副本建立的個數,這樣對入口帶寬的佔用不會過大,進程也不會由於過量進行這類操做而增長大量其餘操做的延遲時間。這對於採用分發的副本複製協議的系統尤爲重要。分發協議通常都有慢節點檢查機制,副本流控不會進一步加劇系統延遲而增大成爲慢節點的可能。若是慢節點可能性增大,新建立的文件可能在建立時就由於慢節點檢查機制而缺乏副本,這會讓集羣情況更加惡化。

3. 提早預測、提早行動

1) 預測磁盤故障,容錯單磁盤錯誤。

場景復現:

某廠商的SSD盤某批次存在問題,集羣上線運行一段時間後,局部集中出現數量較多的壞盤,但並不是全部的盤都損壞。當時並未有單磁盤容錯機制,一塊磁盤壞掉,整個機器就被置成不可用狀態,這樣致使擁有這批壞盤的機器都不可用,集羣在一段時間內都處於副本修復狀態,吞吐受到較大影響。

改進措施:

a) 對硬盤進行健康性預測,自動遷移大機率即將成爲壞盤的數據副本

近年來,對磁盤健康狀態進行提早預測的技術愈來愈成熟,技術上已能夠預判磁盤健康程度並在磁盤擁有大機率壞掉前,自動遷移數據到其餘磁盤,減小磁盤壞掉對系統穩定性的影響。

b) 對單硬盤錯誤進行容錯處理

存儲節點支持對壞盤的異常處理。單盤掛掉時,自動遷移/修復單盤的原有數據到其餘盤,而不是進程總體宕掉,由於一旦總體宕掉,其餘盤的數據也會被分佈式存儲系統當作缺失副本,存儲資源緊張的集羣經歷一次這樣的宕機事件會形成長時間的副本修復過程。在現有的分佈式存儲系統中, 也有相似淘寶TFS那樣,每一個磁盤啓動一個進程進行管理,整機掛載多少個盤就啓動多少個進程。

2) 根據現有存儲分佈,預測均衡性發展,提早進行負載均衡操做。

這類的策略設計愈來愈常見。因爲分佈式存儲集羣掛機後的修復策略使得集羣某些機器總有概率成爲熱點機器,咱們能夠對此類的機器進行熱點預測,提早遷移部分數據到相對負載低的機器。

負載均衡策略和副本選擇策略同樣,須要取捨複雜度和優化程度問題。複雜的均衡策略帶來好的集羣負載,但也所以引入高複雜度、高bug率問題。如何取捨,仍舊是個困擾分佈式存儲系統設計者的難題。

四 安全模式

安全模式是項目實踐過程當中產生的防分佈式存儲系統雪崩大殺器,所以我特別將其單獨列爲一節介紹。其基本思路是在必定時間內宕機數目超過預期上限則讓集羣進入安全模式,按照策略配置、狀況嚴重程度,中止修復副本、中止讀寫,直到中止一切操做(通常策略)。

在沒有機器region概念的系統中,安全模式能夠起到很好的保護做用。我過去參與的一個項目經歷的某次大規模宕機,因爲沒有安全模式,系統進行正常的處理副本修復,生生將本來健康的存儲節點也打到殘廢,進而雪崩,整個集羣都陷入瘋狂副本修復狀態。這種狀態以後的集羣修復過程會由於已發生的副本修復致使的元信息/實際數據的更改而變的困難重重。 該事件最後結局是數據從冷備數據中恢復了一份,丟失了冷備到故障發生時間的數據。

固然,安全模式並不是天衣無縫。「一段時間」、「上限」該如何設置、何時停副本修復、何時停讀、何時停寫、是本身恢復仍是人工干預恢復到正常狀態、安全模式力度是否要到region級別,這些問題都須要安全模式考慮,而此類的設計通常都和集羣設計的目標用戶息息相關。舉例,若是是低延遲且業務敏感用戶,可能會選擇小規模故障不能影響讀寫,而高延遲、高吞吐集羣就能夠接受停讀寫。

五 思考

因爲分佈式存儲系統的複雜性和篇幅所限,本文僅選擇有限個典型場景進行了分析和討論, 真實的分佈式存儲系統遠比這數個案例複雜的多、細節的多。如何平衡集羣異常自動化處理和引入的複雜度,如何較好的實現流控和避免影響低延遲用戶的響應時間,如何引導集羣進行負載均衡和避免因負載均衡帶來的過量集羣資源開銷,這類問題在真實的分佈式存儲系統設計中層出不窮。若是設計者是你,你會如何取捨呢?

相關文章
相關標籤/搜索