zookeeper 的介紹以及c api的使用

1、zookeeper 的安裝與配置:

1.zookeeper安裝

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

安裝: 解壓 便可java

安裝C 語言 api:node

進入./zookeeper/src/c目錄數據庫

./configureexpress

makeapache

make installapi

 

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。

2、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 拒絕。

 

3、zookeeper原理機制

1.文件系統

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

 

 

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

有四種類型的znode:

一、PERSISTENT-持久化目錄節點

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

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

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

三、EPHEMERAL-臨時目錄節點

客戶端與zookeeper斷開鏈接後,該節點被刪除

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

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

2.通知機制

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

Zookeeper 的watch函數時一次性觸發的,即一 個watch事件將會在數據發生變動時發送給客戶端。例如,若是客戶端執行操做getData(「/znode1″, true),然後 /znode1 發生變動或是刪除了,客戶端都會獲得一個  /znode1 的watch事件。若是  /znode1 再次發生變動,則在客戶端沒有設置新的watch的狀況下,是不會再給這個客戶端發送watch事件的。

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

4、使用場景

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;};

相關文章
相關標籤/搜索