Zookeeper請求處理原理分析


Zookeeper是可以存儲數據的,所以我們可以把它理解一個數據庫,實際上它的底層原理本身也和數據庫是類似的。

一、數據庫的原理

我們知道,數據庫是用來存儲數據的,只是數據可以存儲在內存中或磁盤中。而Zookeeper實際是結合了這兩種的,Zookeeper中的數據即會存儲在磁盤中以達到持久化的目的,也會同步到內存中以到達快速訪問的目的。

事實上,用過Zookeeper的同學應該知道,Zookeeper中有兩種類型的節點:持久化節點和臨時節點。

  • 持久化節點:會持久化在磁盤中,除非主動刪除,將一直存在。

  • 臨時節點:不會持久化在磁盤中,只會存儲在內存中,創建這個臨時節點的Session一旦過期,此臨時節點也將自動被刪除。

二、數據庫處理數據的原理

作為一個數據庫,肯定是要接收客戶端創建、修改、刪除、查詢節點等請求的。

在Zookeeper中對於請求分為兩類:

  • 事務性請求

  • 非事務性請求

1、事務性請求

Zookeeper通常都是以集群模式運行的,也就是Zookeeper集群中各個節點的數據需要保持一致的。但是和Mysql集群不一樣的是:

  • Mysql集群中,從服務器是異步從主服務器同步數據的,這中間的間隔時間可以比較長。

  • Zookeeper集群中,當某一個集群節點接收到一個寫請求操作時,該節點需要將這個寫請求操作發送給其他節點,以使其他節點同步執行這個寫請求操作,從而達到各個節點上的數據保持一致,也就是數據一致性。我們通常說Zookeeper保證CAP理論中的CP就只這個意思。

Zookeeper集群底層是怎么保證數據一致性的,其實是用的兩階段提交+過半機制來保證的。

事務性請求包括:更新操作、新增操作、刪除操作,結合上面的分析,因為這些操作是會影響數據的,所以要保證這些操作在整個集群內的事務性,所以這些操作就是事務性請求。

2、非事務性請求

那么非事務性請求就好理解的,像查詢操作、exist操作這些不影響數據的操場,就不需要集群來保持事務性,所以這些操場就是非事務性請求。

Zookeeper在處理事務性請求時,比處理非事務性請求要復雜很多

三、數據在磁盤中的表示

假設我們現在在Zookeeper中有一個數據節點,節點名為/datanode,內容為125,該節點是持久化節點,所以該節點信息會保存在文件中。

可能大家都會認為是類似下面這樣方式保存在磁盤文件中的,方法一:

但是除開這種表示方法,還有另外一種表示方法,快照+事務日志,比如方法二:

當前快照:

當前事務日志:

乍一看方法二比方法一要更復雜,並且占用的磁盤更多。但是我們上文提到過,Zookeeper集群中的節點在處理事務性請求時,需要將事務操作同步給其他節點,所以這里的事務操作是一定要進行持久化的,以便在同步給其他節點時出現異常進行補償。所以就出現了事務日志。實際上事務日志還運行數據進行回滾,這個在兩階段提交中也是非常重要的。

那么快照又有什么用呢?事務日志一定要有,但是隨着時間的推移,日志肯定會越來越多,所以肯定不能持久化歷史上所有的日志,所以Zookeeper會定時的進行快照,並刪除之前的日志。

那么如果按方法二這么存儲數據,在對數據進行查詢時就不太方便了。上文說到,Zookeeper為了提高數據的查詢速度,會在內存中也存儲一份數據,那么內存中的這份數據又該怎么存呢?

四、數據在內存中的表示

Zookeeper中的數據在內存中的表示其實和上文的方法一很類似,只是Zookeeper中的數據是具有文件目錄特點的,說白了就是Zookeeper中的數據節點的名字一定要以“/”開頭,這樣就導致Zookeeper中的數據類似一顆樹:

 

一顆具有父子層級的多叉樹,在Zookeeper源碼中叫DataTree。

五、請求處理邏輯

請看下圖:

請注意,對於上圖,Zookeeper真正的底層實現,zk1是Leader,zk2和zk3是Learner,是根據領導者選舉選出來的。

非事務性請求直接讀取DataTree上的內容,DataTree是在內存中的,所以會非常快。

六、總結

這篇文章介紹了Zookeeper在處理請求時的幾個核心概念:

1、事務性請求

2、事務日志

3、快照

4、DataTree

5、兩階段提交

今天分享一套系統的zookeeper學習視頻,java系統學習必備,值得大家參考學習,希望能對你有幫助!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM