程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Zookeeper的集群配置和Java測試程序

Zookeeper的集群配置和Java測試程序

編輯:JAVA綜合教程

Zookeeper的集群配置和Java測試程序


概述

Zookeeper是Apache下的項目之一,傾向於對大型應用的協同維護管理工作。IBM則給出了IBM對ZooKeeper的認知: Zookeeper 分布式服務框架是 Apache Hadoop 的一個子項目,它主要是用來解決分布式應用中經常遇到的一些數據管理問題,如:統一命名服務、狀態同步服務、集群管理、分布式應用配置項的管理等。總之,可以用“協調”這個核心的詞來形容它的作用。關於它能干嗎,你可以看看 “Zookeeper能干什麼?”。

特征

我們可以把Zookeeper理解為一個精簡的文件系統(和Linux文件系統結構非常相似),其每一個節點稱為znode,znode下可以存放子節點,也可以直接對節點進行賦值存值。

Zookeeper被應用與一些集群上,提高集群的高可用。它可以幫助你避免單點故障,使你的系統更加可靠。

Zookeeper的集群我們可以通俗的理解為,一個有Leader的團隊,團隊中各個成員的數據都是一致的。團隊中的Leader采用選舉算法推舉,所以可以保證在Leader出現問題的時候,又會選舉出新的Leader。(fast paxos 選舉算法大家可以深入了解下)

Zookeeper使用路徑來描述節點,節點可以被看做是一個目錄,也可以被看做是一個文件,它同時具有兩者的特點。

Zookeeper的Watch機制也是它的最大被應用的原因。當我們有很多客戶端連接到Zookeeper時,當被設置了Watch的數據發生了改變的時候,則服務器將這個改變發送給設置了Watch的客戶端,通知它們。所以我們經常用它來做業務系統的統一配置管理。使用zk的Watch要特別注意一點就是它的“一次性觸發器”(最後的Java例子中有模擬這點)

集群部署

1. 下載

官網:http://zookeeper.apache.org/releases.html
下載:zookeeper-3.4.8.tar.gz

2. 安裝

因為資源有限,所以我在同一個服務器上面創建3個目錄 server1、server2、server3 來模擬3台服務器集群。
cd server1
tar -zxvf zookeeper-3.4.8.tar.gz
mkdir data
mkdir dataLog
data 為數據目錄,dataLog 為日志目錄。

3. 配置

cd zookeeper-3.4.8/conf
創建文件 zoo.cfg,內容如下:

tickTime=2000 
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server1/data
dataLogDir=/opt/zookeeper/server1/dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

tickTime:zookeeper中使用的基本時間單位, 毫秒值。
initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這裡所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集群中連接到 Leader 的 Follower 服務器)初始化連接時最長能忍受多少個 tickTime 時間間隔數。這裡設置為5表名最長容忍時間為 5 * 2000 = 10 秒。
syncLimit:這個配置標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2 * 2000 = 4 秒。
dataDirdataLogDir 看配置就知道干嗎的了,不用解釋。
clientPort:監聽client連接的端口號,這裡說的client就是連接到Zookeeper的代碼程序。
server.{myid}={ip}:{leader服務器交換信息的端口}:{當leader服務器掛了後, 選舉leader的端口}
maxClientCnxns:對於一個客戶端的連接數限制,默認是60,這在大部分時候是足夠了。但是在我們實際使用中發現,在測試環境經常超過這個數,經過調查發現有的團隊將幾十個應用全部部署到一台機器上,以方便測試,於是這個數字就超過了。

修改zoo.cfg非常簡單,然後還需要創建myid文件:
cd server1
echo 1 > myid

然後拷貝server1為server2和server3,並修改其中的zoo.cfg配置,當然也要修改myid的內容為2和3。

下面給出3個server的zoo.cfg 內容:

# server1
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server1/data
dataLogDir=/opt/zookeeper/server1/dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
# server2
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server2/data
dataLogDir=/opt/zookeeper/server2/dataLog
clientPort=2182
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
# server3
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server3/data
dataLogDir=/opt/zookeeper/server3/dataLog
clientPort=2183
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

這裡做下說明:因為我們是在同一個機器上模擬的集群,所以要注意server端口號和clientPort不要重復了,不然會出現端口沖突。所以,如果我們是3個不同的機器上做的3個server,那麼我們的zoo.cfg配置都是一樣的(注意server.{myid}=後面的IP地址使用具體的IP地址,如192.168.0.88)。還有就是,每一個server的myid內容都不能一樣,這也可以理解為不同server的標識。

