Eurake和Zookeeper作爲服務註冊中心的區別 以及CAP原則如何理解

CAP原則

  • C: Consistency 一致性
  • A: Available 可用性
  • P: Partition Tolerance 分區容錯性
怎麼理解CAP原則
如果我們的系統是分佈式部署,節點之間組成的網絡應該是連通的,然而可能額因爲一些問題導致網路無法連通,
這樣整個網絡就分成了幾塊區域,這時候就形成了分區,

如果你的一些數據在一個節點中保存,因爲網絡導致分區,沒辦法和其他的分區的實例進行信息同步,導致其他分區沒有此數據項,
那麼訪問其他分區的時候就沒辦法訪問到這個數據了,這個時候分區是無法令人容忍的,

提高分區容忍的辦法就是 節點之間要進行數據同步,那麼出現分區之後 其他分區上的節點也有這些數據項,就可以被訪問到

然而,把數據同步到多個節點的時候就會帶來一致性問題,就是可能多個節點上的數據可能不一致,要保證一致性,
就要確保每次在進行寫操作的時候,所有節點都要等待所有節點寫成功,然而這個等待又會帶來可用性問題。

總的來說:數據存在的節點越多,分區容忍性越高,要複製更新的數據就越多,數據的一致性就越難得到保證,
同步數據到所有節點的耗時就越長,可用性就會越低。

綜上我們可以看到:在分佈式系統中,P也就是分區容錯性是必須保證的。

Zookeeper 和Eurake的區別

結論:

Zookeeper 遵循CP原則
Eurake 遵循AP原則

Eurake

Eurake 是遵循的AP原則,爲了保證分區容忍,eurake實例之間會進行信息同步,從而保證集羣中的eurake實例都能提供相同的服務,
因爲Eurake集羣的實例之間採用的是Peer to Peer通信,這是一種對等的機制,不像zookeeper是一種主從機制,這是一種
去中心化的架構,任何一個eurake實例宕機都不會影響別的實例正常工作,這保證了Eurake的可用性,

而且我們知道 Eurake的Client端會在本地緩存 服務列表,而且本地緩存的服務列表的更新是通過心跳進行定時更新的,
所以即使服務註冊中心出現了問題,Eurake客戶端依然可以通過本地的緩存信息調用服務,所以Eurake的可用性很高。

Zookeeper

Zookeeper 是遵循CP原則,我們知道Zookeeper集羣中的實例主要分爲三種角色:

Leader:集羣中有且僅有一個leader,通過選舉產生,負責所有事務的寫操作(寫請求),保證事務處理的順序性,以及更新系統狀態,
默認支持讀請求

Follower:處理客戶端的非事務請求(讀請求),將事務請求(寫請求)轉發給leader進行處理,參與“過半通過”的投票選主策略

Observer:只處理客戶端的讀請求,從而在不影響集羣寫性能的前提下提升集羣的讀性能,不參與投票選主

Zookeeper服務器的三種狀態:

  • looking 當server不知道主是誰的時候正在進行搜尋的時候的狀態
  • leading 當前server爲leader時,負責協調事務 即 Leasder’
  • following leader已經選舉出來,當前server與之同步,即Follower
  • observing observer的狀態,當前服務器即observer
    zookeeper處理事務請求
上圖顯示了,zookeeper是如何解決寫請求的,我們知道寫請求是會影響數據狀態的,所以zookeeper是通過一個類似於兩階段提交的方式完成的,
步驟如下:

1. 首先Follower將接收到的寫請求轉發給Leader,Leader採取兩階段提交的方式,本地生成對應這個事務的zxid,
   生成proposal(上圖拼寫錯誤,中文:提議)日誌(持久化),廣播這個事務給所有的Follower

2. Follower在收到事務之後,會返回Proposal ACK給Leader,Leader會有一個線程專門收集Proposal ACK,
    Leader這時候的角色就是協調者

3. Leader根據收回來的Proposal ACK的數量,如果過半,就廣播commit,並把這個request丟到每個zk實例的CommitProcessor
    裏面進行處理

因爲寫是個事務操作,所以在zookeeper裏面要麼成功 要麼執行失敗,沒有第三種狀態,

上面的操作體現了zookeeper的一致性操作,

Zookeeper的同步機制,保證了分區容忍性。 所以Zookeeper是遵循CP原則。

如果Zookeeper集羣因爲網絡問題出現了分區, 那麼無法和Leader進行通訊,這些分區裏面的zk實例就會被拋棄掉,
無法進行寫請求的轉發給zookeeper,導致不可用。

而且還有另外一種情況就是Leader宕機之後,進行投票選舉,這個過程可能需要大概30-120秒的時間,
這個期間集羣都是不可用的。尤其是在雲環境中,因爲網絡問題導致節點宕機可能性很高。

所以Zookeeper的可用性是沒辦法進行保證的。

思考:對於一個服務註冊中心來說什麼是最重要的?

可用性是最應該被保證的。

Zookeeper的集羣選主

選主的數據結構:
id:被推舉的Leader的SID。

zxid:每次zk進行寫請求,該id都會遞增,被推舉的Leader事務ID。

electionEpoch:邏輯時鐘,用來判斷多個投票是否在同一輪選舉週期中,該值在服務端是一個自增序列,一次選舉會自增1,不是一輪投票自增1。

state:當前服務器的狀態。

  • 全新集羣選主
    全新的5臺服務器啓動,按照服務器配置文件中配置的myid啓動後,選舉過程如下:
    1啓動,id爲1,因爲只有它自己,所以他一直處於looking狀態.
    2啓動,id爲2,此時1,2可以進行報文交流,由於兩者都是全新的,**所以id較大的服務器2勝出,**但是由於沒有超過半數,所以兩者還都是looking狀態.
    3.啓動, id爲3,此時1,2,3都可以進行交流,由於三者都是全新的,**所以id較大的服務器3勝出,**此時有三臺服務器,此時投票數超過服務器數量的一半,所以3爲Leader,進入leading狀態,1,2爲Follower,進入following狀態.
    4.啓動,理論上id爲4的服務器id最大,但是前面已經選主成功發,所以只能是follower.
    5.啓動,同id4一樣。
  • 非全新集羣選主
    首先electionEpoch會自增1
    然後初始化投票,每臺服務器都會初始化自己的投票(Sid,Zxid,electionEpoch,state)
    大家都會投自己(Sid,Zxid,electionEpoch,state),然後進行廣播,每個服務器都會接收到所有的廣播消息,然後進行內部投票,
    收到廣播消息後:
    1. 首先判斷electionEpoch:
    如果自己的electionEpoch較小,則更新electionEpoch到一致,然後清空收到的投票,投出自己的初始化票,
    如果自己的electionEpoch較大,清空收到的投票,投出自己的初始化票
    如果一致,則進行PK
    PK如下:
    如果Zxid比自己的初始化的Zxid大,則選這個Zxid較大的爲自己的投票。
    如果Zxid和自己的一樣大,那麼比較Sid,Sid較大的爲自己的投票。
    然後所有ZK節點將自己的投票再進行一次廣播,統計大家的投票,超過總實例的一半即爲主。
    如果不滿足超過一半,則繼續投,直至選出爲止。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章