摘要:Heroku的問(wèn)題讓我們意識(shí)到,在負(fù)載均衡測(cè)試時(shí)發(fā)現(xiàn)問(wèn)題并妥善解決的成功經(jīng)驗(yàn)有沒(méi)有?于是,挖掘出“淘寶在雙十一壓測(cè)OB時(shí)發(fā)現(xiàn)存在嚴(yán)重的隨機(jī)訪問(wèn)導(dǎo)致負(fù)載不均問(wèn)題,并通過(guò)加權(quán)算法妥善解決”的成功案例,也就是本文。
在CSDN云計(jì)算頻道日前所做的文章《響應(yīng)高達(dá)6秒 用戶(hù)揭露Heroku私自修改路由造成高支出》中,網(wǎng)友們認(rèn)為這是“因隨機(jī)調(diào)度+Rails的單線程處理導(dǎo)致延遲增加的負(fù)載均衡失敗的案例”。但在負(fù)載均衡測(cè)試時(shí)就能發(fā)現(xiàn)問(wèn)題并妥善解決的成功經(jīng)驗(yàn)有沒(méi)有?在隨后的微博中,支付寶的@Leverly評(píng)論:“去年雙11前的壓測(cè)OB就發(fā)現(xiàn)了存在嚴(yán)重的隨機(jī)訪問(wèn)導(dǎo)致負(fù)載不均問(wèn)題,還好通過(guò)加權(quán)算法很好的解決了?!?引發(fā)了我們的關(guān)注,于是有了本文。重點(diǎn)是淘寶在“雙十一”背后,OceanBase分布式系統(tǒng)負(fù)載均衡的經(jīng)驗(yàn)分享。
云計(jì)算所具備的低成本、高性能、高可用性、高可擴(kuò)展性等特點(diǎn)與互聯(lián)網(wǎng)應(yīng)用日益面臨的挑戰(zhàn)不謀而合,成為近年來(lái)互聯(lián)網(wǎng)領(lǐng)域的熱門(mén)話(huà)題。作為一名技術(shù)人員不難理解在云計(jì)算的底層架構(gòu)中,分布式存儲(chǔ)是不可或缺的重要組成部分。國(guó)外知名的互聯(lián)網(wǎng)公司如Google、Amazon、Facebook、Microsoft、Yahoo等都推出了各自的分布式存儲(chǔ)系統(tǒng),在國(guó)內(nèi)OceanBase是淘寶自主研發(fā)的一個(gè)支持海量數(shù)據(jù)的高性能分布式數(shù)據(jù)庫(kù)系統(tǒng),實(shí)現(xiàn)了數(shù)千億條記錄、數(shù)百TB數(shù)據(jù)上的跨行跨表事務(wù)[1]。
在分布式系統(tǒng)中存在著著名的“短板理論”[2],一個(gè)集群如果出現(xiàn)了負(fù)載不均衡問(wèn)題,那么負(fù)載最大的機(jī)器往往將成為影響系統(tǒng)整體表現(xiàn)的瓶頸和短板。為了避免這種情況的發(fā)生,需要?jiǎng)討B(tài)負(fù)載均衡機(jī)制,以達(dá)到實(shí)時(shí)的最大化資源利用率,從而提升系統(tǒng)整體的吞吐。在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流圈。交流學(xué)習(xí)企鵝圈號(hào):948368769 里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化、分布式架構(gòu)等這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,目前受益良多
本文將結(jié)合OceanBase的實(shí)際應(yīng)用和大家分享一個(gè)去年淘寶雙十一前期的準(zhǔn)備工作中遇到負(fù)載均衡相關(guān)案例,拋磚引玉,期望對(duì)大家的工作有所啟發(fā)。
OceanBase架構(gòu)介紹
OceanBase是一個(gè)具有自治功能的分布式存儲(chǔ)系統(tǒng),由中心節(jié)點(diǎn)RootServer、靜態(tài)數(shù)據(jù)節(jié)點(diǎn)ChunkServer、動(dòng)態(tài)數(shù)據(jù)節(jié)點(diǎn)UpdateServer以及數(shù)據(jù)合并節(jié)點(diǎn)MergeServer四個(gè)Server構(gòu)成[1],如圖1所示。

