Zookeeper入门篇

Posted Fire king

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zookeeper入门篇相关的知识,希望对你有一定的参考价值。

Zookeeper特性:

  • Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。
  • 集群中只要有半数以上(不包括半数)节点存活,Zookeeper集群就能正常服务。
  • 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
  • 更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行。
  • 数据更新原子性,一次数据更新要么成功,要么失败(有事务特性)。
  • 实时性,在一定时间范围内,Client能读到最新数据。

Zookeeper的选举机制:
在这里插入图片描述
按照节点的生成顺序,如myid=1、myid=2…这都是有顺序的;当开始选举时,myid=1的节点肯定会投自己一票,然后发现票数没达到节点数的一半以上,继而轮到,myid=2的节点投自己一票,这时myid<2的节点也会投自己一票,这时发现票数还是没达到节点数的一半以上,又转向myid=3的节点投自己一票,根据之前的规律,myid<3的节点也会投自己一票,此时myid=3的节点已经有三票了,超过了节点数的一半,因此就被选举为leader,注意,此时虽然根据之前的规律,myid=4或者5的节点可能会获得更多的票数,但是myid=3的节点已经是leader了,所以它们就只能是follow。

问题:为什么推荐Zookeeper节点个数是奇数呢?
举个栗子:
有两个Zookeeper集群,一个有五个节点,另一个有六个节点。
倘若两个集群都是三个节点宕机,根据Zookeeper特性中集群中只要有半数以上(不包括半数)节点存活,Zookeeper集群就能正常服务,即半数机制。因此来说,两个集群都不能工作,但是拥有六个节点的集群多了维护一个节点的代价,所以说推荐Zookeeper节点个数是奇数。

节点类型

  • 持久(Persistent):客户端和服务器端断开连接后, 创建的节点不删除

  • 短暂(Ephemeral):客户端和服务器端断开连接后, 创建的节点自己删除
    在这里插入图片描述
    1.持久化节点分析:

  • 持久化目录节点 客户端与Zookeeper断开连接后,该节点依旧存在

  • 持久化顺序编号目录节点 客户端与Zookeeper断开连接后, 该节点依旧存在, 只是Zookeeper给该节点名称进行顺序编号
    2.临时节点分析:

  • 临时目录节点 客户端与Zookeeper断开连接后, 该节点被删除

  • 临时顺序编号目录节点 客户端与Zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号。

  • 说明:创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护。

  • 注意:在分布式系统中,顺序号可以被用于为所有的事件进行全局排序, 这样客户端可以通过顺序号推断事件的顺序。

  • 并不是说临时节点不好,只能说持久化节点和临时节点应用场景不同,因为持久化节点和临时节点的区别是Zookeeper断开连接后,该节点是否依旧存在,我们可以反过来运用规则:如果我们想知道某个客户端是否下线,就可以根据与客户端相连的节点是否存在来判断,因为在临时节点的规则中,客户端下线,连接必然断开,节点也将不复存在。

Zookeeper单机安装:
1.在centos中使用root用户创建zookeeper用户

useradd zookeeper
passwd zookeeper

2.zookeeper底层依赖于jdk,zookeeper用户登录后,根目录(/home/zookeeper)下先进行jdk的安装,jdk
使用jdk-8u131-linux-x64.tar.gz版本,上传并解压jdk

//解压jdk
tar -xzvf jdk-8u131-linux-x64.tar.gz

3.配置jdk环境变量

// vim打开 .bash_profile文件
vi .bash_profile
// 文件中加入如下内容
JAVA_HOME=/home/zookeeper/jdk1.8.0_131
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
// 使环境变量生效
. .bash_profile

4.检测jdk安装

// 敲如下命令,系统如图反馈说明安装成功
java -version

在这里插入图片描述
5.zookeeper使用zookeeper-3.4.10.tar.gz,上传并解压

// 解压zookeeper
tar -xzvf zookeeper-3.4.10.tar.g

6.为zookeeper准备配置文件

