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