高併發服務端分佈式系統設計概要(下)html
上篇 連接地址:http://www.cnblogs.com/ccdev/p/3338412.html算法
中篇 連接地址:http://www.cnblogs.com/ccdev/p/3340484.html瀏覽器
如今接着設計咱們的「山推」系統。有了前面兩篇的鋪墊,咱們的系統如今已經有了五臟六腑,剩下的工做就是要讓其羽翼豐滿。那麼,是時候,放出咱們的「山推」系統全貌了:緩存
前面囉嗦了半天,也許很多同窗看的不明不白,好了,如今開始看圖說話環節:服務器
(1)整個系統由N臺機器組合而成,其中Global Master一臺,Global Slave一臺到多臺,二者之間保持強一致性並徹底同步,可由Global Slave隨時頂替Global Master工做,它們被Global Heartbeat(一臺)來管理,保證有一個Global Master正常工做;Global Heartbeat因爲無壓力,一般認爲其不能掛掉,若是它掛掉了,則必須人工干預才能恢復正常;併發
(2)整個系統由多個groups合成,每個group負責相應業務的數據的存取,它們是數據節點,是真正抗壓力的地方,每個group由一個Group Master和一個到多個Group Slave構成,Group Master做爲該group的主節點,提供讀和寫,而Group Slave則只提供讀服務且保證這些Group Slave節點中,至少有一個和Group Master保持徹底同步,剩餘的Group Slave和Group Master可以達到最終一致,它們之間以「半同步」模式工做保證最終一致性;負載均衡
(3)每個group的健康狀態由Global Master來管理,Global Master向group發送管理信息,並保證有一個Group Master正常工做,若Group Master宕機,在該group內經過分佈式選舉產生新的Group Master頂替原來宕機的機器繼續工做,但仍然有一小段時間須要中斷寫服務來切換新的Group Master;分佈式
(4)每個group的底層是實際的存儲系統,File system,它們是無狀態的,即,由分佈式選舉產生的Group Master能夠在原來的File system上繼續工做;高併發
(5)Client的上端可認爲是Web請求,Client在「首次」進行數據讀寫時,向Global Master查詢相應的group信息,並將其緩存,後續將直接與相應的group進行通訊;爲避免大量「首次」查詢沖垮Global Master,在Client與Global Master之間增長DNS負載均衡,可由Global Slave分擔部分查詢工做;性能
(6)當Client已經擁有足夠的group信息時,它將直接與group通訊進行工做,從而真正的壓力和流量由各個group分擔,並處理完成須要的工做。
好了,如今咱們的「山推」系統設計完成了,可是要將它編碼實現,還有很遠的路要走,細枝末節的問題也會暴露更多。若是該系統用於線上計算,若有大量的Map-Reduce運行於group中,系統將會更復雜,由於此時不光考慮的數據的存儲同步問題,操做也須要同步。如今來檢驗下咱們設計的「山推」系統,主要分佈式指標:
一致性:如前文所述,Global機器強一致性,Group機器最終一致性;
可用性:Global機器保證了HA(高可用性),Group機器則不保證,但知足了分區容錯性;
備份Replication:Global機器採用徹底同步,Group機器則是半同步模式,均可以進行橫向擴展;
故障恢復:如前文所述,Global機器徹底同步,故障可不受中斷由slave恢復工做,但Group機器採用分佈式選舉和最終一致性,故障時有較短期的寫服務須要中斷並切換到slave機器,但讀服務可不中斷。
還有其餘一些指標,這裏就再也不多說了。還有一些細節,須要提一下,好比以前的評論中有同窗提到,group中master掛時,由slave去頂替,但這樣一來該group內其餘全部slave須要分擔以前成這新master的這個slave的壓力,有可能繼續掛掉而形成雪崩。針對此種狀況,可採用以下作法:即在一個group內,至少還存在一個真正作「備份」用途的slave,平時不抗壓力,只同步數據,這樣當出現上述狀況時,可由該備份slave來頂替成爲新master的那個slave,從而避免雪崩效應。不過這樣一來,就有新的問題,因爲備份slave平時不抗壓力,加入抗壓力後必然產生必定的數據遷移,數據遷移也是一個較麻煩的問題。常採用的分攤壓力作法如一致性Hash算法(環狀Hash),可將新結點加入對整個group的影響降到較小的程度。
另外,還有一個較爲棘手的問題,就是系統的日誌處理,主要是系統宕機後如何恢復以前的操做日誌。比較常見的方法是對日誌做快照(Snapshot)和回放點(checkpoint),並採用Copy-on-write方式按期將日誌做snapshot存儲,當發現宕機後,找出對應的回放點並恢復以後的snapshot,但此時仍可能有新的寫操做到達,併產生不一致,這裏主要依靠Copy-on-write來同步。
最後再說說圖中的Client部分。顯然這個模塊就是面向Web的接口,後面鏈接咱們的「山推」系統,它能夠包含諸多業務邏輯,最重要的,是要緩存group的信息。在Client和Web之間,還能夠有諸如Nginx之類的反向代理服務器存在,作進一步性能提高,這已經超出了本文的範疇,但咱們必須明白的是,一個高併發高性能的網站,對性能的要求是從起點開始的,何爲起點,即用戶的瀏覽器。
如今,讓咱們來看看GFS的設計:
很明顯,這麼牛的系統我是設計不出來的,咱們的「山推」,就是在學習GFS + Bigtable的主要思想。說到這,也必須提一句,可能我文章中,名詞擺的有點多了,如NWR,分佈式選舉,Paxos包括Copy-on-write等,有興趣的同窗可自行google瞭解。由於說實在的,這些概念我也無法講透徹,只是只知其一;不知其二。另外,你們可參考一些分佈式項目的設計,如Cassandra,包括淘寶的Oceanbase等,以加深理解。
就寫到這裏算是完結了。因爲寫的比較匆忙,可能包含一些錯誤,但願同窗們不吝賜教!提早祝你們國慶節快樂。