目录

  • 一、zookeeper下载与安装
  • 二、zoo.cfg配置文件解读:
  • 三、集群部署
  • 1.节点规划
  • 2.配置hosts文件
  • 3.部署前配置
  • 4.服务启动与选举策略
  • 四、客户端操作
  • 1.客户端启动
  • 2.节点信息
  • 3.节点类型与节点操作
  • 五、java代码实现节点基本操作


一、zookeeper下载与安装

1.zookeeper包的下载地址:zookeeper-3.5.7 2.解压:

tar -xvf apache-zookeeper-3.5.7-bin.tar.gz

3.本文中的@{ZK_HOME}:代表zookeeper的主目录,即tar包的解压目录,目录结构如下:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_linux


解压完成即安装完成!

二、zoo.cfg配置文件解读:

@{ZK_HOME}/conf下的zoo_sample.cfg即为zookeeper的主要配置文件,安装时需改名为zoo.cfg

解压后配置文件初始状态如下(省略注释):

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
clientPort=2181

1.tickTime:单位毫秒,意思是两次心跳之间的间隔,这个心跳指的是客户端与服务器或者服务器与服务器之间维持的状态监测;
2.initLimit:初始通信的最多心跳次数,如果到达此数值的心跳检测仍失败则宣告初始通信失败
3.syncLimit:初始通信成功之后的通信检测次数,如果到达此数值的心跳检测仍失败则宣告通信失败
4.dataDir:保存zk数据,不能放在/tmp下
5.clientPort:通信端口,用了与客户端建立连接

三、集群部署

1.节点规划

windows节点 *1+linux节点 *2

  • windows ip: 192.168.100.86 --hostname:zookeeper86
  • linux1 ip: 192.168.100.153 --hostname:zookeeper153
  • linux2: 192.168.100.72 --hostname:zookeeper72

2.配置hosts文件

(如果不配置,后面一步配置zoo.cfg也可直接用IP)

windows的hosts文件位置:C:\Windows\System32\drivers\etc\hosts
linux的hosts文件位置:/etc/hosts
同时增加如下几行:

192.168.100.86 zookeeper86
192.168.100.72 zookeeper72
192.168.100.153 zookeeper153

3.部署前配置

1) 创建目录,@{ZK_HOME}/zkData,并在zkData下创建myid文件,zkData名字可自定义,myid文件名字必须是myid

linux节点中:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_apache_02


windows节点中:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_zookeeper_03


2)配置myid此文件内容为一个id号,为节点的唯一标识,可自定义,本实验取每个节点的ip末位为myid,如在72节点上:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_java_04

3)配置zoo.cfg

!!!这一步是zk集群搭建最重要的配置,配置每个节点的信息,格式如下:
【server.myid=ip[/hostname]:port01:port02】

  • myid即为2)中的myid号
  • ip或者hostname为节点的ip或者hostname,如果使用hostname需要在hosts文件中配置
  • port01为follower与leader交换信息的端口
  • port02为leader不能使用时用来重新选举时使用的端口

本实验在三个节点的zoo.cfg同时增加如下内容:

server.153=zookeeper153:2888:3888
server.72=zookeeper72:2888:3888
server.86=zookeeper86:2888:3888

4.服务启动与选举策略

1)linux节点中启动与检查状态,并查看身份为leader还是follower:

# 启动
sh @{ZK_HOME}/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/zy/l30003394/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

# 查看状态,最后一行Mode表示身份
sh @{ZK_HOME}/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/lzq/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader

查看进程:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_linux_05

windows节点中,dos 窗口执行:

@{ZK_HOME}/bin/zkServer.cmd

查看端口:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_java_06


2)关于选举策略(一般集群节点数为奇数,假设为n):

– 第一次启动时:在(n+1)/2个节点启动成功时选出leader,为此时myid最大的节点
– 非第一次启动:

  • 一个follower(F)断开连接,leader与其他follower正常,F会尝试选举leader,但会被告知leader信息,仅仅需要重新与leader连接
  • leader(L)与所有follower断开连接,所有follower会尝试选举新leader,先后根据Epoch、Zxid、Sid大小确定最终的leader(类似字典排序的方法)

四、客户端操作

1.客户端启动

linux:

# 本地启动
sh zookeeper-3.5.7/bin/zkCli.sh
# 远程连接
sh zookeeper-3.5.7/bin/zkCli.sh -server zookeeper153:2181

