1.zk service什么情況下不可用?
2.zk寫數據,什么時候才算完成?
3.zk讀數據可以在任意一台zk節點上,為什么?
4.zk znode有哪些類型?
帶着這些問題走進zookeeper吧。。。
zk service網絡結構
zookeeper的工作集群可以簡單分成兩類,一個是Leader,唯一一個,其余的都是follower,如何確定Leader是通過內部選舉確定的。
Leader和各個follower是互相通信的,對於zk系統的數據都是保存在內存里面的,同樣也會備份一份在磁盤上。對於每個zk節點而言,可以看做每個zk節點的命名空間是一樣的,也就是有同樣的數據(下面的樹結構)
- 如果Leader掛了,zk集群會重新選舉,在毫秒級別就會重新選舉出一個Leaer
- 集群中除非有一半以上的zk節點掛了,zk service才不可用。
zk命名空間結構
zk的命名空間就是zk應用的文件系統,它和linux的文件系統很像,也是樹狀,這樣就可以確定每個路徑都是唯一的,對於命名空間的操作必須都是絕對路 徑操作。與linux文件系統不同的是,linux文件系統有目錄和文件的區別,而zk統一叫做znode,一個znode節點可以包含子znode,同 時也可以包含數據。
比如/Nginx/conf,/是一個znode,/Nginx是/的子znode,/Nginx還可以包含數據,數據內容就是 所有安裝Nginx的機器IP,/Nginx/conf是/Nginx子znode,它也可以包含內容,數據就是Nginx的配置文件內容。在應用中,我 們可以通過這樣一個路徑就可以獲得所有安裝Nginx的機器IP列表,還可以獲得這些機器上Nginx的配置文件。
zk讀寫數據
- 寫數據,一個客戶端進行寫數據請求時,會指定zk集群中節點,如果是follower接收到寫請求,就會把請求轉發給 Leader,Leader通過內部的Zab協議進行原子廣播,直到所有zk節點都成功寫了數據后(內存同步以及磁盤更新),這次寫請求算是完成,然后 zk service就會給client發回響應
- 讀數據,因為集群中所有的zk節點都呈現一個同樣的命名空間視圖(就是結構數據),上面的寫請求已經保證了寫一次數據必須保證集群所有的zk節點都是同步命名空間的,所以讀的時候可以在任意一台zk節點上
- ps:其實寫數據的時候不是要保證所有zk節點都寫完才響應,而是保證一半以上的節點寫完了就把這次變更更新到內存,並且當做最新命名空 間的應用。所以在讀數據的時候可能會讀到不是最新的zk節點,這時候只能通過sync()解決。這里先不考慮了,假設整個zk service都是同步meta信息的,后面的文章再討論。
zk znode類型
zk中znode的節點創建時候是可以指定類型的,主要有下面幾種類型。
- PERSISTENT:持久化znode節點,一旦創建這個znode點存儲的數據不會主動消失,除非是客戶端主動的delete。
- SEQUENCE:順序增加編號znode節點,比如ClientA去zk service上建立一個znode名字叫做/Nginx/conf,指定了這種類型的節點后zk會創建/Nginx /conf0000000000,ClientB再去創建就是創建/Nginx/conf0000000001,ClientC是創建/Nginx /conf0000000002,以后任意Client來創建這個znode都會得到一個比當前zk命名空間最大znode編號+1的znode,也就說 任意一個Client去創建znode都是保證得到的znode是遞增的,而且是唯一的。
- EPHEMERAL:臨時znode節點,Client連接到zk service的時候會建立一個session,之后用這個zk連接實例創建該類型的znode,一旦Client關閉了zk的連接,服務器就會清除 session,然后這個session建立的znode節點都會從命名空間消失。總結就是,這個類型的znode的生命周期是和Client建立的連接 一樣的。比如ClientA創建了一個EPHEMERAL的/Nginx/conf0000000011的znode節點,一旦ClientA的zk連接 關閉,這個znode節點就會消失。整個zk service命名空間里就會刪除這個znode節點。
- PERSISTENT|SEQUENTIAL:順序自動編號的znode節點,這種znoe節點會根據當前已近存在的znode節點編號自動加 1,而且不會隨session斷開而消失。
- EPHEMERAL|SEQUENTIAL:臨時自動編號節點,znode節點編號會自動增加,但是會隨session消失而消失