zookeeper 簡介

五柳-先生發表於2015-11-25


系統越來越大後切分出的模組越來越多,一些模組還部署了雙機。配置檔案混亂,更新部署極易出錯,準備上 zookeeper下載當前穩定版的 zookeeper,解壓並拷貝 conf/zoo_sample.cfg 為 zoo.cfg,配置所需要的專案。最少配是隻指定其中的 dataDir 項,其他項則使用預設值。

tickTime=2000        # 心跳基本時間單位,毫秒級,zk基本上所有時間都是這個時間的整數倍
clientPort=2181      # 監聽客戶端連線的埠
dataDir=/zookeeper/server0/data         # 記憶體資料庫快照存放地址
dataLogDir=/zookeeper/server0/dataLog   # 事務日誌存放地址,未指定則同dataDir項,建議分開

主要配置項說明

最小配置

最小配是保證zk正常執行必不可少的配置項。

  • clientPort:監聽客戶端連線的服務埠
  • dataDir:記憶體資料庫快照地址,事務日誌地址(除非由 dataLogDir 另行指定)
  • tickTime:毫秒級的基本時間單位,其他時間如心跳/超時等都為該單位時間的整數倍

建議另行指定 dataLogDir,以便將事務日誌儲存在單獨的路徑下,這很重要,因事物日誌儲存的裝置效率直接影響zk的效能。

高階配置

高階引數是可選的,可以通過這些引數調優zk效能。有些引數還可以通過 java system properties 動態指定,格式為 zookeeper.keyword 。

  • dataLogDir:事務日誌目錄,可以使用專用的裝置,以避免事務日誌與快照之間的競爭。(No Java system property)
  • globalOutstandingLimit:zk接收的請求佇列大小,預設1000,設定太大對導致記憶體溢位。(Java system property: zookeeper.globalOutstandingLimit)
  • preAllocSize:預先分配事務日誌空間塊,單位kb,預設64M。如果快照寫入很頻繁,減少這個值,參考 snapCount。 (Java system property: zookeeper.preAllocSize)
  • snapCount:每當 snapCount 個事物日誌寫入時,快照被建立,同時建立新的事務日誌檔案,預設值100,000。(Java system property: zookeeper.snapCount)

垃圾清理引數

  • autopurge.purgeInterval:清理頻率,單位小時,預設0,表示不開啟清理功能。
  • autopurge.snapRetainCount:需要保留的檔案數目,預設是保留3個。

叢集配置

  • electionAlg:領導選舉演算法,預設3。(No Java system property)
  • initLimit:tickTime的倍數,表示leader選舉結束後,followers與leader同步需要的時間,leader的資料非常多時或followers比較多,則該值應該適當大一些。(No Java system property)
  • syncLimit:tickTime的倍數,表示follower和observer與leader互動時的最大等待時間,只不過是在與leader同步完畢之後,正常請求轉發或ping等訊息互動時的超時時間。(No Java system property)
  • server.x=[hostname]:nnnnn[:nnnnn], etc
    叢集配置中,在dataDir目錄下必須有一個myid檔案,其中的值就是數字x,範圍是1-255。第一個nnnnn是與leader通訊使用,第二個nnnnn是選舉leader使用,electionAlg等於0時不需要此引數。(No Java system property)

叢集配置的例子
conf下的zoo.cfg檔案:

server.1=127.0.0.1:12888:13888
server.2=127.0.0.1:22888:23888
server.3=127.0.0.1:32888:33888

dataDir下的myid檔案:

1

更多引數參考 ZK Administrator’s GuideZK 配置項詳解ZK 配置檔案 或 ZK 管理員指南

Java API

zk 官方的Java API是非常難用的,建議使用第三方基於官方API封裝的工具包。

看一下官方API的主要介面:

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) 
   throws IOException

  • connectString:逗號分隔,如localhost:2181,127.0.0.1:2181,zk會選出一個建立連線
  • sessionTimeout:session超時時間
  • watcher:回撥函式

該方法是非阻塞的,如果需要阻塞,可以在Watcher中自己處理。

public String create(String path, byte data[], List<ACL> acl, CreateMode createMode)
   throws KeeperException, InterruptedException
```        
- path:znode路徑
- data:znode上的資料
- acl:許可權資訊, 如果不想指定許可權, 可傳入org.*.ZooDefs.Ids.OPEN_ACL_UNSAFE。
- createMode:列舉類CreateMode,PERSISTENT / PERSISTENT_SEQUENTIAL / EPHEMERAL / EPHEMERAL_SEQUENTIAL

```java
public List<String> getChildren(final String path, Watcher watcher)
   throws KeeperException, InterruptedException
  • path:znode路徑
  • watcher:回撥函式

監聽 path node 自身的刪除事件,以及 children nodes 的建立/刪除事件。

public Stat exists(final String path, Watcher watcher)
   throws KeeperException, InterruptedException

監聽 path node 自身的建立/刪除/資料更新事件,path 不存在返回 null。

public byte[] getData(final String path, Watcher watcher, Stat stat)
   throws KeeperException, InterruptedException

監聽 path node 的刪除/資料更新事件, 注意, 不監聽 path node 的建立事件。stat 是傳出引數,返回當前節點狀態。

public Stat setData(final String path, byte data[], int version)
   throws KeeperException, InterruptedException

version 引數指定要更新資料的當前版本, 就是stats中的 version 值,如果和現有版本不匹配, 更新操作將失敗。指定 version 為-1則忽略版本檢查。

public void delete(final String path, int version)
   throws InterruptedException, KeeperException

總結:

getChildren, getData, exists 方法可指定是否監聽相應的事件;而create,delete,setData 方法則會觸發相應的事件。

許可權設定

// new一個acl
List<ACL> acls = new ArrayList<ACL>();
// 新增第一個id,採用使用者名稱密碼形式
Id id1 = new Id("digest", DigestAuthenticationProvider.generateDigest("admin:admin"));
ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1);
acls.add(acl1);
// 新增第二個id,所有使用者可讀許可權
Id id2 = new Id("world", "anyone");
ACL acl2 = new ACL(ZooDefs.Perms.READ, id2);
acls.add(acl2);

// zk用admin認證,建立/buru ZNode。
final ZooKeeper zk = new ZooKeeper("localhost:2181,127.0.0.1:2181", 2000, null);
zk.addAuthInfo("digest", "admin:admin".getBytes());

Stat exists = zk.exists("/buru", true);
if (exists != null)
   zk.setData("/buru", "2323".getBytes(), -1);
else
   zk.create("/buru", "data112".getBytes(), acls, CreateMode.PERSISTENT);

更多內容參考文章, ZK 許可權配置ZK ACL使用ZK 許可權控制 或 說說Zookeeper中的ACL

管理工具

很可惜,沒有順手的,試試下面幾個吧!

轉載: http://ibruce.info/2014/10/23/zookeeper/