4. 啟動

進入 zookeeper-3.4.8/bin 目錄,使用 ./zkServer.sh start 啟動zk服務。(你也可以使用 ./zkServer.sh start myzoo.cfg 指定配置文件啟動,這在自動化運維的時候很有用)
使用 tail -f zookeeper.out 查看日志。
要說的是:在啟動第一個的時候,日志中會出現一堆錯誤,仔細一看就能明白,是因為另外2個server還沒有啟動它連接不上的錯誤。然後當我們啟動第二個server的時候,日志中的錯誤將會減少。最後我們把所有server都啟動起來後,日志中便沒有錯誤了。

5. 測試

隨便進入一個zk目錄,連接一個server測試。
cd zookeeper-3.4.8/bin
zkCli.sh -server 127.0.0.1:2181
如果你要連接別的服務器,請指定具體的IP地址。

幾個基本命令說明:
ls 查看指定節點中包含的子節點(如:ls / 或 ls /app1/server1)
create 創建節點並賦值
get 讀取節點內容
set 改變節點內容
delete 刪除節點
注意zk中所有節點都基於路徑確定,如你要刪除 /app1/server1/nodeA 的命令為:
delete /app1/server1/nodeA

下面是基本操作截圖:
這裡寫圖片描述

Java程序Demo

創建一個Maven工程
打開pom.xml文件添加zookeeper依賴

        
            org.apache.zookeeper
            zookeeper
            3.4.6
        

創建Demo.java,代碼如下:

package com.shanhy.demo.zookeeper;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

/**
 * Zookeeper測試
 *
 * @create    2016年3月10日
 */
public class Test {

    // 會話超時時間,設置為與系統默認時間一致
    private static final int SESSION_TIMEOUT = 30 * 1000;

    // 創建 ZooKeeper 實例
    private ZooKeeper zk;

    // 創建 Watcher 實例
    private Watcher wh = new Watcher() {
        /**
         * Watched事件
         */
        public void process(WatchedEvent event) {
            System.out.println("WatchedEvent >>> " + event.toString());
        }
    };

    // 初始化 ZooKeeper 實例
    private void createZKInstance() throws IOException {
        // 連接到ZK服務,多個可以用逗號分割寫
        zk = new ZooKeeper("192.168.19.130:2181,192.168.19.130:2182,192.168.19.130:2183", Test.SESSION_TIMEOUT, this.wh);

    }

    private void ZKOperations() throws IOException, InterruptedException, KeeperException {
        System.out.println("\n1. 創建 ZooKeeper 節點 (znode : zoo2, 數據: myData2 ,權限: OPEN_ACL_UNSAFE ,節點類型: Persistent");
        zk.create("/zoo2", "myData2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        System.out.println("\n2. 查看是否創建成功: ");
        System.out.println(new String(zk.getData("/zoo2", this.wh, null)));// 添加Watch

        // 前面一行我們添加了對/zoo2節點的監視,所以這裡對/zoo2進行修改的時候,會觸發Watch事件。
        System.out.println("\n3. 修改節點數據 ");
        zk.setData("/zoo2", "shanhy20160310".getBytes(), -1);

        // 這裡再次進行修改,則不會觸發Watch事件,這就是我們驗證ZK的一個特性“一次性觸發”,也就是說設置一次監視,只會對下次操作起一次作用。
        System.out.println("\n3-1. 再次修改節點數據 ");
        zk.setData("/zoo2", "shanhy20160310-ABCD".getBytes(), -1);

        System.out.println("\n4. 查看是否修改成功: ");
        System.out.println(new String(zk.getData("/zoo2", false, null)));

        System.out.println("\n5. 刪除節點 ");
        zk.delete("/zoo2", -1);

        System.out.println("\n6. 查看節點是否被刪除: ");
        System.out.println(" 節點狀態: [" + zk.exists("/zoo2", false) + "]");
    }

    private void ZKClose() throws InterruptedException {
        zk.close();
    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        Test dm = new Test();
        dm.createZKInstance();
        dm.ZKOperations();
        dm.ZKClose();
    }
}

我想代碼不用解釋了,該注釋的裡面都注釋了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved