zookeeper

版本:V 1.0

1、zookeeper简介

1.1 官网解释

官方地址:http://zookeeper.apache.org/
顾名思义:动物园管理员
Java高级-zookeeper - 图8

它是拿来管大象(Hadoop)、蜜蜂(Hive)、小猪(Pig)的管理员, Apache Hbase和Apache Solr以及阿里的Dubbo等项目中都采用到了Zookeeper。
Dubbo 推荐使用zookeeper 作为注册中心!
Zookeeper 是 Apache Hadoop 的子项目,是一个树型的目录服务,支持变更推送。
Java高级-zookeeper - 图9


一句话:ZooKeeper是一个分布式协调技术、高性能的,开源的分布式系统的协调(Coordination)服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用程序一致性和分布式协调技术服务的软件。

2、安装配置zookeeper

2.1 linux下安装zookeeper

2.1.1 官网下载安装包

下载地址:https://zookeeper.apache.org/releases.html#download

2.1.2 创建安装目录

mkdir /myzookeeper

2.1.3 拷贝进入到/myzookeeper目录下并解压

[root@localhost myzookeeper]# tar -zxvf zookeeper-3.4.14.tar.gz

2.1.4 进入conf文件夹,拷贝zoo_sample.cfg改为zoo.cfg

[root@localhost conf]# cp zoo_sample.cfg zoo.cfg

tickTime:通信心跳间隔,单位是毫秒,系统默认是2000毫秒,也就是间隔两秒心跳一次。
还可以控制Flower跟Leader的通信时间,默认情况下FL的会话时常是心跳间隔的两倍。
initLimit
默认值10
集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。
syncLimit:LF同步通信时限
默认值 5
集群中Leader与Follower之间的最大响应时间单位。
dataDir:数据文件目录+数据持久化路径
保存内存数据库快照信息的位置,如果没有其他说明,更新的事务日志也保存到数据库。
clientPort:客户端连接端口
默认2181
监听客户端连接的端口。

2.1.5 启动zookeeper

注意:zookeeper 是java 语言编写的,所以启动zookeeper时,必须先有java 环境!
进入到bin 目录执行
启动命令:
[root@localhost bin]# ./zkServer.sh start
是否真正启动成功可以查看进程
# ps –ef | grep zookeeper
Java高级-zookeeper - 图10
关闭命令:
[root@localhost bin]# ./zkServer.sh stop
查看状态:
[root@localhost bin]# ./zkServer.sh status

2.1.6 链接客户端

在bin 目录下面执行命令
[root@localhost bin]# ./zkCli.sh
Java高级-zookeeper - 图11
退出:
# quit 命令
Java高级-zookeeper - 图12

2.1.6.1 客户端基本命令使用

  1. ls / 查看+获得zookeeper服务器上的数据存储信息
    Java高级-zookeeper - 图13
    2. get /zookeeper 获取节点数据
    Java高级-zookeeper - 图14

    2.1.6.2 文件系统

    所使用的数据模型风格很像文件系统的目录树结构,简单来说,有点类似windows中注册表的结构,

    有名称,
    有树节点,
    有Key(键)/Value(值)对的关系,

    可以看做一个树形结构的数据库,分布在不同的机器上做名称管理。

    2.1.6.3 初识znode节点

    Java高级-zookeeper - 图15
    Java高级-zookeeper - 图16

    3、数据模型/znode节点深入

    3.1 Znode的数据模型

    3.1.1 是什么

    | Znode维护了一个stat结构,这个stat包含数据变化的版本号、访问控制列表变化、还有时间戳。版本号和时间戳一起,可让Zookeeper验证缓存和协调更新。每次znode的数据发生了变化,版本号就增加。 | | —- |

3.1.2 ZooKeeper的Stat结构体

Java高级-zookeeper - 图17
czxid- 引起这个znode创建的zxid,创建节点的事务的zxid(ZooKeeper Transaction Id)

每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。
事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么zxid1在zxid2之前发生。

ctime - znode被创建的毫秒数(从1970年开始)
mzxid - znode最后更新的zxid
mtime - znode最后修改的毫秒数(从1970年开始)
pZxid-znode最后更新的子节点zxid
cversion - znode子节点变化号,znode子节点修改次数
dataversion - znode数据变化号
aclVersion - znode访问控制列表的变化号
ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0x0。
dataLength- znode的数据长度
numChildren - znode子节点数量

案例:

1. 创建新的子节点,并添加数据
2. 获取新创建的子节点
3. 修改创建的子节点内容
4. 获取修改后的子节点内容
使用help 查看有哪些命令
Java高级-zookeeper - 图18
案例所对应的命令
1. create /test javademo1
2. get /test
3. set /test javademo2
4. get /test

3.2 Znode中的存在类型

create [-s] [-e] path data acl

3.2.1 PERSISTENT-持久化目录节点

客户端与zookeeper断开连接后,该节点依旧存在
# create /demo01 java01

3.2.2 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点

  1. 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号<br /># create -s /demo011 java011

3.2.3 EPHEMERAL-临时目录节点

