最近再看一個使用ZooKeeper的項目源代碼,用C語言編寫,但是ZooKeeper在C客戶端方面的資料不太多,於是先學習了一下Java版本的客戶端,C版本的客戶端類似,先將這兩天所看到的內容分享如下。
ZooKeeper是一個優秀的分布式協同工具,很多分布式項目都基於它進行架構設計,不過要想要對其有一個深入的理解(如果你想閱讀其源代碼),對其客戶端API的熟悉必不可少。下面就簡要記錄一下ZooKeeper中各個API的簡單用法。
這篇文章不打算對ZooKeeper的基本概念及安裝進行講解,想要了解這部分內容可以參考:http://zookeeper.apache.org/doc/r3.4.3/zookeeperOver.html ,
或者可以參考:http://zookeeper.apache.org/doc/r3.4.3/zookeeperProgrammers.html
均是官方文檔,這也是想要學習某個開源工具必須的先行步驟,並且官網上的文檔也應該算是最權威的,不過ZooKeeper在這方面的文檔不怎麼多,但作為入門了解,還是非常有用的。
下面將從基本用法,Watchert的用法,異步調用以及ACL四個方面對ZooKeeper客戶端編程作簡要介紹。
當完成這四個方面的理解以後,就可以使用ZK完成一些更加高級的任務,如分布式鎖、Master選舉、一致性服務保障、配置管理等。官方文檔對此也有簡要介紹,
參考:http://zookeeper.apache.org/doc/r3.4.3/recipes.html
基本數據結構
- class Stat {
- private long czxid;
- private long mzxid;
- private long ctime;
- private long mtime;
- private int version;
- private int cversion;
- private int aversion;
- private long ephemeralOwner;
- private int dataLength;
- private int numChildren;
- private long pzxid;
- }
- class Id {
- private String scheme; //world、auth、digest、ip
- private String id;
- }
- class ACL {
- private int perms; //CREATE、READ、WRITE、DELETE、ADMIN
- private org.apache.zookeeper.data.Id id;
- }
基本使用
- try {
- static String hostport = "127.0.0.1:2181";
- ZooKeeper zooKeeper = new ZooKeeper(hostport, 300000, null); //創建一個ZooKeeper實例,不設置默認watcher
- String path = "/test";
- zooKeeper.create(path, path.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); //創建一個節點
- Stat stat = new Stat();
- byte[] b = zooKeeper.getData(path, false, stat); //獲取節點的信息及存儲的數據
- System.out.println(stat);
- System.out.println(new String(b));
- stat = zooKeeper.exists(path, false); //查看path所代表的節點是否存在
- zooKeeper.setData(path, "helloworld".getBytes(), stat.getVersion()); //設置節點的數據
- //zooKeeper.delete(path, -1); //刪除節點
- zooKeeper.close(); //關閉實例
- } catch (Exception e) {
- e.printStackTrace();
- }
ZooKeeper通過Auth和ACL完成節點的權限控制。
Auth表示某種認證,由於一個ZooKeeper集群可能被多個項目使用,各個項目屬於不同的項目組,他們在進行開發時肯定不想其他項目訪問與自己相關的節點,這時可以通過為每個項目組分配一個Auth,然後每個項目組先通過Auth認證以後再繼續相關的操作,這樣甲Auth認證的用戶就不能操作其他Auth認證後創建的節點,從而實現各個項目之間的隔離。ZooKeeper提供了如下方法完成認證,如下所示:
Void addAuthInfo(String scheme, byte[] auth) ,使用示例如下:
- @Test
- public void testFirstStep() {
- try {
- zk = new ZooKeeper(hostport, 1000000, null);
-
- String auth_type = "digest";
- String auth = "joey:some";
-
- String p = "/acl_digest";
-
- zk.addAuthInfo(auth_type, auth.getBytes());
-
- zk.create(p, "hello".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
-
- Stat stat = new Stat();
- System.out.println(new String(zk.getData(p, false, stat)));
-
- zk.close();
- } catch(Exception ex) {
- ex.printStackTrace();
- }
- }
- @Test
- public void testSecondStep() {
- String p = "/acl_digest";
-
- try {
- zk = new ZooKeeper(hostport, 1000000, null);
-
- String authType = "digest";
- String badAuth = "joey:someBAD";
-
- zk.addAuthInfo(authType, badAuth.getBytes());
- Stat stat = new Stat();
- System.out.println(new String(zk.getData(p, false, stat)));
- } catch(Exception ex) {
- ex.printStackTrace(); //拋出異常
- } finally {
- try {
- zk.delete(p, -1);
- zk.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
- }
ACL用於控制Znode的訪問,和Unix文件訪問權限類似,提供對某類用戶設置某種權限的能力(如Unix中對Owner提供讀、寫、執行的權限),但是在ZooKeeper中沒有Owner、Group等概念,於是在ZooKeeper中使用ID表示某一類用戶,可以對ID設置某種權限。(ZooKeeper對ID的數量沒有限制,不像Unix文件僅支持三種類型用戶)