不懂 Zookeeper?沒關係,看這篇就夠了

前言

高併發分佈式開發技術體系已然非常的龐大,從國內互聯網企業使用情況,可發現RPC、Dubbo、ZK是最基礎的技能要求。關於Zookeeper你是不是還停留在Dubbo註冊中心的印象中呢?還有它的工作原理呢?經典應用場景呢?對前面三個問題,如若回答時沒有自己的思路或者說並未瞭解,那麼我覺得我可以幫助到你去入門,並深化這些知識,讓你在面試中更好地去回答。

話不多說進入正題

1. 併發環境下面臨的挑戰

回憶我們學多線程的時候,網上有個圖也是十分的有意思

不懂 Zookeeper?沒關係,看這篇就夠了

其實我們把線程換成進程,相當於每臺服務上跑了一個程序,相同的應用程序運行於多個服務器集群上,是為了解決單臺服務面對高併發處理不來的情況。而嘗試去處理這些情況,我們就會面臨很多諸如此類的問題

比如說我們現在是3臺服務器的一個集群, 怎麼保證所有機器共享的配置信息保持一致?

有一臺機器掛掉了,其他機器如何感知到這一變化並接管任務?

用戶量突然的爆增,需要增加機器來緩解壓力,如何做到不重啟集群而完成機器的添加?

分佈式系統,怎麼高效協同多臺服務對同一網絡文件進行寫操作(網絡並不是即時的,它並不可靠,存在延時)?

此時我們就需要一個類似於線程協同機制的能讓進程進行協同的工具

2. Zookeeper的介紹

① Zookeeper的名字由來

在apache上的許多開源項目都是以動物形象作為icon,比如tomcat就是一隻貓,hive是隻黃蜂等,zookeeper的工作就是把這些動物的行動進行協調

② Zookeeper的簡介

zookeeper就是一種用於分佈式應用程序的高性能協調服務,它的特點就是數據是存於內存中的,持久化實現在日誌中。它的內存類似於樹形結構,且高吞吐低延遲,可以幫助我們實現分佈式統一配置中心,服務註冊,分佈式鎖等 組成ZooKeeper服務的服務器必須彼此瞭解。它們維護內存中的狀態圖像,以及持久性存儲中的事務日誌和快照。只要大多數服務器可用,ZooKeeper服務就可用。客戶端連接到單個ZooKeeper服務器。客戶端維護TCP連接,通過該連接發送請求,獲取響應,獲取監視事件以及發送tick。如果與服務器的TCP連接中斷,則客戶端將連接到其他服務器。

③ Zookeeper的安裝(linux下)

<code>1.JDK版本需要在1.6以上
2.下載:https://archive.apache.org/dist/zookeeper/zookeeper-3.5.2/zookeeper-3.5.2.tar.gz
3.解壓後的conf目錄,增加配置文件zoo.cfg
4.啟動服務端 bin/zkServer.sh start
5.測試,客戶端連接:bin/zkCli.sh -server 127.0.0.1:2181
zoo.cfg的關鍵配置有3個:
tickTime=2000:一次心跳的基本時間,
dataDir:數據與日誌的存放處
clientPort:端口號/<code>

④ Zookeeper的特點

1.數據結構簡單

類似於Unix文件系統樹形結構,每個目錄成為Znode節點,但它不同於文件系統,它既可以視為文件夾,也可以視為文件來存放數據,但是我們平時還是得叫它節點,別叫文件夾這麼掉價。

需要注意:同一個節點下的子節點名稱不能相同,且命名是有規範的,它的路徑是沒有相對路徑的概念的,都是絕對路徑,任何開始都以"/"開始,最後就是,它存放數據的大小是有限制的

2.數據模型特點

層次命名空間:就是上面已經提到的,類似於unix的文件系統,以"/"為根,節點可以包含關聯數據和子節點,絕對路徑 Znode:名稱唯一,命名有規範,類型分4種:持久,順序,臨時,臨時順序,節點的數據構成之後再提

3.命名規範

節點名稱除下列限制外,可以使用任何unicode字符:

<code>1. null字符(\\\\u0000)不能作為路徑名的一部分;

2. 以下字符不能使用,因為它們不能很好地顯示,或者以令人困惑的方式呈現:\\\\u0001 - \\\\u0019和\\\\u007F - \\\\u009F。


3. 不允許使用以下字符:\\\\ud800 - uf8fff, \\\\uFFF0 - uFFFF。

4. “.”字符可以用作另一個名稱的一部分,但是“.”和“..”不能單獨用於指示路徑上的節點,因為ZooKeeper不使用相對路徑。

下列內容無效:“/a/b/. / c”或“c / a / b / . . /”。

5. “zookeeper”是保留節點名。/<code>

4.一些命令

因為我的電腦是window系統的,所以我找了一個window版本的zookeeper來進行演示

先大致解釋一下各個目錄的內容

<code>bin ---> 包括了linux和window的運行程序的運行目錄
conf ---> zookeeper的配置zoo.cfg
contrib ---> 其他一些組件和發行版本
dist-maven ---> maven發佈下的一些jar包
docs ---> 文檔
lib ---> 庫
recipe ---> 一些應用實例
src ---> zookeeper的源碼,因為zookeeper是java寫出來的/<code>

啟動bin目錄下的zkServer.cmd,再啟動zkClient.cmd即可,在我根本不知道該如何進行學習的時候,一般來說輸入help,-help,-h這些指令就可以獲取到幫助,下圖我就是在客戶端輸入了-help指令