// 进入conf目录
cd /home/zookeeper/zookeeper-3.4.10/conf
// 复制配置文件
cp zoo_sample.cfg zoo.cfg
// zookeeper根目录下新建data目录
mkdir data
// vi 修改配置文件中的dataDir
// 此路径用于存储zookeeper中数据的内存快照、及事物日志文件
dataDir=/home/zookeeper/zookeeper-3.4.10/data

7.启动zookeeper

// 进入zookeeper的bin目录
cd /home/zookeeper/zookeeper-3.4.10/bin
// 启动zookeeper
./zkServer.sh start
//启动:zkServer.sh start
//停止:zkServer.sh stop
//查看状态:zkServer.sh status

8.通过zookeeper客户端操作zookeeper服务器(不然是无法使用相关命令的,如create)

[zookeeper@localhost bin]$ ./zkCli.sh

9.zookeeper安装的一些坑
1…/zkServer.sh start和./zkServer.sh status能用,zkServer.sh start和zkServer.sh status用不了

bash: zkServer.sh: command not found...

6种解决方法:
前面五种方法都要基于最后一种方法才可以成功

  • /home/zookeeper/.bash_profile中jdk的配置是否正确,执行source /home/zookeeper/.bash_profile生效环境变量(集群启动zk.Server.sh时,先把所有节点环境变量生效后才能启动)
  • 修改 zookeeper.out 权限,chmod a+xwr zookeeper.out完成之后,先关闭zkServer.sh stop,再启动 zkServer.sh start(zookeeper.out 文件在/home/zookeeper/zookeeper-3.4.10/bin下)
  • 去到zookeeper下面的data文件夹里面可能会有两个文件( 它也是一个文件夹),也可能只有一个( zookeeper_server.pid),删掉zookeeper_server.pid
  • 配置环境变量:vim /etc/profile ,添加:
export ZOO_HOME=/usr/local/zookeeper-3.4.6
 export PATH=$ZOO_HOME/bin:$PATH

然后 source /etc/profile

  • 在zookeeper用户下操作,很多人都在root操作,这是不行的,你的zookeeper安装在zookeeper用户下

zookeeper常用Shell命令
1.新增节点

create [-s] [-e] path data #其中-s 为有序节点,-e 临时节点

创建持久化节点并写入数据:

create /hadoop "123456"

创建持久化有序节点,此时创建的节点名为指定节点名 + 自增序号

[zk: localhost:2181(CONNECTED) 26] delete  /a0000000001
[zk: localhost:2181(CONNECTED) 27] delete  /b0000000002
[zk: localhost:2181(CONNECTED) 28] delete  /c0000000003
#验证了自增序号
[zk: localhost:2181(CONNECTED) 29] create -s /a "aaa"
Created /a0000000005
[zk: localhost:2181(CONNECTED) 30] create -s /b "bbb"
Created /b0000000006
[zk: localhost:2181(CONNECTED) 33] create -s /c "ccc"
Created /c0000000007

创建临时节点,临时节点会在会话过期后被删除:

[zk: localhost:2181(CONNECTED) 6] create -e /tmp "tmp"
Created /tmp

[zk: localhost:2181(CONNECTED) 0] ls /
[c0000000007, hadoop, zookeeper, b0000000006, a0000000005]

创建临时有序节点,临时节点会在会话过期后被删除:

[zk: localhost:2181(CONNECTED) 1] create -s -e /aa 'aaa'
Created /aa0000000008
[zk: localhost:2181(CONNECTED) 2] create -s -e /bb 'bbb'
Created /bb0000000009
[zk: localhost:2181(CONNECTED) 3] create -s -e /cc 'ccc'
Created /cc0000000010

[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper, b0000000006, c0000000007, hadoop, a0000000005]

2.更新节点
更新节点的命令是 set ,可以直接进行修改,如下:

[zk: localhost:2181(CONNECTED) 9] set  /hadoop "564"
cZxid = 0x2
ctime = Wed Mar 31 03:43:53 EDT 2021
mZxid = 0x20
mtime = Wed Mar 31 22:38:50 EDT 2021
pZxid = 0xf
cversion = 2
dataVersion = 6
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

也可以基于版本号进行更改,此时类似于乐观锁机制,当你传入的数据版本号
(dataVersion) 和当前节点的数据版本号不符合时,zookeeper 会拒绝本次修改:

