zookeeper 的介紹以及使用


一、zookeeper 的安裝與配置:

1.zookeeper安裝

下載:https://zookeeper.apache.org/  建議下載zookeeper 3.4.6穩定版的, 3.5版本的在搭建集群時,會出現服務啟動失敗的錯誤。

安裝: 解壓 即可

安裝C 語言 api:

進入./zookeeper/src/c目錄

./configure

make

make install

 

2.集群配置

Zookeeper 的配置文件在 conf 目錄下,這個目錄下有 zoo_sample.cfg 和 log4j.properties,需要將 zoo_sample.cfg 改名為 zoo.cfg,因為 Zookeeper 在啟動時會找這個文件作為默認配置文件。下面詳細介紹一下,這個配置文件中各個配置項的意義。

 tickTime=2000

 dataDir= /home/zoo/data

 clientPort=2181

  • tickTime:這個時間是作為 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
  • dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日志文件也保存在這個目錄里。
  • clientPort:這個端口就是客戶端連接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。

當這些配置項配置好后,你現在就可以啟動 Zookeeper 了,啟動后要檢查 Zookeeper 是否已經在服務,可以通過 netstat – ano 命令查看是否有你配置的 clientPort 端口號在監聽服務。

集群模式

Zookeeper 不僅可以單機提供服務,同時也支持多機組成集群來提供服務。實際上 Zookeeper 還支持另外一種偽集群的方式,也就是可以在一台物理機上運行多個 Zookeeper 實例,下面將介紹集群模式的安裝和配置。

Zookeeper 的集群模式的安裝和配置也不是很復雜,所要做的就是增加幾個配置項。集群模式除了上面的三個配置項還要增加下面幾個配置項:

 initLimit=5

 syncLimit=2

 server.1=192.168.211.1:2888:3888

 server.2=192.168.211.2:2888:3888

  • initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集群中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是 tickTime)長度后 Zookeeper 服務器還沒有收到客戶端的返回信息,那么表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒
  • syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
  • server.myid=ip:port1:port2:其中 myid 是一個數字,表示這個是第幾號服務器;ip是這個服務器的 ip 地址;port1表示的是這個服務器與集群中的 Leader 服務器交換信息的端口;port2表示的是萬一集群中的 Leader 服務器掛了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。如果是偽集群的配置方式,由於 ip 都是一樣,所以不同的 Zookeeper 實例通信端口號不能一樣,所以要給它們分配不同的端口號。

除了修改 zoo.cfg 配置文件,集群模式下還要配置一個文件 myid,這個文件在 dataDir 目錄下,這個文件里面就有一個數據就是 A 的值,Zookeeper 啟動時會讀取這個文件,拿到里面的數據與 zoo.cfg 里面的配置信息比較從而判斷到底是那個 server。

二、Zookeeper的使用:

1.服務端的啟動:

進入/bin目錄,使用./zkServer.sh start 啟動zookeeper服務。 使用./zkServer.sh stop 停止服務。./zkServer.sh status 查看服務狀態 (leader or follower).

2.客戶端命令的使用:

進入/bin目錄下,使用 ./zkCli.sh –server host:port 登陸服務,例如

./zkCli.sh  -server 192.168.1.91:2181,鍵入任意字符出現以下help命令。

[zk: localhost:2181(CONNECTED) 1] help
ZooKeeper -server host:port cmd args
        connect host:port
        get path [watch]
        ls path [watch]
        set path data [version]
        delquota [-n|-b] path
        quit 
        printwatches on|off
        create [-s] [-e] path data acl
        stat path [watch]
        close 
        ls2 path [watch]
        history 
        listquota path
        setAcl path acl
        getAcl path
        sync path
        redo cmdno
        addauth scheme auth
        delete path [version]
        setquota -n|-b val path

 

  1. create [-s] [-e] path data acl
    其中”-s”表示創建一個順序自動編號的節點,”-e”表示創建一個臨時節點.默認為持久性節點

例如:創建一個持久性節點和臨時節點

[zk: localhost:2181(CONNECTED) 7] create /test null

Created /test

[zk: localhost:2181(CONNECTED) 8] create -e /test0 null

Created /test0

當會話退出,臨時節點將會自動刪除,並且臨時節點無子節點。

關於ACL的設置和使用在下一節單獨介紹。

2.get path [watch]和set path data [version]

get是獲取Znode的數據及相關屬性,而set是修改此Znode的數據.

 

3.ls path [watch]

查看Znode的子節點

 

4.stat path [watch]

查看Znode的屬性

 

5.delete path [version]

刪除Znode,前提若有子節點,先刪除其子節點

 

6.addauth scheme auth

認證授權,若某個節點需要認證后才能查看,就需要此命令,具體見下節。

 

3.ACL 的使用

 傳統的文件系統中,ACL分為兩個維度,一個是屬組,一個是權限,子目錄/文件默認繼承父目錄的ACL。而在Zookeeper中,node的ACL是沒有繼承關系的,是獨立控制的.

多集群共用zookeeper又涉及一個權限隔離的問題。zookeeper本身提供了ACL機制,表示為scheme:id:permissions,第一個字段表示采用哪一種機制,第二個id表示用戶,permissions表示相關權限,如只讀,讀寫,管理等。

scheme: scheme對應於采用哪種方案來進行權限管理,zookeeper實現了一個pluggable的ACL方案,可以通過擴展scheme,來擴展ACL的機制。zookeeper-3.4.4缺省支持下面幾種scheme:

ž   world: 它下面只有一個id, 叫anyone, world:anyone代表任何人,zookeeper中對所有人有權限的結點就是屬於world:anyone的

ž   auth: 它不需要id, 只要是通過authentication的user都有權限(zookeeper支持通過kerberos (http://www.cnblogs.com/jankie/archive/2011/08/22/2149285.html)來進行authencation, 也支持username/password形式的authentication)

ž   digest: 它對應的id為username:BASE64(SHA1(password)),它需要先通過username:password形式的authentication

ž   ip: 它對應的id為客戶機的IP地址,設置的時候可以設置一個ip段,比如ip:192.168.1.0/16, 表示匹配前16個bit的IP段

ž   super: 在這種scheme情況下,對應的id擁有超級權限,可以做任何事情(cdrwa)

  另外,zookeeper-3.4.4的代碼中還提供了對sasl的支持,不過缺省是沒有開啟的,需要配置才能啟用,具體怎么配置在下文中介紹。
       * sasl: sasl的對應的id,是一個通過sasl authentication用戶的id,zookeeper-3.4.4中的sasl authentication是通過kerberos來實現的,也就是說用戶只有通過了kerberos認證,才能訪問它有權限的node.(關於sasl 參考:http://www.wxdl.cn/cloud/zookeeper-sasl.html)

 

id: id與scheme是緊密相關的,具體的情況在上面介紹scheme的過程都已介紹.

 

permission: zookeeper目前支持下面一些權限:

 

權限

描述

備注

CREATE

有創建子節點的權限

 

READ

有讀取節點數據和子節點列表的權限

 

WRITE

有修改節點數據的權限

無創建和刪除子節點的權限

DELETE

有刪除子節點的權限

 

ADMIN

有設置節點權限的權限

 

 

客戶端示例:

  1. create [-s] [-e] path data acl
    create /acl  test world:anyone:rwd

Created  /test

  1. create -s /test/test null digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:rwcda

Created /test/test0000000000

  1. getAcl  /acl  查看路徑的acl信息
  2. setAcl /test digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:r
  3. setAcl /test auth:username:password:crdwa
  4. addauth /<node-name> digest <username>:<password>

 

ACL的原理:

ZooKeeper 的權限管理通過Server、Client 兩端協調完成:

(1) Server

一個ZooKeeper 的節點存儲兩部分內容:數據狀態,狀態中包含ACL 信息。創建一個znode 會產生一個ACL 列表,列表中每個ACL 包括:

 權限perms

 驗證模式scheme

 具體內容expression:Ids

例如,當scheme="digest" 時, Ids 為用戶名密碼, 即"root :J0sTy9BCUKubtK1y8pkbL7qoxSw"。ZooKeeper 提供了如下幾種驗證模式:

 Digest: Client 端由用戶名和密碼驗證,譬如user:pwd

 Host: Client 端由主機名驗證,譬如localhost

 Ip:Client 端由IP 地址驗證,譬如172.2.0.0/24

 World :固定用戶為anyone,為所有Client 端開放權限

 

(2) 客戶端

Client 通過調用addAuthInfo()(java, c為zoo_add_auth)函數設置當前會話的Author信息。Server 收到Client 發送的操作請求除exists、getAcl 之外,需要進行ACL 驗證:對該請求攜帶的Author 明文信息加密,並與目標節點的ACL 信息進行比較,如果匹配則具有相應的權限,否則請求被Server 拒絕。

 

三、zookeeper原理機制

1.文件系統

Zookeeper維護一個類似文件系統的數據結構:

 

 

每個子目錄項如 NameService 都被稱作為 znode,和文件系統一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯一的不同在於znode是可以存儲數據的。

有四種類型的znode:

1、PERSISTENT-持久化目錄節點

客戶端與zookeeper斷開連接后,該節點依舊存在

2、 PERSISTENT_SEQUENTIAL-持久化順序編號目錄節點

客戶端與zookeeper斷開連接后,該節點依舊存在,只是Zookeeper給該節點名稱進行順序編號

3、EPHEMERAL-臨時目錄節點

客戶端與zookeeper斷開連接后,該節點被刪除

4、EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節點

客戶端與zookeeper斷開連接后,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號

2.通知機制

客戶端注冊監聽它關心的目錄節點,當目錄節點發生變化(數據改變、被刪除、子目錄節點增加刪除)時,zookeeper會通知客戶端。

Zookeeper 的watch函數時一次性觸發的,即一 個watch事件將會在數據發生變更時發送給客戶端。例如,如果客戶端執行操作getData(“/znode1″, true),而后 /znode1 發生變更或是刪除了,客戶端都會得到一個  /znode1 的watch事件。如果  /znode1 再次發生變更,則在客戶端沒有設置新的watch的情況下,是不會再給這個客戶端發送watch事件的。

這就是說,一個事件會發送向客戶端,但可能在在操作成功的返回值到達發起變動的客戶端之前,這個事件還沒有送達watch的客戶端。Watch是異步發送 的。但ZooKeeper保證了一個順序:一個客戶端在收到watch事件之前,一定不會看到它設置過watch的值的變動。網絡時延和其他因素可能會導 致不同的客戶端看到watch和更新返回值的時間不同。但關鍵點是,每個客戶端所看到的每件事都是有順序的。

四、使用場景

1.配置同步:

  1. 搭建zookeeper集群,在集群服務器上創建永久節點如:Authorization
  2. 需要更新緩存的客戶機器,連接至集群,並通過zookeeper watch機制對Authorization節點設置watch。
  3. 當數據庫認證信息發生變化時,對 Authorization 節點數據進行更新,從而觸發客戶機的watch 函數,在watch函數中進行更新緩存的操作。

注意事項:

  1. watch 時一次性觸發的,因此在watch函數觸發后,需要重新注冊,從而實現永久監聽。
  2. 由於網絡原因,或者更新操作過於頻繁時,在客戶機處理更新操作,沒有注冊新的watch間隙,數據庫的認證信息發生變化時,這時會出現客戶端緩存和數據庫數據不一致的錯誤,因此,在watch函數結束后,通過再次獲取Authorization的相關信息(程序中使用的是mzxid)與之前的進行比較,若不一致,需要再次進行更新緩存操作。
  3. zookeeper session 失效問題 http://blog.csdn.net/kobejayandy/article/details/26289273當客戶端收到SESSIONEXPIRED狀態信息后,由於之前設置的watch將失效,因此,進行了關閉之前的連接,重新開始連接,並設置watch函數的操作。

2.集群管理

使用zookeeper可以進行集群管理,主要針對兩點

  1. 是否有機器的加入或退出

解決這個問題,可以在約定一個父目錄,gropmember,然后再父目錄下面,每個機器創建臨時節點,並且監聽父目錄的子節點變化消息,一旦有機器退出集群,對應的子節點也將被刪除,其它機器將受到通知。同樣,當加入新的機器時,其它機器也將受到通知。

  1. Master的選舉

Master的選舉與上面的原理大致一致,所有機器創建臨時子節點並按順序編號,每次選擇編號最小的子節點對應的機器作為master即可。

 

另外:

zookeeper 

zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer, 
int* buffer_len, struct Stat *stat);

1.在傳遞參數時,buffer_len 的值是buffer緩沖的大小,當zoo_get成功返回后,buffer_len將被至為對應node節點數據的長度

2.如何確定buffer的大小? 可以設置一個大約值,然后當zoo_get 返回后,從stat結構體中獲取node數據長度,與返回的buffer_len 進行比較,若是不相符,說明緩沖區小了,這時可以拿到正確的長度,再次get即可。

stat結構體:

struct Stat {
    int64_t czxid;
    int64_t mzxid;
    int64_t ctime;
    int64_t mtime;
    int32_t version;
    int32_t cversion;
    int32_t aversion;
    int64_t ephemeralOwner;
    int32_t dataLength;
    int32_t numChildren;
    int64_t pzxid;
};

~~~~~


免責聲明!

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



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