在本地模擬搭建zookeeper集群環境實例


先給一堆學習文檔,方便以后查看

官網文檔地址大全:

OverView(概述)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperOver.html

Getting Started(開始入門)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperStarted.html

Tutorial(教程)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperTutorial.html

Java Example(Java示例)

http://zookeeper.apache.org/doc/r3.4.6/javaExample.html

Programmer's Guide(開發人員指南)

http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html

Recipes and Solutions(技巧及解決方案)

http://zookeeper.apache.org/doc/r3.4.6/recipes.html

3.4.6 API online(在線API速查)

http://zookeeper.apache.org/doc/r3.4.6/api/index.html

另外推薦園友sunddenly的zookeeper系列

http://www.cnblogs.com/sunddenly/category/620563.html

 

一、安裝部署

本文在一台機器上模擬3個 zk server的集群安裝

1.1 下載解壓

解壓到3個目錄(模擬3台zk server):

  /home/hadoop/zookeeper-1

  /home/hadoop/zookeeper-2

  /home/hadoop/zookeeper-3

1.2 創建每個目錄下conf/zoo.cfg配置文件 

/home/hadoop/zookeeper-1/conf/zoo.cfg 內容如下:

復制代碼
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/hadoop/tmp/zk1/data
dataLogDir=/home/hadoop/tmp/zk1/log
clientPort=2181
server.1=localhost:2287:3387
server.2=localhost:2288:3388
server.3=localhost:2289:3389
復制代碼

/home/hadoop/zookeeper-2/conf/zoo.cfg 內容如下:

復制代碼
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/hadoop/tmp/zk2/data
dataLogDir=/home/hadoop/tmp/zk2/log
clientPort=2182
server.1=localhost:2287:3387
server.2=localhost:2288:3388
server.3=localhost:2289:3389
復制代碼

/home/hadoop/zookeeper-3/conf/zoo.cfg 內容如下:

復制代碼
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/hadoop/tmp/zk3/data
dataLogDir=/home/hadoop/tmp/zk3/log
clientPort=2183
server.1=localhost:2287:3387
server.2=localhost:2288:3388
server.3=localhost:2289:3389
復制代碼

注:因為是在一台機器上模擬集群,所以端口不能重復,這里用2181~2183,2287~2289,以及3387~3389相互錯開。另外每個zk的instance,都需要設置獨立的數據存儲目錄、日志存儲目錄,所以dataDir、dataLogDir這二個節點對應的目錄,需要手動先創建好。

另外還有一個灰常關鍵的設置,在每個zk server配置文件的dataDir所對應的目錄下,必須創建一個名為myid的文件,其中的內容必須與zoo.cfg中server.x 中的x相同,即:

/home/hadoop/tmp/zk1/data/myid 中的內容為1,對應server.1中的1
/home/hadoop/tmp/zk2/data/myid 中的內容為2,對應server.2中的2
/home/hadoop/tmp/zk3/data/myid 中的內容為3,對應server.3中的3

生產環境中,分布式集群部署的步驟與上面基本相同,只不過因為各zk server分布在不同的機器,上述配置文件中的localhost換成各服務器的真實Ip即可。分布在不同的機器后,不存在端口沖突問題,可以讓每個服務器的zk均采用相同的端口,這樣管理起來比較方便。

1.3 啟動驗證 

/home/hadoop/zookeeper-1/bin/zkServer.sh start

/home/hadoop/zookeeper-2/bin/zkServer.sh start

/home/hadoop/zookeeper-3/bin/zkServer.sh start

啟用成功后,輸入 jps 看下進程

20351 ZooKeeperMain
20791 QuorumPeerMain
20822 QuorumPeerMain
20865 QuorumPeerMain

應該至少能看到以上幾個進程。

可以啟動客戶端測試下:

bin/zkCli.sh -server localhost:2181

(注:如果是遠程連接,把localhost換成指定的IP即可)

成功后,應該會進到提示符下,類似下面這樣:

