高并發(fā)整體可用性:大規(guī)模集群下的分片管理策略
大規(guī)模系統(tǒng)的分片部署是一個難點,既要考慮容災和故障轉移,又要考慮負載均衡和資源利用率。本文就從服務狀態(tài)、故障轉移、負載及資源利用率等幾個方面來闡述下他們的關系,并帶大家一起看下,facebook面對這種挑戰(zhàn)是怎么做系統(tǒng)架構的~
1有狀態(tài)&無狀態(tài)的服務部署
應用服務,根據(jù)其類型一般可以分為兩種:無狀態(tài)服務 和 有狀態(tài)服務
無狀態(tài)的服務,擴展起來其實比較容易,用流量路由等負載均衡方式即可實現(xiàn);
但是有狀態(tài)服務不太容易,讓所有服務器一直能夠持有全部數(shù)據(jù)時不現(xiàn)實的。
-- 散列是一種方案 --
如一致性散列策略,將數(shù)據(jù)散列部署。但是,一致性散列會存在一些不可避免的問題,主要有數(shù)據(jù)傾斜、數(shù)據(jù)漂移等。雖然我們可以通過將某節(jié)點的一部分數(shù)據(jù)移到其他節(jié)點來解決,但這需要非常細粒度的負載統(tǒng)計標尺來進行發(fā)現(xiàn)和衡量。
來源:百度百科
另外,由于一致性散列對多數(shù)據(jù)中心的支持不太友好,比如,希望讓某些區(qū)域的用戶走特定數(shù)據(jù)中心,以降低延遲的話,用該策略不好實現(xiàn)。
-- 分片是另一種方案 --
其目的是支持業(yè)務增長、應對系統(tǒng)的高并發(fā)及吞吐量。并且加載和使用更加靈活。
來源:fb engineering
數(shù)以萬計、億計的數(shù)據(jù)分散存儲在多個數(shù)據(jù)庫實例中,則每個實例都叫一個分片。另外,為了容錯,每個分片都可以有多個副本,而每個副本根據(jù)不同的一致性要求可以分為主副本和從副本。
然后,分片又通過多種策略規(guī)范,顯示計算出到服務器的映射,以向用戶提供完整的服務。這些策略規(guī)范包括:不同用戶ID選擇不同的服務分區(qū)、不同地理位置的請求分散到較近的數(shù)據(jù)中心等等。
從這個要求來看,分片的方式要比散列更靈活,更適用大型服務部署。
2故障是一種常態(tài)
在分布式環(huán)境下,我們對故障需要有清晰的認知--故障的發(fā)生不應該被當成是小概率事件,而應該被當成一種常態(tài)。
這也是系統(tǒng)設計應該遵守的一個前提條件。這樣系統(tǒng)才有可能更加穩(wěn)固。
所以,服務的容錯能力、從故障中恢復的能力,是實現(xiàn)服務高可用的關鍵。
那可以有哪些措施呢?
-- 復制 --
數(shù)據(jù)、服務的冗余部署,是提高容錯能力的常用手段。比如服務主備和數(shù)據(jù)庫主從。
但是有些情況下,這種方式是可以打商量的。如果單個容錯域的故障會導致所有冗余副本宕機,那復制還有啥作用?
-- 自動檢測 & 故障轉移 --
想要高可用,故障的發(fā)現(xiàn)和自動檢測機制是前提。然后才是故障轉移。
故障轉移的快慢,決定了程序的可用性高低。那么,所有的故障都必須立馬進行轉移才能達到最好的效果么?
也不竟然。
如果新副本的構建成本非常大呢?比如要加載龐大的數(shù)據(jù)量資源等等,指不定還沒構建完,原故障機器就恢復了說不定。
-- 故障轉移限流 --
一個服務掛了不是最可怕的,最可怕的是它能把全鏈路都帶崩。就比如上一篇文章中寫的《Zookeeper引發(fā)的全鏈路崩潰》一樣,級聯(lián)問題,絕對不容小覷!
因此,在進行故障轉移時,要給予這個問題足夠的重視,以免引發(fā)正常服務在脈沖流量下崩盤。
3資源是寶貴的,不浪費才最好
就算是阿里的財大氣粗,每個季度也會有運維同學和業(yè)務同學,因為1%的CPU利用率,在服務容器數(shù)量分配上來回博弈好多次。
業(yè)務同學當然是想機器越多越好,因為機器越多,單節(jié)點的故障幾率就可以小些;
而運維同學的任務則是盡可能提高資源利用率。畢竟有那么多要買718、911的。。。不都得錢么~
-- 負載均衡 --
負載均衡是指在應用服務器之間持續(xù)均勻地分布分片及其工作負載的過程。它可以有效地利用資源,避免熱點。
- 異構的硬件。由于硬件規(guī)格不同,服務所能承載的壓力也不盡相同,因此需要考慮硬件限制來分配負載。
- 動態(tài)資源。比如可用的磁盤空間、空閑的CPU等,如果負載和這些動態(tài)資源綁定,那么不同的時間點,服務負載是不能一概而論的。
-- 彈性擴展 --
很多時候,我們的很多應用都是為用戶提供服務的。而用戶的行為隨著作息呈現(xiàn)一定的規(guī)律性,如白天的訪問量大,晚上的訪問量小。
因此,彈性計算其實是在不影響可靠性的前提下提高資源效率的一種解決方案,即根據(jù)負載變化動態(tài)調(diào)整資源分配。
4Facebook怎么平衡上述訴求[1]
我們平常見到,其實不同的團隊有不同的分片管理策略。比如,本地生活有一套自己的外賣服務分片的管理容災方案、大文娛也有一套自己視頻服務的分片管理。
facebook早期也是如此。不同團隊間各有各的方案,但是這些方案都更偏重于解決故障轉移,保障系統(tǒng)可用性,對負載均衡考慮較少。
這樣的方式,其實對集團資源利用率、操作性上有些不適合?;谶@樣的考慮,facebook設計了一個通用的分片管理平臺Shard Manager,簡稱 SM 。。。
距今,已經(jīng)有成百上千的應用程序被構建或遷移到分片管理器上,在幾十萬的服務器上構建出總計超過千萬的分片副本。。。
那么,我們來一起看下,他們是怎么做的。
1、基礎架構分層設計
facebook基礎設施架構
Host management: 即主機管理,使用資源配額系統(tǒng),管理所有物理服務器,并給各團隊分配容量。
Container management: 每個團隊從下層獲取到容量后,以容器為單位將其分配給各個應用程序。
Shard management: 在下層提供的容器內(nèi)為分片應用程序分配分片。
Sharded applications: 在每個分片中,應用程序分配并運行相關的工作負載。
Products: 上層應用程序。
2、Shard Management整體架構
來源:fb engineering
應用程序實現(xiàn)分片狀態(tài)轉換接口(該接口由SM library定義,由應用程序實現(xiàn)),并根據(jù)調(diào)度程序的調(diào)用進行狀態(tài)轉換。
應用程序向 ZooKeeper 上報服務器成員資格和活動狀態(tài)。由Shard Manager Scheduler 收集應用程序監(jiān)測的自身動態(tài)負載信息。
Shard Manager Scheduler 是協(xié)調(diào)分片轉換和移動的中央服務。它收集應用程序狀態(tài);監(jiān)控服務器加入、服務器故障和負載變化等狀態(tài)變化;通過對應用程序服務器的RPC調(diào)用來驅動分片狀態(tài)轉換,從而實現(xiàn)分片分配的調(diào)整。
Shard Manager Scheduler 將分片分配的公共視圖發(fā)布到服務發(fā)現(xiàn)系統(tǒng)(該系統(tǒng)保障了自己的高可用和可擴展);
服務發(fā)現(xiàn)系統(tǒng)將信息傳遞到應用程序的客戶端用于計算請求路由。
那么,Shard Manager Scheduler掛了怎么辦呢?
一是,其內(nèi)部可以進行分片擴展,來保證其高可用;
二是,由上述設計可知,中央處理程序不在客戶端調(diào)用的關鍵路徑上,即使掛了,應用程序還是可以以現(xiàn)有的分片來執(zhí)行運轉,業(yè)務不會受中央處理器宕機的影響。
3、標準化分片管理
為了實現(xiàn)上述架構,facebook定義了幾個原語:
- //分片加載
- status add_shard(shard_id)
- //分片刪除
- status drop_shard(shard_id)
- //主從切換
- status change_role(shard_id, primary <-> secondary)
- //驗證和變更副本成員關系
- status update_membership(shard_id, [m1, m2, ...])
- //客戶端路由計算和直連調(diào)用
- rpc_client create_rpc_client(app_name, shard_id)
- rpc_client.execute(args)
根據(jù)上述原語,通過組合,即可以合成高級分片移動協(xié)議:
如,我們希望將將分片A,從當前負載較高的服務器A,移動到負載較低的服務器B:
- Status status= A.drop_share(xx);
- if(status == success){
- B.add_share(xx)
- }
不僅是普通服務,對于主從切換、paxos協(xié)議的服務管理也可以用上述原語滿足,有興趣的同學可以自己試試組合一下,這個對我們工作中的系統(tǒng)設計時非常有幫助的。
那么,針對文章前半部分涉及到的一些分片管理的難點和問題,facebook在該架構下是怎么應對的呢?
對于容錯中的復制,Shard Manager允許在每個分片上配置復制因子,以實現(xiàn)合理的復制策略,如果不需要復制,則可以通過復制因子來控制;
對于故障轉移,Shard Manager通過配置故障轉移延遲策略,來權衡新副本的構建成本和服務的不可用時間;
對于故障節(jié)流,Shard Manager支持限制分片故障轉移速度,來保護其余健康服務器不會被沖垮;
對于負載均衡,Shard Manager支持根據(jù)硬件規(guī)格定制負載因子;通過定期收集應用程序每個副本的負載,來實現(xiàn)各實例間的平衡;并支持多資源平衡,確保短板資源可用。
對于彈性,Shard Manager支持分片縮放和擴展,針對不同流量實行不同的擴展速率。
參考資料
[1]fb engineering: "使用ShardManager擴展服務"