系統越來越大後切分出的模組越來越多,一些模組還部署了雙機。配置檔案混亂,更新部署極易出錯,準備上 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 Guide、ZK 配置項詳解、ZK 配置檔案 或 ZK 管理員指南。
Java API
zk 官方的Java API是非常難用的,建議使用第三方基於官方API封裝的工具包。
- Netflix curator:http://github.com/Netflix/curator(強大)
- sgroschupf zkclient:http://github.com/sgroschupf/zkclient(簡單)
- adyliu zkclient:http://github.com/adyliu/zkclient(極簡)
看一下官方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。
管理工具
很可惜,沒有順手的,試試下面幾個吧!