ZooKeeper1 利用虛擬機搭建自己的ZooKeeper集群


前言:

      前段時間自己參考網上的文章,梳理了一下基於分布式環境部署的業務系統在解決數據一致性問題上的方案,其中有一個方案是使用ZooKeeper,加之在大數據處理中,ZooKeeper確實起到協調服務的作用,所以利用周末休息時間,自己在虛擬機上簡單搭建了一個ZooKeeper集群,學習了解一下。

===============================================================長長的分割線====================================================================

正文:

  在本文中主要涉及三塊內容: 第一,就是搭建虛擬機環境;第二,安裝ZooKeeper、啟動ZooKeeper以及使用內置命令操作ZooKeeper;第三,使用Java API完成操作,以便了解如何在實際的項目中使用。

  閑話少說,言歸正傳,本次的目的是利用VMware搭建一個屬於自己的ZooKeeper集群。本次我們選擇的是VMware10,具體的安裝步驟大家可以到網上搜索,資源很多。

  第一步,確定目標:

      ZooKeeperOne       192.168.224.170  CentOS

      ZooKeeperTwo       192.168.224.171  CentOS

      ZooKeeperThree     192.168.224.172  CentOS

      我們安裝的ZooKeeper是3.4.6版本,可以從這里下載zookeeper-3.4.6; JDK安裝的版本是1.7版本

 

      第二步,安裝CentOS環境、JDK1.7、配置網絡:

      此處大家可以參考網上的文章,或者參考我之前寫的一篇文章 Hadoop4  利用VMware搭建自己的hadoop集群 ,該文章中的 第一步 到 第八步 涉及了安裝基本環境的步驟哦和方法。我們只需要注意一下兩點:

      (1). 由於我們是在VMware中搭建三個服務器,所以我們可以先搭建一台,待配置都okay后,再利用VMware的克隆功能,直接克隆出另外兩台,克隆出的兩台只需要注意修改 /etc/sysconfig/network-scripts/ifcfg-eth0 中HWADDR屬性、IPADDR 以及 /etc/sysconfig/network 的主機名稱HOSTNAME

      (2). JDK的安裝注意使用JDK1.7,有些ZooKeeper版本在JDK1.6下是不支持的,所以簡單一點,我們就直接使用JDK1.7。

 

      第三步,安裝配置ZooKeeper:

      (1). 從這里下載zookeeper-3.4.6,將文件解壓縮,不用安裝。以我的為例,我的ZooKeeper路徑是: /myself_settings/zookeeper3.4.6/zookeeper-3.4.6,詳細如下圖:

      

      (2). 需要執行 vi  ~/.bash_profile,編輯一下ZooKeeper的環境變量,編輯完畢后執行 source ~/.bash_profile 使配置生效,詳細如下圖:

      

      (3). 在(1)的zookeeper目錄中,有一個conf文件夾,該文件夾中有一個 zoo_sample.cfg 的文件,我們使用命令 mv zoo_sample.cfg zoo.cfg 復制出一個zoo.cfg文件,這個文件就是ZooKeeper啟動是時候默認要加載的配置文件,我們可以打開zoo.cfg查看都有哪些配置,並簡單了解一下配置的含義,然后我們需要將配置改成如下圖中的配置: 

      

      (4). 如(3)中的圖中的配置,除了我在圖中用紅色框圈中的屬性需要你添加或者修改,其余屬性可以使用默認的。對於dataDir和dataLogDir這連個配置,顧名思義,分別是ZooKeeper的數據和日志目錄,這個路徑可以任意配置,我自己的目錄就分別為/opt/zookeeper4.3.6/data 和 /opt/zookeeper4.3.6/log; 對於配置中的最后三行,每一行的格式都形如: server.id=host:port1:port2,其中host就是你的主機名稱,port1代表着從(follower)機器連接到主(leader)機器的端口,port2代表着是用來進行leader選舉的端口,注意這兩個端口與 clientPort=2181 這個端口的含義區別。還有server.id中的id標識的是不同的服務器,在dataDir這個配置的路徑下,建立一個名為myid的文件,在文件中只包含一行內容,即所指定的自身的id值,比如服務器"1"應該在myid文件中寫入"1"。

      (5). 其余兩台服務器,注意修改(4)中的提到的這些需要變動的配置。

      (6). 經過上邊的配置,我們就可以准備啟動ZooKeeper了,我么通過執行 zkServer.sh start 就可以將ZooKeeper啟動了,其余服務器也直接使用相同命令啟動即可。我們也可以使用  zkServer.sh start 指定路徑的zoo.cfg文件  這個命令來啟動ZooKeeper。啟動成功截圖詳細如下:

      

 

      第四步,使用客戶端命令訪問客戶端:

      (1). 我們可以在服務器上執行 zkCli.sh -server 192.168.224.170:2181 進入客戶端,我們可以看到WelCome to ZooKeeper!等文字,詳細如下圖:

      

      (2). 在客戶端中我們了解以下幾個命令,大家可以自行在客戶端執行體驗一下,對於get /zk這個命令執行返回的結果中,每個屬性的含義值大家可以參考這片文章初步了解一下。

      a. ls /   該命令用來查看當前ZooKeeper中所包含的內容

      b. create /zk myData   該命令是創建了一個新的Znode節點zk,其內容是 myData

      c. get /zk   該命令是獲取已創建節點的信息

      d. set /zk hahaha    該命令是對zk這個節點的內容進行設置

      e. delete /zk   該命令是刪除某個節點

 

      第五步,使用Java API訪問ZooKeeper:

      其實Java API提供的功能基本也是基於上邊的客戶端命令來實現的,萬變不離其宗,我將我整理的網上的例子貼到下面,大家可以在本地Java工程中執行一下,即可了解調用方法。這里有一點需要注意,我們需要在本地Java工程中引入 ZooKeeper安裝包根目錄下的zookeeper-3.4.6.jar 和 lib目錄中的jar包。

 1 import java.util.List;
 2 
 3 import org.apache.zookeeper.CreateMode;
 4 import org.apache.zookeeper.WatchedEvent;
 5 import org.apache.zookeeper.Watcher;
 6 import org.apache.zookeeper.ZooDefs.Ids;
 7 import org.apache.zookeeper.ZooKeeper;
 8 import org.apache.zookeeper.data.Stat;
 9 