客户端与zookeeper断开连接后,该节点被删除

# create -e /demo2 java2

3.2.4 EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点

客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
# create -s -e /demo03 /java03
默认情况下是持久化节点!

4、基础命令和Java客户端操作

4.1 zkCli的常用命令操作

  1. Help
    Java高级-zookeeper - 图19
    2. ls 使用 ls 命令来查看当前znode中所包含的内容
    3. ls2查看当前节点数据并能看到更新次数等数据
    4. stat查看节点状态
    5. set
    a) 设置节点的具体值
    b) set 节点 value值 set /test atguigu
    6. get
    a) 获得节点的值
    b) get 节点
    7. create
    a) 普通创建 create /test demo001
    b) -s含有序列
    c) -e 临时
    8. delete 删除无子节点的目录
    9. rmr 递归删除

    4.2 四字命令 [了解]

    4.2.1 是什么

    zookeeper支持某些特定的四字命令,他们大多是用来查询ZK服务的当前状态及相关信息的。
    通过telnet或nc向zookeeper提交相应命令,如:echo ruok | nc 127.0.0.1 2181
    运行公式:echo 四字命令 | nc 主机IP zookeeper端口
    如果显示no comm…nc错误:安装nc即可yum install nc

    4.2.2 常用命令

    | ruok:测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应
    stat:输出关于性能和连接的客户端的列表
    conf:输出相关服务配置的详细信息
    cons:列出所有连接到服务器的客户端的完全的连接 /会话的详细信息。包括“接受 / 发送”的包数量、会话id 、操作延迟、最后的操作执行等等信息
    dump:列出未经处理的会话和临时节点
    envi:输出关于服务环境的详细信息(区别于conf命令)
    reqs:列出未经处理的请求
    wchs:列出服务器watch的详细信息
    wchc:通过session列出服务器watch的详细信息,它的输出是一个与watch相关的会话的列表
    wchp:通过路径列出服务器 watch的详细信息。它输出一个与 session相关的路径 | | —- |

4.3 Java客户端操作

4.3.1 创建项目

创建一个maven 项目zk-demo
Java高级-zookeeper - 图20

4.3.2 添加依赖

修改pom.xml




com.101tec
zkclient
0.10



org.apache.zookeeper
zookeeper
3.4.9


log4j
log4j
1.2.17


4.3.3 代码部分

| public class ZkDemo {
private static final String CONNECTSTRING = “192.168.200.129:2181”;
private static final String PATH = “/atguigu”;
private static final int SESSION_TIMEOUT = 50*1000;

_// 连接zk 方法    _**public **ZooKeeper startZk() **throws **Exception{<br />        _//<br />        _**return new **ZooKeeper(**_CONNECTSTRING_**, **_SESSION_TIMEOUT_**, **new **Watcher() {<br />            @Override<br />            **public void **process(WatchedEvent event) {

        }<br />        });<br />    }<br />    _// 关闭zk 方法    _**public void **stopZk(ZooKeeper zooKeeper) **throws **Exception{<br />        **if **(zooKeeper!=**null**){<br />            zooKeeper.close();<br />        }<br />    }