[zk: localhost:2181(CONNECTED) 0]  

然后,就可以用一些基礎命令,比如 ls ,create ,delete ,get 來測試了(關於這些命令,大家可以查看文檔),特別提一個很有用的命令rmr 用來遞歸刪除某個節點及其所有子節點

 

二、java 與 zk的連接示例

2.1 maven項目的pom.xml中先添加以下依賴項

復制代碼
        <!--zk-->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
復制代碼

2.2 最基本的示例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package  yjmyzz;
 
import  java.io.IOException;
import  org.apache.zookeeper.*;
import  org.apache.zookeeper.data.Stat;
 
public  class  ZooKeeperHello {
 
     public  static  void  main(String[] args)  throws  IOException, InterruptedException, KeeperException {
         ZooKeeper zk =  new  ZooKeeper( "172.28.20.102:2181" 300000 new  DemoWatcher()); //連接zk server
         String node =  "/app1" ;
         Stat stat = zk.exists(node,  false ); //檢測/app1是否存在
         if  (stat ==  null ) {
             //創建節點
             String createResult = zk.create(node,  "test" .getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
             System.out.println(createResult);
         }
         //獲取節點的值
         byte [] b = zk.getData(node,  false , stat);
         System.out.println( new  String(b));
         zk.close();
     }
 
     static  class  DemoWatcher  implements  Watcher {
         @Override
         public  void  process(WatchedEvent event) {
             System.out.println( "----------->" );
             System.out.println( "path:"  + event.getPath());
             System.out.println( "type:"  + event.getType());
             System.out.println( "stat:"  + event.getState());
             System.out.println( "<-----------" );
         }
     }
}

2.3 與zk集群的連接

zk的優點之一,就是高可用性,上面的代碼連接的是單台zk server,如果這台server掛了,自然代碼就會出錯,事實上zk的API考慮到了這一點,把連接代碼改成下面這樣:

 ZooKeeper zk = new ZooKeeper("172.28.20.102:2181,172.28.20.102:2182,172.28.20.102:2183", 300000, new DemoWatcher());//連接zk server
  

 即:IP1:port1,IP2:port2,IP3:port3...  用這種方式連接集群就行了,只要有超過半數的zk server還活着,應用一般就沒問題。但是也有一種極罕見的情況,比如這行代碼執行時,剛初始化完成,正准備連接ip1時,因為網絡故障ip1對應的server掛了,仍然會報錯(此時,zk還來不及選出新leader),這個問題詳見:http://segmentfault.com/q/1010000002506725/a-1020000002507402,參考該文的做法,改成:

復制代碼
 1         ZooKeeper zk = new ZooKeeper("172.28.20.102:2181,172.28.20.102:2182,172.28.20.102:2183", 300000, new DemoWatcher());//連接zk server
 2         if (!zk.getState().equals(ZooKeeper.States.CONNECTED)) {
 3             while (true) {
 4                 if (zk.getState().equals(ZooKeeper.States.CONNECTED)) {
 5                     break;
 6                 }
 7                 try {
 8                     TimeUnit.SECONDS.sleep(5);
 9                 } catch (InterruptedException e) {
10                     e.printStackTrace();
11                 }
12             }
13         }
復制代碼

 但是這樣代碼未免太冗長,建議用開源的zkClient,官方地址: https://github.com/sgroschupf/zkclient,使用方法很簡單:

復制代碼
        <!--zkclient-->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
復制代碼

pom.xml先加這一坨,然后這樣用:

復制代碼
1     @Test
2     public void testZkClient() {
3         ZkClient zkClient = new ZkClient("172.28.20.102:2181,172.28.20.102:2182,172.28.20.102:2183");
4         String node = "/app2";
5         if (!zkClient.exists(node)) {
6             zkClient.createPersistent(node, "hello zk");
7         }
8         System.out.println(zkClient.readData(node));
9     }
復制代碼


免責聲明!

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



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