10 
11 /**
12  * @Title ZookeeperDemo0001.java
13  * @Package 
14  * @author zhangyi03
15  * @description 基於zookeeper3.4.6,完成第一個zookeeper程序
16  * @date 2015-9-19 下午11:14:20
17  * @version v1.0
18  */
19 public class ZookeeperDemo0001 {
20     // 會話超時時間,設置為系統默認時間一致
21     private static final int SESSION_TIMEOUT = 30000;
22     
23     // 創建ZooKeeper實例
24     ZooKeeper zk;
25     
26     // 創建Watcher實例
27     Watcher wh = new Watcher() {
28         public void process(WatchedEvent event) {
29             System.out.println(event.toString());
30         }
31     };
32     
33     // 初始化ZooKeeper實例
34     private void createZKInstance() throws Exception {
35         zk = new ZooKeeper("192.168.224.170:2181", SESSION_TIMEOUT, wh);
36     }
37     
38     private void ZKOperations() throws Exception {
39         System.out.println("\n1. 創建 ZooKeeper 節點 (znode: zoo2, 數據: myData2, " +
40                 "權限: OPEN_ACL_UNSAFE, 節點類型: Persistent)");
41         zk.create("/zoo2", "myData2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
42         
43         System.out.println("\n2. 查看是否創建成功:");
44         System.out.println(new String(zk.getData("/zoo2", false, null)));
45         
46         System.out.println("\n3. 修改節點數據");
47         Stat setDataStat = zk.setData("/zoo2", "zhangyi03201509192339".getBytes(), -1);
48         
49         
50         System.out.println("\n4. 查看是否修改成功:");
51         System.out.println(new String(zk.getData("/zoo2", false, null)));
52         
53         System.out.println("\n5. 添加子節點");
54         for (int index = 0; index < 3; index++) {
55             zk.create("/zoo2/" + "child_" + (index+1), ("child_" + (index+1)).getBytes(), 
56                     Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
57         }
58         
59         System.out.println("\n6. 查看所有子節點:");
60         List<String> childList = zk.getChildren("/zoo2", false);
61         for (String child : childList) {
62             System.out.println("\t\t\t 子節點:" + child);
63         }
64         
65         System.out.println("\n7. 刪除所有子節點");
66         for (String child : childList) {
67             zk.delete("/zoo2" + "/" + child, -1);
68         }
69         
70         System.out.println("\n8. 刪除節點");
71         zk.delete("/zoo2", -1);
72         
73         System.out.println("\n9. 查看節點是否被刪除:");
74         System.out.println("節點狀態: [" + zk.exists("/zoo2", false) + "]");
75     }
76     
77     private void ZKClose() throws Exception {
78         zk.close();
79     }
80     
81     /**
82      * @author zhangyi03
83      * @date 2015-9-19 下午11:14:01
84      * @description 
85      * @param args
86      */
87     public static void main(String[] args) throws Exception {
88         ZookeeperDemo0001 demo = new ZookeeperDemo0001();
89         demo.createZKInstance();
90         demo.ZKOperations();
91         demo.ZKClose();
92     }
93 }

 

      經過上邊的五步,我們基本上已經對如何安裝ZooKeeper和使用ZooKeeper有了一定的了解,也就是ZooKeeper核心基本內容。這里需要大家再執行上班的Java代碼中再主動的查詢這樣幾個問題:

      (1). ZooKeeper中的Znode、Watches的含義

      (2). ZooKeeper中的永久節點和臨時節點的含義和區別

      (3). ZooKeeper中的ACL的含義,以及對應的Java代碼中的Ids.OPEN_ACL_UNSAFE 等幾個屬性的含義

      (4). ZooKeeper中的cZxid、mZxid等時間戳的含義;version、cversion、aversion等版本號的含義

      (5). 我開頭提到的如何利用ZooKeeper的節點數據版本號和Java API來實現數據鎖

      上述這5個問題,都是我在安裝和執行測試代碼過程中想過的,找到答案也很簡單哦,加油! 

      同時,我在查看ZooKeeper安裝目錄下的zookeeper-3.4.6\recipes目錄中的lock工程時,這是一個"寫鎖"的實現,基本的思想流程搞明白了,但是看的過程中對代碼理解的還不是很深,大家也可以看一下。哎,今天實在是不想再看了,寫完博客玩游戲去了,明天晚上再看看那個例子。

      各位同仁,加油哈!!!

      

   


免責聲明!

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



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