摘要:Heroku的問題讓咱們意識到,在負載均衡測試時發現問題並妥善解決的成功經驗有沒有?因而,挖掘出「淘寶在雙十一壓測OB時發現存在嚴重的隨機訪問致使負載不均問題,並經過加權算法妥善解決」的成功案例,也就是本文。算法
在CSDN雲計算頻道日前所作的文章《響應高達6秒 用戶揭露Heroku私自修改路由形成高支出》中,網友們認爲這是「因隨機調度+Rails的單線程處理致使延遲增長的負載均衡失敗的案例」。但在負載均衡測試時就能發現問題並妥善解決的成功經驗有沒有?在隨後的微博中,支付寶的@Leverly評論:「去年雙11前的壓測OB就發現了存在嚴重的隨機訪問致使負載不均問題,還好經過加權算法很好的解決了。」 引起了咱們的關注,因而有了本文。重點是淘寶在「雙十一」背後,OceanBase分佈式系統負載均衡的經驗分享。數據庫
雲計算所具有的低成本、高性能、高可用性、高可擴展性等特色與互聯網應用日益面臨的挑戰不謀而合,成爲近年來互聯網領域的熱門話題。做爲一名技術人員不難理解在雲計算的底層架構中,分佈式存儲是不可或缺的重要組成部分。國外知名的互聯網公司如Google、Amazon、Facebook、Microsoft、Yahoo等都推出了各自的分佈式存儲系統,在國內OceanBase是淘寶自主研發的一個支持海量數據的高性能分佈式數據庫系統,實現了數千億條記錄、數百TB數據上的跨行跨表事務[1]。緩存
在分佈式系統中存在着著名的「短板理論」[2],一個集羣若是出現了負載不均衡問題,那麼負載最大的機器每每將成爲影響系統總體表現的瓶頸和短板。爲了不這種狀況的發生,須要動態負載均衡機制,以達到實時的最大化資源利用率,從而提高系統總體的吞吐。在此我向你們推薦一個架構學習交流圈。交流學習企鵝圈號:948368769 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多性能優化
本文將結合OceanBase的實際應用和你們分享一個去年淘寶雙十一前期的準備工做中遇到負載均衡相關案例,拋磚引玉,指望對你們的工做有所啓發。服務器
OceanBase是一個具備自治功能的分佈式存儲系統,由中心節點RootServer、靜態數據節點ChunkServer、動態數據節點UpdateServer以及數據合併節點MergeServer四個Server構成[1],如圖1所示。網絡
Tablet:分片數據,最基本的存儲單元,通常會存儲多份,一個Table由多個tablet構成;架構
RootServer:負責集羣機器的管理、Tablet定位、數據負載均衡、Schema等元數據管理等。併發
UpdateServer:負責存儲動態更新數據,存儲介質爲內存和SSD,對外提供寫服務;負載均衡
ChunkServer:負責存儲靜態Tablet數據,存儲介質爲普通磁盤或者SSD。分佈式
MergeServer:負責對查詢中涉及多個Tablet數據進行合併,對外提供讀服務;
在一個集羣中,Tablet的多個副本分別存儲在不一樣的ChunkServer,每一個ChunkServer負責一部分Tablet分片數據,MergeServer和ChunkServer通常會一塊兒部署。
雙十一前期準備
對於淘寶的大部分應用而言,「雙十一」就是一年一度的一次線上壓測。伴隨流量不斷刷新着歷史新高,對每一個系統的可擴展性提出了很大的挑戰。爲了迎戰雙十一各產品線對有可能成爲瓶頸部分的流量進行預估和擴容成爲刻不容緩的任務。在本文要分享的案例中,應用方根據歷史數據預估讀請求的訪問峯值爲7w QPS,約爲平時的5-6倍,合計天天支持56億次的讀請求。當時OceanBase集羣部署規模是36臺服務器,存儲總數據量爲200億行記錄,天天支持24億次的讀請求。
當前集羣的讀取性能遠不能知足需求,咱們首先進行了一次擴容,上線了10臺Chunkserver/Mergeserver服務器。因爲OceanBase自己具備比較強的可擴展性,爲集羣加機器是一件很是簡單的操做。中心節點Rootserver在新機器註冊上線後,會啓動Rebalance功能以Tablet爲單位對靜態數據進行數據遷移,見下圖的示意,最終達到全部ChunkServer上數據分片的均衡分佈。
擴容完成後引入線上流量回放機制進行壓力測試,以驗證當前集羣的性能是否能夠知足應用的雙十一需求。咱們使用了10臺服務器,共2000-4000個線程併發回放線上讀流量對集羣進行壓測,很快發現集羣總體的QPS在達到4萬左右後,壓測客戶端出現大量超時現象,平均響應延遲已經超過閾值100ms,即便不斷調整壓力,系統的總體QPS也沒有任何增大。此時觀察整個集羣機器的負載狀態發現只有極個別服務器的負載超高,是其餘機器的4倍左右,其餘機器基本處於空閒狀態,CPU、網絡、磁盤IO都凸現了嚴重的不均衡問題。
負載不均衡致使了總體的吞吐取決於負載最高的那臺Server,這正是前文提到的典型 「短板理論」問題。
客戶端鏈接到OceanBase以後一次讀請求的讀流程以下圖所示:
Client 從RootServer獲取到MergeServer 列表;
Client將請求發送到某一臺MergeServer;
MergeServer從RootServer獲取請求對應的ChunkServer位置信息;
MergeServer將請求按照Tablet拆分紅多個子請求發送到對應的ChunkServer;
ChunkServer向UpdateServer請求最新的動態數據,與靜態數據進行合併;
MergeServer合併全部子請求的數據,返回給Client;
OceanBase的讀請求流程看起來如此複雜,實際上第1步和第3步中Client與RootServer以及MergeServer與RootServer的兩次交互會利用緩存機制來避免,即提升了效率,同時也極大下降了RootServer的負載。
分析以上的流程可知,在第2步客戶端選擇MergeServer時若是調度不均衡會致使某臺MergeServer機器過載;在第4步MergeServer把子請求發送到數據所在的ChunkServer時,因爲每一個tablet會有多個副本,選擇副本的策略若是不均衡也會形成ChunkServer機器過載。因爲集羣部署會在同一臺機器會同時啓動ChunkServer和MergeServer,沒法簡單區分過載的模塊。經過查看OceanBase內部各模塊的提供的監控信息好比QPS、Cache命中率、磁盤IO數量等,發現負載不均問題是由第二個調度問題引起,即MergeServer對ChunkServer的訪問出現了不均衡致使了部分ChunkServer的過載。
ChunkServer是存儲靜態Tablet分片數據的節點,分析其負載不均的緣由包含以下可能:
數據不均衡: ChunkServer上數據大小的分佈是不均衡的,好比某些節點由於存儲Tablet分片數據量多少的差別性而形成的不均衡;
流量不均衡:數據即便是基本均衡的狀況下,仍然會由於某些節點存在數據熱點等緣由而形成流量是不均衡的。
經過對RootServer管理的全部tablet數據分片所在位置信息Metadata進行統計,咱們發現各個ChunkServer上的tablet數據量差別不大,這同時也說明擴容加入新的Server以後,集羣的Rebalance是有效的(後來咱們在其餘應用的集羣也發現了存在數據不均衡問題,本文暫不解釋)。
儘管排除了數據不均衡問題,流量不均衡又存在以下的幾種可能性:
存在訪問熱點:好比熱銷的商品,這些熱點數據會致使ChunkServer成爲訪問熱點,形成了負載不均;
請求差別性較大:系統負載和處理請求所耗費的CPUMemory磁盤IO資源成正比,而資源的耗費通常又和處理的數據量是成正比的,便可能是由於存在某些大用戶而致使沒有數據訪問熱點的狀況下,負載仍然是不均衡的。
通過如上的分析至少已經肯定ChunkServer流量不均衡問題和步驟4緊密相關的,而目前所採用的tablet副本選擇的策略是隨機法。通常而言隨機化的負載均衡策略簡單、高效、無狀態,結合業務場景的特色進行分析,熱點數據所佔的比例並不會過高,把ChunkServer上的Tablet按照訪問次數進行統計也發現並無超乎想象的「大熱點」,基本服從正太分佈。在此我向你們推薦一個架構學習交流圈。交流學習企鵝圈號:948368769 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
可見熱點Tablet雖訪問頻率稍高對負載的貢獻率相對較大,可是熱點tablet的佔比很低,相反全部非熱點tablet對負載的貢獻率總和仍是很高的,這種狀況就比如「長尾效應」[3]。
若是把熱點ChunkServer上非熱點Tablet的訪問調度到其餘Server,是能夠緩解流量不均問題的,所以咱們設計了新的負載均衡算法爲:以實時統計的ChunkServer上全部tablet的訪問次數爲Ticket,每次對Tablet的讀請求會選擇副本中得票率最低的ChunkServer。
同時考慮到流量不均衡的第二個緣由是請求的差別較大問題,ChunkServer對外提供的接口分爲Get和Scan兩種,Scan是掃描一個範圍的全部行數據,Get是獲取指定一行數據,所以兩種訪問方式的次數須要劃分賦予不一樣的權重(α,β)參與最終Ticket的運算:
除此以外,簡單的區分兩種訪問模式仍是遠遠不夠的,不一樣的Scan佔用的資源也是存在較大差別的,引入平均響應時間(avg_time)這個重要因素也是十分必要的:
負載均衡算法要求具備自適應性和強的實時性,一方面新的訪問要實時累積參與下次的負載均衡的調度,另外一方面歷史權重數據則須要根據統計週期進行非線性的衰減(y 衰減因子),減小對實時性的影響:
採用新的算法後,很好的緩解了負載不均衡的問題,總體負載提高了1倍,總體QPS吞吐提高到了8w。
負載均衡問題是老生常談的問題,解決很差就會出現「短板效應」,更甚至引起分佈式系統中的連鎖反應即「雪崩」,從而演化成系統的災難。負載均衡的算法也層出不窮,有的出於成本最優,有的是爲了最小延遲,有的則是最大化系統吞吐,目的不一樣算法天然各異,不存在包治百病的良方,並非越複雜的算法越有效[4],要綜合考慮算法所需數據獲取的Overhead,更多的是遵循「簡單實用」的法則,根據業務場景進行分析和嘗試。
正是這種靈活性的策略,對咱們的系統設計提出了新的需求,要有必定的機制來監控和驗證問題:好比能夠實時獲取系統運行的各類內部狀態和數據,容許選擇不一樣負載均衡算法進行試驗等。