歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100)
週一至週五早8點半!精品技術文章準時送上!
億級流量架構專欄:
- 億級流量系統架構之如何支撐百億級資料的儲存與計算
- 億級流量系統架構之如何設計高容錯分散式計算系統
- 億級流量系統架構之如何設計承載百億流量的高效能架構【敬請期待】
- 億級流量系統架構之如何設計每秒數十萬查詢的高併發架構【敬請期待】
- 億級流量系統架構之如何設計全鏈路99.99%高可用架構【敬請期待】
一、寫在前面
上篇文章《大型系統架構演進之如何支撐百億級資料的儲存與計算》,聊了一下商家資料平臺第一個階段的架構演進。通過離線與實時計算鏈路的拆分,離線計算的增量計算優化,實時計算的滑動時間視窗計算引擎,分庫分表 + 讀寫分離,等各種技術手段,支撐住了百億量級的資料量的儲存與計算。
我們先來回看一下當時的那個架構圖,然後繼續聊聊這套架構在面對高併發、高可用、高效能等各種技術挑戰下,應該如何繼續演進。
二、active-standby高可用架構
大家看看上面的那個架構圖,有沒有發現裡面有一個比較致命的問題?就是如何避免系統單點故障!
在最初的部署架構下,因為資料平臺系統對CPU、記憶體、磁碟的要求很高,所以我們是單機部署在一臺較高配置的虛擬機器上的,16核CPU、64G記憶體、SSD固態硬碟。這個機器的配置是可以保證資料平臺系統在高負載之下正常執行的。
但是如果僅僅是單機部署資料平臺系統的話,會導致致命的單點故障問題,也就是如果單臺機器上部署的資料平臺系統當機的話,就會立馬導致整套系統崩潰。
因此在初期的階段,我們對資料平臺實現了active-standby的高可用架構,也就是一共部署在兩臺機器上,但是同一時間只有一臺機器是會執行的,但是另外一臺機器是備用的。處於active狀態的系統會將滑動視窗計算引擎的計算狀態和結果寫入zookeeper中,作為後設資料儲存起來。
關於後設資料基於zookeeper來儲存,我們是充分參考了開源的Storm流式計算引擎的架構實現,因為Storm作為一個非常優秀的分散式流式計算系統,同樣需要高併發的讀寫大量的計算中間狀態和資料,他就是基於zookeeper來進行儲存的。
本身zookeeper的讀寫效能非常的高,而且zookeeper叢集自身就可以做到非常高的可用性,同時還提供了大量的分散式系統需要的功能支援,包括分散式鎖、分散式協調、master選舉、主備切換等等。
因此基於zookeeper我們實現了active-standby的主備自動切換,如果active節點當機,那麼standby節點感知到,會自動切花為active,同時自動讀取他們共享的一個計算引擎的中間狀態,然後繼續恢復之前的計算。
大家看下面的圖,一起感受一下。
在完成上述的active-standby架構之後,肯定是消除掉了系統的單點故障了,保證了基本的可用性。而且在實際的線上生產環境中表現還不錯,一年系統總有個幾次會出現故障,但是每次都能自動切換standby機器穩定執行。
這裡隨便給大家舉幾個生產環境機器故障的例子,因為部署在公司的雲環境中,用的都是虛擬機器,可能遇到的坑爹故障包括但不限於下面幾種情況:
- 虛擬機器所在的宿主機掛了
- 虛擬機器的網路出現故障
- 負載過高導致磁碟壞了
所以線上上高負載環境中,永遠別寄希望於機器永遠不當機,你要隨時做好準備,機器會掛!系統必須做好充分的故障預測、高可用架構以及故障演練,保證各種場景下都可以繼續執行。
三、Master-Slave架構的分散式計算系統
但是此時另外一個問題又來了,大家考慮一個問題,資料平臺系統其實最核心的任務就是對一個一個的時間視窗中的資料進行計算,但是隨著每天的日增資料量越來越多,每個時間視窗內的資料量也會越來越大,同時會導致資料平臺系統的計算負載越來越高。
線上上生產環境表現出來的情況就是,資料平臺系統部署機器的CPU負載越來越高,高峰期很容易會100%,機器壓力較大。新一輪的系統重構,勢在必行。
首先我們將資料平臺系統徹底重構和設計為一套分散式的計算系統,將任務排程與任務計算兩個職責進行分離,有一個專門的Master節點負責讀取切分好的資料分片(也就是所謂的時間視窗,一個視窗就是一個資料分片),然後將各個資料分片的計算任務分發給多個Slave節點。
Slave節點的任務就是專門接收一個一個的計算任務,每個計算任務就是對一個資料分片執行一個幾百行到上千行的複雜SQL語句來產出對應的資料分析結果。
同時對Master節點,我們為了避免其出現單點故障,所以還是沿用了之前的Active-Standby架構,Master節點是線上上部署一主一備的,平時都是active節點運作,一旦當機,standby節點會切換為active節點,然後自動排程執行各個計算任務。
這套架構部署上線之後,效果還是很不錯的,因為Master節點其實就是讀取資料分片,然後為每個資料分片構造計算任務,接著就是將計算任務分發給各個Slave節點進行計算。
Master節點幾乎沒有太多複雜的任務,部署一臺高配置的機器就絕對沒問題。
負載主要在Slave節點,而Slave節點因為部署了多臺機器,每臺機器就是執行部分計算任務,所以很大程度上降低了單臺Slave節點的負載,而且只要有需要,隨時可以對Slave叢集進行擴容部署更多的機器,這樣無論計算任務有多繁忙,都可以不斷的擴容,保證單臺Slave機器的負載不會過高。
四、彈性計算資源排程機制
在解決了單臺機器計算負載壓力過高的問題之後,我們又遇到了下一個問題,就是線上上生產環境中偶爾會發現某個計算任務耗時過長,導致某臺Slave機器積壓了大量的計算任務一直遲遲得不到處理。
這個問題的產生,其實主要是由於系統的高峰和低谷的資料差異導致的。
大家可以想想,在高峰期,瞬時湧入的資料量很大,很可能某個資料分片包含的資料量過大,達到普通資料分片的幾倍甚至幾十倍,這是原因之一。
還有一個原因,因為截止到目前為止的計算操作,其實還是基於幾百行到上千行的複雜SQL落地到MySQL從庫中去執行計算的。
因此,在高峰期可能MySQL從庫所在資料庫伺服器的CPU負載、IO負載都會非常的高,導致SQL執行效能下降數倍,這個時候資料分片裡的資料量又大,執行的又慢,很容易就會導致某個計算任務執行時間過長。
最後一個造成負載不均衡的原因,就是每個計算任務對應一個資料分片和一個SQL,但是不同的SQL執行效率不同,有的SQL可能只要200毫秒就可以結束,有的SQL要1秒,所以不同的SQL執行效率不同,造成了不同的計算任務的執行時間的不同。
因此,我們又專門在Master節點中加入了計算任務metrics上報、計算任務耗時預估、任務執行狀態監控、機器資源管理、彈性資源排程等機制。
實現的一個效果大致就是:
- Master節點會實時感知到各個機器的計算任務執行情況、排隊負載壓力、資源使用等情況。
- 同時還會收集各個機器的計算任務的歷史metrics
- 接著會根據計算任務的歷史metrics、預估當前計算任務的耗時、綜合考慮當前各Slave機器的負載,來將任務分發給負載較低的Slave機器。
通過這套機制,我們充分保證了線上Slave叢集資源的均衡利用,不會出現單臺機器負載過高,計算任務排隊時間過長的情況,經過生產環境的落地實踐以及一些優化之後,該機制執行良好。
五、分散式系統高容錯機制
其實一旦將系統重構為分散式系統架構之後,就可能會出現各種各樣的問題,此時就需要開發一整套的容錯機制。
大體說起來的話,這套系統目前線上上生產環境可能產生的問題包括但不限於:
- 某個Slave節點在執行過程中突然當機
- 某個計算任務執行時間過長
- 某個計算任務執行失敗
因此,Master節點內需要實現一套針對Slave節點計算任務排程的容錯機制,大體思路如下:
- Master節點會監控各個計算任務的執行狀態,同時也會監控各個Slave節點的執行狀態
- 如果說某個Slave當機了,那麼此時Master就會將那個Slave沒執行完的計算任務重新分配給其他的Slave節點
- 如果說某個Slave的計算任務執行失敗了,同時重試幾次之後還是失敗,那麼Master會將這個計算任務重新分配給其他的Slave節點來執行
- 如果說某個計算任務在多個Slave中無法成功計算的話,此時會將這個計算任務儲存在一個延時記憶體佇列中,間隔一段時間過後,比如說等待高峰期故去,然後再重新嘗試執行這個計算任務
- 如果某個計算任務等待很長時間都沒成功執行,可能是hang死了,那麼Master節點會更新這個計算任務的版本號,然後分配計算任務給其他的Slave節點來執行。
- 之所以要更新版本號,是為了避免說,新分配的Slave執行完畢寫入結果之後,之前的那個Slave hang死了一段時間恢復了,接著將計算結果寫入儲存覆蓋正確的結果。用版本號機制可以避免這種情況的發生。
六、階段性總結
系統架構到這個程度為止,其實在當時而言是執行的相當不錯的,每日億級的請求以及資料場景下,這套系統架構都能承載的很好,如果寫資料庫併發更高可以隨時加更多的主庫,如果讀併發過高可以隨時加更多的從庫,同時單表資料量過大了就分更多的表,Slave計算節點也可以隨時按需擴容。
計算效能也是可以在這個請求量級和資料量級下保持很高的水準,因為資料分片計算引擎(滑動視窗)可以保證計算效能在秒級完成。同時各個Slave計算節點的負載都可以通過彈性資源排程機制保持的非常的均衡。
另外整套分散式系統還實現了高可用以及高容錯的機制,Master節點是Active-Standby架構可以自動故障轉移,Slave節點任何故障都會被Master節點感知到同時自動重試計算任務。
七、下一個階段的展望
其實如果僅僅只是每天億級的流量請求過來,這套架構是可以撐住了,但是問題是,隨之接踵而來的,就是每天請求流量開始達到數十億次甚至百億級的請求量,此時上面那套架構又開始支撐不住了,需要繼續重構和演進系統架構。
END
下一篇文章,會給大家聊聊:《億級流量系統架構之如何設計承載百億流量的高效能架構》,敬請期待。
敬請期待:
《億級流量系統架構之如何設計高容錯分散式計算系統》
《億級流量系統架構之如何設計承載百億流量的高效能架構》
《億級流量系統架構之如何設計每秒數十萬查詢的高併發架構》
《億級流量系統架構之如何設計全鏈路99.99%高可用架構》
如有收穫,請幫忙轉發,您的鼓勵是作者最大的動力,謝謝!
一大波微服務、分散式、高併發、高可用的原創系列
文章正在路上,歡迎掃描下方二維碼,持續關注:
石杉的架構筆記(id:shishan100)
十餘年BAT架構經驗傾囊相授
推薦閱讀:
2、【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?
3、【效能優化之道】每秒上萬併發下的Spring Cloud引數優化實戰
6、大規模叢集下Hadoop NameNode如何承載每秒上千次的高併發訪問
7、【效能優化的祕密】Hadoop如何將TB級大檔案的上傳效能優化上百倍
8、拜託,面試請不要再問我TCC分散式事務的實現原理坑爹呀!
9、【坑爹呀!】最終一致性分散式事務如何保障實際生產中99.99%高可用?