[zk: localhost:2181(CONNECTED) 11] set  /hadoop "563" 5
version No is not valid : /hadoop

3.删除节点
删除节点的语法如下:

[zk: localhost:2181(CONNECTED) 12] delete /hadoop
[zk: localhost:2181(CONNECTED) 13] ls /
[zookeeper, b0000000006, c0000000007, a0000000005]

[zk: localhost:2181(CONNECTED) 14] delete /a0000000005 5
version No is not valid : /a0000000005

要想删除某个节点及其所有后代节点,可以使用递归删除,命令为rmr path
4.查看节点
get path

[zk: localhost:2181(CONNECTED) 15] get /a0000000005
aaa
cZxid = 0x16
ctime = Wed Mar 31 22:01:05 EDT 2021
mZxid = 0x16
mtime = Wed Mar 31 22:01:05 EDT 2021
pZxid = 0x16
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

节点各个属性如下表。其中一个重要的概念是 Zxid(ZooKeeper Transaction
Id),ZooKeeper 节点的每一次更改都具有唯一的 Zxid,如果 Zxid1 小于 Zxid2,则
Zxid1 的更改发生在 Zxid2 更改之前。
状态属性 说明
cZxid 数据节点创建时的事务 ID
ctime 数据节点创建时的时间
mZxid 数据节点最后一次更新时的事务 ID
mtime 数据节点最后一次更新时的时间
pZxid 数据节点的子节点最后一次被修改时的事务 ID
cversion 子节点的更改次数
dataVersion 节点数据的更改次数
aclVersion 节点的 ACL 的更改次数
ephemeralOwner
如果节点是临时节点,则表示创建该节点的会话的
SessionID;如果节点是持久节点,则该属性值为 0
dataLength 数据内容的长度
numChildren 数据节点当前的子节点个数

5.查看节点状态
可以使用 stat 命令查看节点状态,它的返回值和 get 命令类似,但不会返回
节点数据

[zk: localhost:2181(CONNECTED) 16] stat /a0000000005
cZxid = 0x16
ctime = Wed Mar 31 22:01:05 EDT 2021
mZxid = 0x16
mtime = Wed Mar 31 22:01:05 EDT 2021
pZxid = 0x16
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

6.查看节点列表
查看节点列表有 ls pathls2 path 两个命令,后者是前者的增强,不仅可
以查看指定路径下的所有节点,还可以查看当前节点的信息

[zk: localhost:2181(CONNECTED) 2] ls /
[zookeeper, b0000000006, c0000000007, a0000000005]
[zk: localhost:2181(CONNECTED) 3] ls2 /
[zookeeper, b0000000006, c0000000007, a0000000005]
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x23
cversion = 18
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

7.监听器get path [watch](哪个会话设置的监听哪个会话才能收到信息)
使用 get path [watch] 注册的监听器能够在节点内容发生改变的时候,向客
户端发出通知。需要注意的是 zookeeper 的触发器是一次性的 (One-time trigger),即
触发一次后就会立即失效。

[zk: localhost:2181(CONNECTED) 20] get /hadoop "123" watch
123
cZxid = 0x25
ctime = Wed Mar 31 22:49:29 EDT 2021
mZxid = 0x25
mtime = Wed Mar 31 22:49:29 EDT 2021
pZxid = 0x25
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 21]
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop#节点
值改变

[zk: localhost:2181(CONNECTED) 4] set /hadoop "456"
cZxid = 0x25
ctime = Wed Mar 31 22:49:29 EDT 2021
mZxid = 0x26
mtime = Wed Mar 31 22:50:27 EDT 2021
pZxid = 0x25
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

acl超级管理员模式:
zookeeper的权限管理模式有一种叫做super,该模式提供一个超管可以方便的访问任何权限的节点

以上是关于Zookeeper入门篇的主要内容,如果未能解决你的问题,请参考以下文章

springboot+Zookeeper+Dubbo入门

从入门到精通的ActiveMQ

c语言入门到入门,hello world篇

什么是ZooKeeper?

推荐net开发cad入门阅读代码片段

consul入门篇