?
Tablet:分片數(shù)據(jù),最基本的存儲(chǔ)單元,一般會(huì)存儲(chǔ)多份,一個(gè)Table由多個(gè)tablet構(gòu)成;
RootServer:負(fù)責(zé)集群機(jī)器的管理、Tablet定位、數(shù)據(jù)負(fù)載均衡、Schema等元數(shù)據(jù)管理等。
UpdateServer:負(fù)責(zé)存儲(chǔ)動(dòng)態(tài)更新數(shù)據(jù),存儲(chǔ)介質(zhì)為內(nèi)存和SSD,對(duì)外提供寫(xiě)服務(wù);
ChunkServer:負(fù)責(zé)存儲(chǔ)靜態(tài)Tablet數(shù)據(jù),存儲(chǔ)介質(zhì)為普通磁盤(pán)或者SSD。
MergeServer:負(fù)責(zé)對(duì)查詢(xún)中涉及多個(gè)Tablet數(shù)據(jù)進(jìn)行合并,對(duì)外提供讀服務(wù);
在一個(gè)集群中,Tablet的多個(gè)副本分別存儲(chǔ)在不同的ChunkServer,每個(gè)ChunkServer負(fù)責(zé)一部分Tablet分片數(shù)據(jù),MergeServer和ChunkServer一般會(huì)一起部署。
雙十一前期準(zhǔn)備
對(duì)于淘寶的大部分應(yīng)用而言,“雙十一”就是一年一度的一次線上壓測(cè)。伴隨流量不斷刷新著歷史新高,對(duì)每個(gè)系統(tǒng)的可擴(kuò)展性提出了很大的挑戰(zhàn)。為了迎戰(zhàn)雙十一各產(chǎn)品線對(duì)有可能成為瓶頸部分的流量進(jìn)行預(yù)估和擴(kuò)容成為刻不容緩的任務(wù)。在本文要分享的案例中,應(yīng)用方根據(jù)歷史數(shù)據(jù)預(yù)估讀請(qǐng)求的訪問(wèn)峰值為7w QPS,約為平時(shí)的5-6倍,合計(jì)每天支持56億次的讀請(qǐng)求。當(dāng)時(shí)OceanBase集群部署規(guī)模是36臺(tái)服務(wù)器,存儲(chǔ)總數(shù)據(jù)量為200億行記錄,每天支持24億次的讀請(qǐng)求。
當(dāng)前集群的讀取性能遠(yuǎn)不能滿(mǎn)足需求,我們首先進(jìn)行了一次擴(kuò)容,上線了10臺(tái)Chunkserver/Mergeserver服務(wù)器。由于OceanBase本身具有比較強(qiáng)的可擴(kuò)展性,為集群加機(jī)器是一件非常簡(jiǎn)單的操作。中心節(jié)點(diǎn)Rootserver在新機(jī)器注冊(cè)上線后,會(huì)啟動(dòng)Rebalance功能以Tablet為單位對(duì)靜態(tài)數(shù)據(jù)進(jìn)行數(shù)據(jù)遷移,見(jiàn)下圖的示意,最終達(dá)到所有ChunkServer上數(shù)據(jù)分片的均衡分布。

?

?

?
擴(kuò)容完成后引入線上流量回放機(jī)制進(jìn)行壓力測(cè)試,以驗(yàn)證當(dāng)前集群的性能是否可以滿(mǎn)足應(yīng)用的雙十一需求。我們使用了10臺(tái)服務(wù)器,共2000-4000個(gè)線程并發(fā)回放線上讀流量對(duì)集群進(jìn)行壓測(cè),很快發(fā)現(xiàn)集群整體的QPS在達(dá)到4萬(wàn)左右后,壓測(cè)客戶(hù)端出現(xiàn)大量超時(shí)現(xiàn)象,平均響應(yīng)延遲已經(jīng)超過(guò)閾值100ms,即使不斷調(diào)整壓力,系統(tǒng)的整體QPS也沒(méi)有任何增大。此時(shí)觀察整個(gè)集群機(jī)器的負(fù)載狀態(tài)發(fā)現(xiàn)只有極個(gè)別服務(wù)器的負(fù)載超高,是其他機(jī)器的4倍左右,其他機(jī)器基本處于空閑狀態(tài),CPU、網(wǎng)絡(luò)、磁盤(pán)IO都凸現(xiàn)了嚴(yán)重的不均衡問(wèn)題。
負(fù)載不均衡導(dǎo)致了整體的吞吐取決于負(fù)載最高的那臺(tái)Server,這正是前文提到的典型 “短板理論”問(wèn)題。
負(fù)載不均問(wèn)題跟蹤
客戶(hù)端連接到OceanBase之后一次讀請(qǐng)求的讀流程如下圖所示:

?
Client 從RootServer獲取到MergeServer 列表;
Client將請(qǐng)求發(fā)送到某一臺(tái)MergeServer;
MergeServer從RootServer獲取請(qǐng)求對(duì)應(yīng)的ChunkServer位置信息;
MergeServer將請(qǐng)求按照Tablet拆分成多個(gè)子請(qǐng)求發(fā)送到對(duì)應(yīng)的ChunkServer;
ChunkServer向UpdateServer請(qǐng)求最新的動(dòng)態(tài)數(shù)據(jù),與靜態(tài)數(shù)據(jù)進(jìn)行合并;
MergeServer合并所有子請(qǐng)求的數(shù)據(jù),返回給Client;
OceanBase的讀請(qǐng)求流程看起來(lái)如此復(fù)雜,實(shí)際上第1步和第3步中Client與RootServer以及MergeServer與RootServer的兩次交互會(huì)利用緩存機(jī)制來(lái)避免,即提高了效率,同時(shí)也極大降低了RootServer的負(fù)載。
分析以上的流程可知,在第2步客戶(hù)端選擇MergeServer時(shí)如果調(diào)度不均衡會(huì)導(dǎo)致某臺(tái)MergeServer機(jī)器過(guò)載;在第4步MergeServer把子請(qǐng)求發(fā)送到數(shù)據(jù)所在的ChunkServer時(shí),由于每個(gè)tablet會(huì)有多個(gè)副本,選擇副本的策略如果不均衡也會(huì)造成ChunkServer機(jī)器過(guò)載。由于集群部署會(huì)在同一臺(tái)機(jī)器會(huì)同時(shí)啟動(dòng)ChunkServer和MergeServer,無(wú)法簡(jiǎn)單區(qū)分過(guò)載的模塊。通過(guò)查看OceanBase內(nèi)部各模塊的提供的監(jiān)控信息比如QPS、Cache命中率、磁盤(pán)IO數(shù)量等,發(fā)現(xiàn)負(fù)載不均問(wèn)題是由第二個(gè)調(diào)度問(wèn)題引發(fā),即MergeServer對(duì)ChunkServer的訪問(wèn)出現(xiàn)了不均衡導(dǎo)致了部分ChunkServer的過(guò)載。
ChunkServer是存儲(chǔ)靜態(tài)Tablet分片數(shù)據(jù)的節(jié)點(diǎn),分析其負(fù)載不均的原因包含如下可能:
數(shù)據(jù)不均衡: ChunkServer上數(shù)據(jù)大小的分布是不均衡的,比如某些節(jié)點(diǎn)因?yàn)榇鎯?chǔ)Tablet分片數(shù)據(jù)量多少的差異性而造成的不均衡;
流量不均衡:數(shù)據(jù)即使是基本均衡的情況下,仍然會(huì)因?yàn)槟承┕?jié)點(diǎn)存在數(shù)據(jù)熱點(diǎn)等原因而造成流量是不均衡的。
通過(guò)對(duì)RootServer管理的所有tablet數(shù)據(jù)分片所在位置信息Metadata進(jìn)行統(tǒng)計(jì),我們發(fā)現(xiàn)各個(gè)ChunkServer上的tablet數(shù)據(jù)量差異不大,這同時(shí)也說(shuō)明擴(kuò)容加入新的Server之后,集群的Rebalance是有效的(后來(lái)我們?cè)谄渌麘?yīng)用的集群也發(fā)現(xiàn)了存在數(shù)據(jù)不均衡問(wèn)題,本文暫不解釋?zhuān)?/p>
盡管排除了數(shù)據(jù)不均衡問(wèn)題,流量不均衡又存在如下的幾種可能性:
存在訪問(wèn)熱點(diǎn):比如熱銷(xiāo)的商品,這些熱點(diǎn)數(shù)據(jù)會(huì)導(dǎo)致ChunkServer成為訪問(wèn)熱點(diǎn),造成了負(fù)載不均;
請(qǐng)求差異性較大:系統(tǒng)負(fù)載和處理請(qǐng)求所耗費(fèi)的CPU\Memory\磁盤(pán)IO資源成正比,而資源的耗費(fèi)一般又和處理的數(shù)據(jù)量是成正比的,即可能是因?yàn)榇嬖谀承┐笥脩?hù)而導(dǎo)致沒(méi)有數(shù)據(jù)訪問(wèn)熱點(diǎn)的情況下,負(fù)載仍然是不均衡的。
經(jīng)過(guò)如上的分析至少已經(jīng)確定ChunkServer流量不均衡問(wèn)題和步驟4緊密相關(guān)的,而目前所采用的tablet副本選擇的策略是隨機(jī)法。一般而言隨機(jī)化的負(fù)載均衡策略簡(jiǎn)單、高效、無(wú)狀態(tài),結(jié)合業(yè)務(wù)場(chǎng)景的特點(diǎn)進(jìn)行分析,熱點(diǎn)數(shù)據(jù)所占的比例并不會(huì)太高,把ChunkServer上的Tablet按照訪問(wèn)次數(shù)進(jìn)行統(tǒng)計(jì)也發(fā)現(xiàn)并沒(méi)有超乎想象的“大熱點(diǎn)”,基本服從正太分布。在此我向大家推薦一個(gè)架構(gòu)學(xué)習(xí)交流圈。交流學(xué)習(xí)企鵝圈號(hào):948368769 里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化、分布式架構(gòu)等這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,目前受益良多
可見(jiàn)熱點(diǎn)Tablet雖訪問(wèn)頻率稍高對(duì)負(fù)載的貢獻(xiàn)率相對(duì)較大,但是熱點(diǎn)tablet的占比很低,相反所有非熱點(diǎn)tablet對(duì)負(fù)載的貢獻(xiàn)率總和還是很高的,這種情況就好比“長(zhǎng)尾效應(yīng)”[3]。
負(fù)載均衡算法設(shè)計(jì)
如果把熱點(diǎn)ChunkServer上非熱點(diǎn)Tablet的訪問(wèn)調(diào)度到其他Server,是可以緩解流量不均問(wèn)題的,因此我們?cè)O(shè)計(jì)了新的負(fù)載均衡算法為:以實(shí)時(shí)統(tǒng)計(jì)的ChunkServer上所有tablet的訪問(wèn)次數(shù)為T(mén)icket,每次對(duì)Tablet的讀請(qǐng)求會(huì)選擇副本中得票率最低的ChunkServer。
同時(shí)考慮到流量不均衡的第二個(gè)原因是請(qǐng)求的差異較大問(wèn)題,ChunkServer對(duì)外提供的接口分為Get和Scan兩種,Scan是掃描一個(gè)范圍的所有行數(shù)據(jù),Get是獲取指定一行數(shù)據(jù),因此兩種訪問(wèn)方式的次數(shù)需要?jiǎng)澐仲x予不同的權(quán)重(α,β)參與最終Ticket的運(yùn)算:

?
除此之外,簡(jiǎn)單的區(qū)分兩種訪問(wèn)模式還是遠(yuǎn)遠(yuǎn)不夠的,不同的Scan占用的資源也是存在較大差異的,引入平均響應(yīng)時(shí)間(avg_time)這個(gè)重要因素也是十分必要的:

?
負(fù)載均衡算法要求具有自適應(yīng)性和強(qiáng)的實(shí)時(shí)性,一方面新的訪問(wèn)要實(shí)時(shí)累積參與下次的負(fù)載均衡的調(diào)度,另一方面歷史權(quán)重?cái)?shù)據(jù)則需要根據(jù)統(tǒng)計(jì)周期進(jìn)行非線性的衰減(y 衰減因子),減少對(duì)實(shí)時(shí)性的影響:

?
采用新的算法后,很好的緩解了負(fù)載不均衡的問(wèn)題,整體負(fù)載提升了1倍,整體QPS吞吐提升到了8w。
小結(jié)
負(fù)載均衡問(wèn)題是老生常談的問(wèn)題,解決不好就會(huì)出現(xiàn)“短板效應(yīng)”,更甚至引發(fā)分布式系統(tǒng)中的連鎖反應(yīng)即“雪崩”,從而演化成系統(tǒng)的災(zāi)難。負(fù)載均衡的算法也層出不窮,有的出于成本最優(yōu),有的是為了最小延遲,有的則是最大化系統(tǒng)吞吐,目的不同算法自然各異,不存在包治百病的良方,并不是越復(fù)雜的算法越有效[4],要綜合考慮算法所需數(shù)據(jù)獲取的Overhead,更多的是遵循“簡(jiǎn)單實(shí)用”的法則,根據(jù)業(yè)務(wù)場(chǎng)景進(jìn)行分析和嘗試。
正是這種靈活性的策略,對(duì)我們的系統(tǒng)設(shè)計(jì)提出了新的需求,要有一定的機(jī)制來(lái)監(jiān)控和驗(yàn)證問(wèn)題:比如可以實(shí)時(shí)獲取系統(tǒng)運(yùn)行的各種內(nèi)部狀態(tài)和數(shù)據(jù),允許選擇不同負(fù)載均衡算法進(jìn)行試驗(yàn)等。