windows:

# 本地启动
.\zookeeper-3.5.7\bin\zkCli.cmd
# 远程连接
.\zookeeper-3.5.7\bin\zkCli.cmd -server zookeeper153:2181

登录后如下:

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_hadoop_07

2.节点信息

使用 [get -s 节点]可查看节点信息,如:

[zk: localhost:2181(CONNECTED) 5] get -s /singer
singer
cZxid = 0x70000000b
ctime = Wed Jun 30 18:59:57 CST 2021
mZxid = 0x70000000b
mtime = Wed Jun 30 18:59:57 CST 2021
pZxid = 0x700000012
cversion = 5
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 3

参数说明:
singer 节点数据
cZxid :createZxid,节点创建的事务Zxid
ctime :节点创建的时间
mZxid :modifyZxid,节点最后更新的事务zxid
mtime:最后一次修改的时间
pZxid:最后更新的子节点zxid
cversion:子节点版本(修改次数)
dataVersion:数据版本(修改次数)
aclVersion:访问控制列表的变化号
ephemeralOwner:如果是临时节点,这个是節點拥有者的session id。如果不是临时节点则是0。
dataLength:數據長度
numChildren:子節點數量

3.节点类型与节点操作

1)节点类型

节点类型:

  • 持久型节点:断开连接,节点不删除
  • 临时性节点:断开连接,节点删除
  • 带序号节点
  • 不带序号节点

2)节点创建–create:

create 节点全路径 节点数据

  • -s指定带序号
  • -e指定临时节点
[zk: localhost:2181(CONNECTED) 10] create /china "chinese"
Created /china # 不带序号
[zk: localhost:2181(CONNECTED) 11] create -s /china "chinese"
Created /china0000000002  #带序号
[zk: localhost:2181(CONNECTED) 12] get -s /china
chinese
……
ephemeralOwner = 0x0 # 永久性节点
……
[zk: localhost:2181(CONNECTED) 13] create -e /america
Created /america
[zk: localhost:2181(CONNECTED) 14] get -s /america
null
……
ephemeralOwner = 0x9906a98cfa130002 #临时性节点
……

3)查看修改节点数据与删除节点–get/set/delete/deleteall

[zk: localhost:2181(CONNECTED) 16] get /china
chinese
[zk: localhost:2181(CONNECTED) 17] set /china "great" 
[zk: localhost:2181(CONNECTED) 18] get /china
great  
[zk: localhost:2181(CONNECTED) 19] delete /america
[zk: localhost:2181(CONNECTED) 20] ls /
[china, china0000000002, singer, zookeeper]
[zk: localhost:2181(CONNECTED) 21] deleteall /singer
[zk: localhost:2181(CONNECTED) 22]

4).获取监听器,可监听节点的数据变化或者子节点的变化

get -w 节点全路径

docker中zookeeper的配置文件在哪 zookeeper配置文件详解_hadoop_08

监听器只监听一次,需要继续监听要重新获取监听器

五、java代码实现节点基本操作

package com.my.zk;

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

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;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

public class myZkClient {
    String connStr = "zookeeper72:2181";
    // 可配置多个,不能有空格
    {connStr = "zookeeper72:2181,zookeeper72:2181,zookeeper72:2181";}
    int timeout = 2000;
    ZooKeeper zkClient;

    @Before
    public void zk01() throws IOException {
        zkClient = new ZooKeeper(connStr, timeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                // process里获取监听器应对监听器只能获取一次的弊端
                try {
                    System.out.println("----------");
                    System.out.println(zkClient.getChildren("/", true));
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Test
    public void zk02() throws KeeperException, InterruptedException {
        zkClient.delete("/Asia", -1); // 删除节点
        Stat exists = zkClient.exists("/Asia", false); // 节点不存在返回null
        System.out.println("节点存在的状态:"+exists);
        zkClient.create("/Asia","asia".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); // 创建节点
        Stat exists1 = zkClient.exists("/Asia", false);
        System.out.println("节点存在的状态:"+exists1);
    }

    @Test
    public void zk03() throws KeeperException, InterruptedException {
        List<String> children = zkClient.getChildren("/", true); // 获取监听器
        System.out.println(children);

        Thread.sleep(Long.MAX_VALUE); //防止进程退出不能监听
    }

}