不懂 Zookeeper?沒關係,看這篇就夠了

因為命令都相對簡單所以也不進行演示了,唯一需要注意的是要注意路徑"/"的問題,比如 ls / 就是根目錄,create /zk 123,還有各個命令的依託條件,比如create必須要提供父節點,delete節點時次節點不能有子節點等···

5.Zookeeper的重要特點---有序

提供多種方式跟蹤時間,ZooKeeper給每個更新貼上一個數字,這個數字反映了所有ZooKeeper事務的順序,嚴格的順序意味著可以在客戶機上實現複雜的同步原語 解釋czxid、version、zoo.cfg中ticks配置

  • Zxid :Zookeeper中每次寫請求都對應一個唯一的事務id,稱為 Zxid,它是全局的且有序的,如果 Zxid1 小於 Zxid2,那 Zxid1 就一定是發生在 Zxid2 前
  • version numbers :版本號,對節點的寫請求都會導致該節點的3種版本號增加(其實套路和樂觀鎖差不多),dataVersion(對znode數據的更改次數),cversion(對znode子節點的更改次數),aclVersion(對znode ACL的更改次數
  • ticks :當使用多服務器Zookeeper時,服務器使用一個“滴答”來定義事件的時間,如狀態上傳,會話超時等,它通過最小會話超時(默認是滴答時間x2)間接公開,如果客戶端請求超過這個時間,那客戶端就不再能連接上服務器端
  • real time:Zookeeper並不使用真實時間

你可以使用stat path或者ls2來查看這些信息

不懂 Zookeeper?沒關係,看這篇就夠了

<code>cZxid:創建該節點的zxid
ctime:該節點的創建時間
mZxid:該節點的最後修改zxid
mtime:該節點的最後修改時間
pZxid:該節點的最後子節點修改zxid
cversion:該節點的子節點變更次數

dataVersion:該節點數據被修改的次數
aclVersion:該節點的ACL變更次數
aphemeraOwner:臨時節點所有者會話id,非臨時的為0
dataLength:該節點數據長度
numChildren:子節點數

/<code>

這些數據都在從側面告訴我們,zookeeper是一個協調者

6.zookeeper的第二個特點---可複製

數據可複製,可備份。zookeeper可以快速地搭建一個集群,內部自帶了這樣的一些工具與機制,我們只需要設置一些配置即可,保證服務可靠,不會成為單點故障

不懂 Zookeeper?沒關係,看這篇就夠了

7.zookeeper的第三個特點---迅速

zookeeper的一些特點可以應用於大型分佈式系統

不懂 Zookeeper?沒關係,看這篇就夠了

3.zookeeper的理論

① zookeeper的會話機制

不懂 Zookeeper?沒關係,看這篇就夠了

Session會話

<code>1.一個客戶端連接一個會話,由zookeeper分配唯一會話id
2.客戶端以特定的時間間隔發送心跳以保持會話有效,
3.超過會話超時時間未收到客戶端的心跳,則判斷客戶端無效(默認2倍tickTime)
4.會話中額請求是FIFO(先進先出原則)的順序執行

/<code>

② znode的數據構成

<code>節點數據:存儲的基本信息(狀態,配置,位置等)
節點元數據:stat命令下的一些數據
數據大小:限制1M

/<code>

③ znode的節點類型

<code>1.持久節點:直接通過create path value所創建
2.臨時節點:create -e path value
3.順序節點:create -s path value

注意
1.session會話失效時,臨時節點就會被刪除
2.順序節點的創建,後為10位十進制序號,每個父節點擁有一個計數器,這個計數器也是有限制的,到2147483647之後將溢出

3.順序節點在會話結束仍然存在

/<code>

④ Watch監聽機制

客戶端能在znodes上設置watch,監聽znode的變化,包括增刪改查,通過stat path ,ls2 path get path皆可查看

觸發watch事件的條件有4種,create,delete,change,child(子節點事件)

watch的重要特性

<code>1.僅一次性:watch觸發後會立即刪除,要持續監聽變化的話就要持續提供設置watch,這也是watch的注意事項

2.有序性:客戶端先得到watch通知才可查看變化結果

/<code>

watch的注意事項

<code>1.剛剛提及到的它的僅一次性

2.獲取事件和發送watch,獲取watch,這些請求有可能存在延時,所以不能絕對可靠得到每個節點發生的每個更改

3.一個watch對象只會被通知一次,如果一個watch同時註冊了多個接口(exists,getData),如果此時刪除節點,雖然這個事件對exists和getData都有效,但是watch只會被調用一次

/<code>

阻塞線程喚醒機制—客戶端可以被動接受其他客戶端進程狀態通知

⑤ zookeeper的特性

<code> 1.順序一致性(Sequential Consistency),保證客戶端操作是按順序生效的;

2.原子性(Atomicity),更新成功或失敗。沒有部分結果。

3.單個系統映像,無論連接到哪個服務器,客戶端都將看到相同的內容

4.可靠性,數據的變更不會丟失,除非被客戶端覆蓋修改。

5.及時性,保證系統的客戶端當時讀取到的數據是最新的。

/<code>

finally

通過上面的闡述應該我們對於zookeeper有了一個初步的認識,之後會陸續說說分佈式鎖,集群還有一些場景的應用


分享到:


相關文章: