zookeeper的介紹、部署、常用命令以及API

Zookeeper描述:
Zookeeper是一個開源的分佈式的,爲分佈式應用提供協調服務的Apache項目。起作用有點難描述,在Hadoop生態裏充當潤滑液的作用。zookeeper=文件系統+通知監聽機制。它的文件系統和普通的文件系統有點差別,它的父節點和葉子節點都能存數據;它的監聽通知機制就是:zookeeper分爲客戶端和服務端,客戶端會監聽服務器列表,有服務器下線或者宕機,zookeeper就會作出響應。
話不多說直接上搭建過程:
先去官網下載zookeeper:https://zookeeper.apache.org/
我下載的是3.4.10,然後把壓縮包傳到linux裏,我放的路徑是/opt/software/裏面。前提是要把jdk安裝好。
1.解壓
在/opt/software下解壓,解壓到/opt/module/下,命令爲如下:tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
2.修改配置
(1)將/opt/module/zookeeper-3.4.10/conf這個路徑下的zoo_sample.cfg修改爲zoo.cfg;
mv zoo_sample.cfg zoo.cfg
(2)打開zoo.cfg文件,修改dataDir路徑:
vim zoo.cfg
修改如下內容:
dataDir=/opt/module/zookeeper-3.4.10/zkData
添加一下內容:
server.1=hadoop01:2888:3888
server.2=hadoop02:2888:3888
server.3=hadoop03:2888:3888
hadoop0x是我的三臺虛擬機的主機名,大家配置的時候要修改成自己的。
在/opt/module/zookeeper-3.4.10/zkData目錄下創建一個myid的文件
touch myid
然後把server的編號寫上,例如我現在在hadoop01上配置,通過剛配的文件可以看到,我的hadoop01對應的是server.1,所以在myid裏面要寫上1,等下配置hadoop02的時候就要寫2,以此類推。
(3)在/opt/module/zookeeper-3.4.10/這個目錄上創建zkData文件夾
mkdir zkData
3.zookeeper命令
配置好上述就可以啓動zookeeper了,在zookeeper目錄下:
bin/zkServer.sh start
就可以啓動了,如果想要在哪都可以直接啓動zookeeper就要把zookeeper的bin目錄寫入環境變量即:
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10/bin寫入到/etc/profile裏即可。
啓動後運行jps就能看到QuorumPeerMain進程,這個就是zookeeper的進程。
(1)查看狀態:
bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/…/conf/zoo.cfg
Mode: standalone
(2)啓動客戶端:
bin/zkCli.sh
(3)退出客戶端:
quit
(4)停止Zookeeper
bin/zkServer.sh stop
接下來就可以把解壓好的zookeeper分發到集羣的其他機器上了,用以下命令:
rsync -av /opt/module/zookeeper-3.4.10 hadoop02:/opt/module
發到其他集羣上後要記得修改myid文件還有配置zookeeper的環境變量,hadoop03亦是如此。
zookeeper客戶端程勇命令操作

命令基本語法 功能描述
help 顯示所有操作命令
ls path [watch] 使用 ls 命令來查看當前znode中所包含的內容
ls2 path [watch] ls2 path [watch]
create 普通創建-s 含有序列-e 臨時(重啓或者超時消失)
get path [watch] 獲得節點的值
set 設置節點的具體值
stat 查看節點狀態
delete 刪除節點
rmr 遞歸刪除節點

1.啓動客戶端
bin/zkCli.sh
2.顯示所有操作命令
[zk: localhost:2181(CONNECTED) 1] help
3.查看當前znode中所包含的內容
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
4.查看當前節點詳細數據
[zk: localhost:2181(CONNECTED) 1] ls2 /
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
5.分別創建2個普通節點
[zk: localhost:2181(CONNECTED) 3] create /sanguo “jinlian”
Created /sanguo
[zk: localhost:2181(CONNECTED) 4] create /sanguo/shuguo “liubei”
Created /sanguo/shuguo
6.獲得節點的值
[zk: localhost:2181(CONNECTED) 5] get /sanguo
jinlian
cZxid = 0x100000003
ctime = Wed Aug 29 00:03:23 CST 2018
mZxid = 0x100000003
mtime = Wed Aug 29 00:03:23 CST 2018
pZxid = 0x100000004
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 1
[zk: localhost:2181(CONNECTED) 6]
[zk: localhost:2181(CONNECTED) 6] get /sanguo/shuguo
liubei
cZxid = 0x100000004
ctime = Wed Aug 29 00:04:35 CST 2018
mZxid = 0x100000004
mtime = Wed Aug 29 00:04:35 CST 2018
pZxid = 0x100000004
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
7.創建短暫節點
[zk: localhost:2181(CONNECTED) 7] create -e /sanguo/wuguo “zhouyu”
Created /sanguo/wuguo
(1)在當前客戶端是能查看到的
[zk: localhost:2181(CONNECTED) 3] ls /sanguo
[wuguo, shuguo]
(2)退出當前客戶端然後再重啓客戶端
[zk: localhost:2181(CONNECTED) 12] quit
bin/zkCli.sh
(3)再次查看根目錄下短暫節點已經刪除
[zk: localhost:2181(CONNECTED) 0] ls /sanguo
[shuguo]
8.創建帶序號的節點
(1)先創建一個普通的根節點/sanguo/weiguo
[zk: localhost:2181(CONNECTED) 1] create /sanguo/weiguo “caocao”
Created /sanguo/weiguo
(2)創建帶序號的節點
[zk: localhost:2181(CONNECTED) 2] create -s /sanguo/weiguo/xiaoqiao “jinlian”
Created /sanguo/weiguo/xiaoqiao0000000000
[zk: localhost:2181(CONNECTED) 3] create -s /sanguo/weiguo/daqiao “jinlian”
Created /sanguo/weiguo/daqiao0000000001
[zk: localhost:2181(CONNECTED) 4] create -s /sanguo/weiguo/diaocan “jinlian”
Created /sanguo/weiguo/diaocan0000000002
如果原來沒有序號節點,序號從0開始依次遞增。如果原節點下已有2個節點,則再排序時從2開始,以此類推。
9.修改節點數據值
[zk: localhost:2181(CONNECTED) 6] set /sanguo/weiguo “simayi”
10.節點的值變化監聽
(1)在hadoop104主機上註冊監聽/sanguo節點數據變化
[zk: localhost:2181(CONNECTED) 26] [zk: localhost:2181(CONNECTED) 8] get /sanguo watch
(2)在hadoop103主機上修改/sanguo節點的數據
[zk: localhost:2181(CONNECTED) 1] set /sanguo “xisi”
(3)觀察hadoop104主機收到數據變化的監聽
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo
11.節點的子節點變化監聽(路徑變化)
(1)在hadoop104主機上註冊監聽/sanguo節點的子節點變化
[zk: localhost:2181(CONNECTED) 1] ls /sanguo watch
[aa0000000001, server101]
(2)在hadoop103主機/sanguo節點上創建子節點
[zk: localhost:2181(CONNECTED) 2] create /sanguo/jin “simayi”
Created /sanguo/jin
(3)觀察hadoop104主機收到子節點變化的監聽
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo
12.刪除節點
[zk: localhost:2181(CONNECTED) 4] delete /sanguo/jin
13.遞歸刪除節點
[zk: localhost:2181(CONNECTED) 15] rmr /sanguo/shuguo
14.查看節點狀態
[zk: localhost:2181(CONNECTED) 17] stat /sanguo
cZxid = 0x100000003
ctime = Wed Aug 29 00:03:23 CST 2018
mZxid = 0x100000011
mtime = Wed Aug 29 00:21:23 CST 2018
pZxid = 0x100000014
cversion = 9
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 1

zookeeper API應用

IDEA環境搭建(eclipse搭建方法也差不多)
1.創建一個Maven工程
2.添加pom文件

<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.8.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.10</version>
		</dependency>
</dependencies>

3.拷貝log4j.properties文件到項目根目錄
需要在項目的src/main/resources目錄下,新建一個文件,命名爲“log4j.properties”,在文件中填入。

log4j.rootLogger=INFO, stdout  
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n  
log4j.appender.logfile=org.apache.log4j.FileAppender  
log4j.appender.logfile.File=target/spring.log  
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout  
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

以下代碼包含了zookeeper的一些增刪改查API方法:

package cn.edu.lingnan.zookeeper;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class zkClient {

    private ZooKeeper zkCli;
    private static final String CONNECT_STRING = "192.168.218.130:2181,192.168.218.131:2181,192.168.218.132:2181";
    private static final int SESSION_TIMEOUT = 2000;

    //回調函數會在節點發生變化的時候通知主線程
    @Before
    public void before() throws IOException {
        zkCli = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new Watcher() {
            public void process(WatchedEvent event) {
                System.out.println("默認回調函數");
            }
        });
    }

    //相當於zookeeper的ls path命令
    @Test
    public void ls() throws KeeperException, InterruptedException {
        List<String> children = zkCli.getChildren("/", true);
        System.out.println("================================");
        for (String child : children) {
            System.out.println(child);
        }
        System.out.println("================================");
        //讓主線程休眠,讓程序一直等待回調函數的通知
        Thread.sleep(Long.MAX_VALUE);
    }

    //相當於zookeeper的create命令
    @Test
    public void create() throws KeeperException, InterruptedException {
        //最後一個參數代表創建的節點是臨時還是永久,有序還是無序
        String s = zkCli.create("/Idea", "Idea2019".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println(s);
        Thread.sleep(Long.MAX_VALUE);
    }

    //相當於zookeeper的get命令
    @Test
    public void get() throws KeeperException, InterruptedException {
        byte[] data = zkCli.getData("/test0", true, new Stat());
        String s = new String(data);
        System.out.println(s);
    }

    //相當於zookeeper的set命令
    @Test
    public void set() throws KeeperException, InterruptedException {
        //最後一個參數表示要修改的版本號,在不知道版本號的時候可以用以下代碼獲得
        /*
            Stat exit = zkCli.exists("/test0", false);
            exit.getVersion();
         */
        Stat stat = zkCli.setData("/test0", "4321".getBytes(), 0);
        byte[] data = zkCli.getData("/test0", true, new Stat());
        String s = new String(data);
        System.out.println(s);
    }

    //相當於zookeeper的stat命令
    @Test
    public void stat() throws KeeperException, InterruptedException {
        Stat exit = zkCli.exists("/test0", false);
        exit.getVersion();
        if(exit == null){
            System.out.println("節點不存在!");
        }else{
            System.out.println(exit.getDataLength());
        }
    }

    @Test
    public void delete() throws KeeperException, InterruptedException {
        Stat exit = zkCli.exists("/test0", false);
        if(exit != null)
            zkCli.delete("/test0",exit.getVersion());

    }

    public void register() throws KeeperException, InterruptedException{
        byte[] data = zkCli.getData("/test0", new Watcher() {
            public void process(WatchedEvent event) {
                try {
                    register();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },null);
        System.out.println(new String(data));
    }

    //循環註冊,由於zookeeper註冊一次只監聽一次
    @Test
    public void testregister(){
        try {
            register();
            Thread.sleep(Long.MAX_VALUE);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

發佈了17 篇原創文章 · 獲贊 11 · 訪問量 5114
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章