1. 程式人生 > >高併發服務端分散式系統設計概要(中)

高併發服務端分散式系統設計概要(中)

上篇我們完成了在此分散式系統中,一個group的設計。那麼接下來,我們設計系統的其他部分。如前文所述,我們的業務及其資料以group為單位,顯然在此係統中將存在many many的groups(別告訴我你的網站總共有一個業務,像我們的“山推”,那業務是一堆一堆地),那麼由誰來管理這些groups呢?由Web過來的請求,又將如何到達指定的group,並由該group處理它的請求呢?這就是我們要討論的問題

 我們引入了一個新的角色——Global Master,顧名思義,它是管理全域性的一個節點,它主要完成如下工作:(1)管理系統全域性配置,傳送全域性控制資訊;(2)監控各個group的工作狀態,提供心跳服務,若發現宕機,通知該group發起分散式選舉產生新的Group Master;(3)處理Client端首次到達的請求,找出負責處理該請求的group並將此group的資訊(location)返回,則來自同一個前端請求源的該類業務請求自第二次起不需要再向Global Master查詢group資訊(快取機制);(4)保持和Global Slave的強一致性同步,保持自身健康狀態並向全域性的“心跳”服務驗證自身的狀態。

       現在我們結合圖來逐條解釋上述工作,顯然,這個系統的完整輪廓已經初現。

      

    

首先要明確,不管我們的系統如何“分散式”,總之會有至少一個最主要的節點,術語可稱為primary node,如圖所示,我們的系統中,這個節點叫Global Master,也許讀過GFS + Bigtable論文的同學知道,在GFS + Bigtable裡,這樣的節點叫Config Master,雖然名稱不一樣,但所做的事情卻差不多。這個主要的Global Master可認為是系統狀態健康的標誌之一,只要它在正常工作,那麼基本可以保證整個系統的狀態是基本正常的(什麼?group或其他結點會不正常不工作?前面已經說過,group內會通過“分散式選舉”來保證自己組內的正常工作狀態,不要告訴我group內所有機器都掛掉了,那個概率我想要忽略它),假如Global Master不正常了,掛掉了,怎麼辦?顯然,圖中的Global Slave就派上用場了,在我們設計的這個“山推”系統中,至少有一個Global Slave,和Global Master保持“強一致性”的完全同步,當然,如果有不止一個Global Slave,它們也都和Global Master保持強一致性完全同步,這樣有個好處,假如Global Master掛掉,不用停寫服務,不用進行分散式選舉,更不會讀服務,隨便找一個Global Slave頂替Global Master工作即可。這就是強一致性最大的好處。那麼有的同學就會問,為什麼我們之前的group,不能這麼搞,非要搞什麼最終一致性,搞什麼分散式選舉(Paxos協議屬於既難理解又難實現的坑爹一族)呢?我告訴你,還是壓力,壓力。我們的系統是面向日均千萬級PV以上的網站(“山推”嘛,推特是億級PV,我們千萬級也不過分吧),但系統的壓力主要在哪呢?細心的同學就會發現,系統的壓力並不在Global Master,更不會在Global Slave,因為他們根本不提供資料的讀寫服務!是的,系統的壓力正是在各個group,所以group的設計才是最關鍵的。同時,細心的同學也發現了,由於Global Master存放的是各個group的資訊和狀態,而不是使用者存取的資料,所以它更新較少,也不能認為讀>>寫,這是不成立的,所以,Global Slave和Global Master保持強一致性完全同步,正是最好的選擇。所以我們的系統,一臺Global Master和一臺Global Slave,暫時可以滿足需求了。

 好,我們繼續。現在已經瞭解Global Master的大概用途,那麼,一個來自Client端的請求,如何到達真正的業務group去呢?在這裡,Global Master將提供“首次查詢”服務,即,新請求首次請求指定的group時,通過Global Master獲得相應的group的資訊,以後,Client將使用該資訊直接嘗試訪問對應的group並提交請求,如果group資訊已過期或是不正確,group將拒絕處理該請求並讓Client重新向Global Master請求新的group資訊。顯然,我們的系統要求Client端快取group的資訊,避免多次重複地向Global Master查詢group資訊。這裡其實又挖了許多爛坑等著我們去跳,首先,這樣的工作模式滿足基本的Ddos攻擊條件,這得通過其他安全性措施來解決,避免group總是收到不正確的Client請求而拒絕為其服務;其次,當出現大量“首次”訪問時,Global Master儘管只提供查詢group資訊的讀服務,仍有可能不堪重負而掛掉,所以,這裡仍有很大的優化空間,比較容易想到的就是採用DNS負載均衡,因為Global Master和其Global Slave保持完全同步,所以DNS負載均衡可以有效地解決“首次”查詢時Global Master的壓力問題;再者,這個工作模式要求Client端快取由Global Master查詢得到的group的資訊,萬一Client不快取怎麼辦?呵呵,不用擔心,Client端的API也是由我們設計的,之後才面向Web前端。

之後要說的,就是圖中的“Global Heartbeat”,這又是個什麼東西呢?可認為這是一個管理Global Master和Global Slave的節點,Global Master和各個Global Slave都不停向Global Heartbeat競爭成為Global Master,如果Global Master正常工作,定期更新其狀態並延期其獲得的鎖,否則由Global Slave替換之,原理和group內的“心跳”一樣,但不同的是,此處Global Master和Global Slave是強一致性的完全同步,不需要分散式選舉。有同學可能又要問了,假如Global Heartbeat掛掉了呢?我只能告訴你,這個很不常見,因為它沒有任何壓力,而且掛掉了必須人工干預才能修復。在GFS + Bigtable裡,這個Global Heartbeat叫做Lock Service。