_/**<br />     * 创建节点          * **@param **_**_zk _**_zk 对象     * **@param **_**_path _**_节点名称     * **@param **_**_nodeValue _**_节点数据     * **@throws **Exception<br />     */<br />    _**public void **createZNode(ZooKeeper zk,String path,String nodeValue) **throws **Exception{<br />        _// acl 表示权限 OPEN_ACL_UNSAFE 公开的权限        _zk.create(path,nodeValue.getBytes(), ZooDefs.Ids.**_OPEN_ACL_UNSAFE_**, CreateMode.**_PERSISTENT_**);<br />    }

_// 获取节点    _**public **String getZNode(ZooKeeper zk,String path)**throws **Exception{<br />        **byte**[] byteArray = zk.getData(path, **false**, **new **Stat());<br />        String data = **new **String(byteArray);<br />        System.**_out_**.println(data);<br />        **return **data;<br />    }

_// 调用    _**public static void **main(String[] args) **throws **Exception {<br />        ZkDemo zkDemo = **new **ZkDemo();<br />        _// 获取连接        _ZooKeeper zk = zkDemo.startZk();

    String zNode = **null**;<br />        Stat stat = zk.exists(**_PATH_**, **false**);<br />        **if **(stat==**null**){<br />            _// 创建节点            _zkDemo.createZNode(zk,**_PATH_**,**"java"**);<br />        }**else **{<br />            System.**_out_**.println(**"***********znode has already ok***********"**);<br />        }<br />        _// 获取节点数据        _zNode = zkDemo.getZNode(zk, **_PATH_**);<br />        System.**_out_**.println(**"**********result:"**+zNode);<br />        _// 关闭连接        _zkDemo.stopZk(zk);<br />    }<br />} |

| —- |

5、zookeeper 集群

伪分布式单机配置

5.1 说明

initLimit 是Zookeeper用它来限定集群中的Zookeeper服务器连接到Leader的时限
syncLimit 限制了follower服务器与leader服务器之间请求和应答之间的时限

服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口)
这个配置项的书写格式比较特殊,规则如下:server.N=YYY:A:B 其中,
N表示服务器编号,
YYY表示服务器的IP地址,
A为LF通信端口,表示该服务器与集群中的leader交换的信息的端口。
B为选举端口,表示选举新leader时服务器间相互通信的端口(当leader挂掉时,其余服务器会相互通信,选择出新的leader)

一般来说,集群中每个服务器的A端口都是一样,每个服务器的B端口也是一样。
下面是一个集群的例子:
server.0=233.34.9.144:2008:6008
server.1=233.34.9.145:2008:6008
server.2=233.34.9.146:2008:6008
server.3=233.34.9.147:2008:6008

但是当所采用的为伪集群时,IP地址都一样,只能是A端口和B端口不一样。
下面是一个伪集群的例子:
server.0=127.0.0.1:2008:6008
server.1=127.0.0.1:2007:6007
server.2=127.0.0.1:2006:6006
server.3=127.0.0.1:2005:6005

5.2 搭建集群

5.2.1 拷贝赋值

zookeeper-3.4.14.tar.gz解压后拷贝到/opt目录下并重新名为zk01。

[root@localhost myzookeeper]# mv zookeeper-3.4.14.tar.gz /opt/
[root@localhost opt]# tar -zxvf zookeeper-3.4.14.tar.gz
[root@localhost opt]# mv zookeeper-3.4.14 zk01

5.2.2 在zk01中的创建mydata文件夹

[root@localhost zk01]# mkdir mydata

5.2.3 新建zoo.cfg

[root@localhost conf]# cp zoo_sample.cfg zoo.cfg

5.2.4 修改zoo.cfg配置文件

Java高级-zookeeper - 图21

server.1=127.0.0.1:2991:3991
server.2=127.0.0.1:2992:3992
server.3=127.0.0.1:2993:3993

5.2.5 创建myId文件

在zk01的 mydata下面创建myid的文件,在里面写入server的数字
表示1号服务器

# vim myid
里面写1 然后退出并保存
Java高级-zookeeper - 图22


为了确保zk01 正确,我们可以启动测试一下
Java高级-zookeeper - 图23
关闭当前的zk01 服务
[root@localhost opt]# kill -9 4060

5.2.6 将zk01 赋值两份分别为zk02,zk03

-r 表示递归复制

[root@localhost opt]# cp -r zk01 zk02
[root@localhost opt]# cp -r zk01 zk03

5.2.7 修改zk02,zk03的zoo.cfg,myid配置文件

zk02
[root@localhost opt]# vim zk02/conf/zoo.cfg
Java高级-zookeeper - 图24
[root@localhost opt]# vim zk02/mydata/myid
Java高级-zookeeper - 图25
#zk03
[root@localhost opt]# vim zk03/conf/zoo.cfg
Java高级-zookeeper - 图26
[root@localhost opt]# vim zk03/mydata/myid
Java高级-zookeeper - 图27

5.2.8 启动集群

# vim startup.sh
/opt/zk01/bin/zkServer.sh start
/opt/zk02/bin/zkServer.sh start
/opt/zk03/bin/zkServer.sh start
:wq
# chmod +x startup.sh
./startup.sh
查看进程
# ps –ef |grep zookeeper

5.2.9 使用客户端链接集群

[root@localhost opt]# ./zk01/bin/zkCli.sh -server 127.0.0.1:2191
在客户端2191 中添加节点
Java高级-zookeeper - 图28
在客户端2192中查询
Java高级-zookeeper - 图29

5.2.10 可以通过状态查看节点的状态

[root@localhost opt]# ./zk01/bin/zkServer.sh status
Java高级-zookeeper - 图30

5.2.11 集群主机宕机情况测试

测试1:主机宕机
./zk02/bin/zkServer.sh stop
[root@localhost opt]# ./zk01/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zk01/bin/../conf/zoo.cfg
Mode: follower
[root@localhost opt]# ./zk02/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zk02/bin/../conf/zoo.cfg
Error contacting service. It is probably not running.
[root@localhost opt]# ./zk03/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zk03/bin/../conf/zoo.cfg
Mode: leader
[root@localhost opt]#

3号上位!
create /test01 test01

1,3都有数据。
测试2:主机活了
./zk02/bin/zkServer.sh start

[root@localhost opt]# ./zk02/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zk02/bin/../conf/zoo.cfg
Starting zookeeper … STARTED
[root@localhost opt]# ./zk01/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zk01/bin/../conf/zoo.cfg
Mode: follower
[root@localhost opt]# ./zk02/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zk02/bin/../conf/zoo.cfg
Mode: follower
[root@localhost opt]# ./zk03/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zk03/bin/../conf/zoo.cfg
Mode: leader
[root@localhost opt]#

查看2号机是否有数据同步?
[zk: 127.0.0.1:2192(CONNECTED) 0] ls /
[zookeeper, test, test01]