zookeeper使用教程

zookeeper使用教程

什么是 zookeeper

zookeeper 是一个开源的分布式协调服务,由雅虎公司创建,是 google chubby 的开源实现。zookeeper 的设计目
标是将哪些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集(由若干条指令组成的,完成
一定功能的一个过程),并且以一些列简单一用的接口提供给用户使用。

zookeeper 安装部署

zookeeper 有两种运行模式:集群模式和单机模式。
下 载 zookeeper 安装包:
http://apache.fayea.com/zookeeper/
下载完成,通过 tar -zxvf 解压

单机环境安装

一般情况下,在开发测试环境,没有这么多资源的情况下,而且也不需要特别好的稳定性的前提下,我们可以使用单机部署;
初次使用zookeeper ,需要将conf目录下的zoo_sample.cfg 文件 copy 一份重命名为 zoo.cfg修改 dataDir 目录,dataDir 表示日志文件存放的路径
启动zookeeper即为单机环境

集群环境安装

角色

在 zookeeper 集群中,各个节点总共有三种角色,分别是:
Leader,Follower,Observer

Leader角色

Leader服务器是整个zookeeper集群的核心,主要的工作任务有两项

1、事物请求的唯一调度和处理者,保证集群事物处理的顺序性

2、集群内部各服务器的调度者

Follower角色

Follower角色的主要职责是

1、处理客户端非事务请求、转发事物请求给Leader服务器

2、参与事物请求Proposal的投票(需要半数以上服务器通过才能通知leader commit数据;Leader发起的提案,要求Follower投票)

3、参与Leader选举的投票

Observer角色

Observer是zookeeper3.3开始引入的一个全新的服务器角色,从字面来理解,该角色充当了观察者的角色。

观察zookeeper集群中的最新状态变化并将这些状态变化同步到Observer服务器上。

Observer的工作原理与Follower角色基本一致,而它和Follower角色唯一的不同在于Observer不参与任何形式的投票,包括事务请求、Proposal的投票和Leader选举的投票。

简单来说,observer服务器只提供非事物请求服务,通常在于不影响集群事物处理能力的前提下提升集群非事物处理的能力

搭建

通常zookeeper是由2n+1台server组成,每个server都知道彼此的存在,每个server都维护的内存状态镜像以及持久化存储的事务日志和快照。

对于2n+1台server,只要有n+1台(大多数)server可用,整个系统保持可用。一个zookeeper集群如果要对外提供可用的服务,那么集群中必须要有过半的机器正常工作并且彼此之间能够正常通信,基于这个特性,如果向搭建一个能够允许F台机器down掉的集群,那么就要部署2*F+1台服务器构成的zookeeper集群。

因此3台机器构成的zookeeper集群,能够在挂掉一台机器后依然正常工作。一个5台机器集群的服务,能够对2台机器怪调的情况下进行容灾。如果一台由6台服务构成的集群,同样只能挂掉2台机器。因此,5台和6台在容灾能力上并没有明显优势,反而增加了网络通信负担。

系统启动时,集群中的server会选举出一台server为Leader,其它的就作为follower(这里先不考虑observer角色),之所以要满足这样一个等式,是因为一个节点要成为集群中的leader,需要有超过及群众过半数的节点支持,这个涉及到leader选举算法。同时也涉及到事务请求的提交投票。

这里集群模式采用模拟 3 台机器来搭建 zookeeper 集群。

分别复制安装包到三台机器上并解压,同时 copy 一份zoo.cfg

  • 修改配置文件和端口
1
2
3
server.1=IP1:2888:3888 #2888:访问 zookeeper 的端口;3888:重新选举 leader 的端口
server.2=IP2.2888:3888
server.3=IP3.2888:2888

server.A=B:C:D:
A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader
服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能
一样,所以要给它们分配不同的端口号。在集群模式下,集群中每台机器都需要感知到整个集群是由哪几台机器组成的,在配置文件中,按照格式
server.id=host:port:port,每一行代表一个机器配置id:指的是 server ID,用来标识该机器在集群中的机器序号

  • 新建 datadir 目录,设置 myid 在每台zookeeper机器上,我们都需要在数据目录(dataDir)
    下创建一个 myid 文件,该文件只有一行内容,对应每台机器的 Server ID 数字;
    比如 server.1 的 myid 文件内容就是1。必须确保每个服务器的 myid 文件中的数字不同,并且和自己所在机器的 zoo.cfg 中 server.id 的 id 值一致,id 的范围是 1~255

  • 启动 zookeeper

带 Observer 角色的集群

Observer:在不影响写性能的情况下扩展 zookeeper本身 zookeeper 的集群性能已经很好了,但是如果超大量的客户端访问,就势必需要增加 zookeeper 集群的服务器数量,而随着服务器的增加,zookeeper 集群的写性能就会下降;zookeeper 中 znode 的变更需要半数及以上服务器投票通过,而随着机器的增加,由于网络消耗等原因必定会导致投票成本增加,也就导致性能下降的结果

常用命令

启动 ZK 服务

1
bin/zkServer.sh start

查看 ZK 服务状态

1
bin/zkServer.sh status

停止 ZK 服务

1
bin/zkServer.sh stop

重启 ZK 服务

1
bin/zkServer.sh restart

连接服务器

1
zkCli.sh -timeout 0 -r -server ip:port

zkCli内常用命令

help 帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ZooKeeper -server host:port cmd args
stat path [watch] #获得节点的更新信息
set path data [version] #修改节点
ls path [watch]
delquota [-n|-b] path
ls2 path [watch] #ls命令和stat命令的整合
setAcl path acl #设置权限
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version] # 删除节点
sync path
listquota path
rmr path
get path [watch] #设置watch事件
create [-s] [-e] path data acl # 创建节点
addauth scheme auth
quit
getAcl path #获取某个节点的acl权限信息
close
connect host:port

ls 查看节点命令

1
ls path

节点除了存储数据内容以外,还存储了数据节点本身的一些状态信息,通过get命令可以获得状态信息的详细内容,获取内容的首行为空行说明节点内容为空

1
2
3
4
5
6
7
8
9
10
11
cZxid :创建节点的id
ctime : 节点的创建时间
mZxid :修改节点的id
mtime :修改节点的时间
pZxid :子节点的id
cversion : 子节点的版本
dataVersion : 当前节点数据的版本
aclVersion :权限的版本
ephemeralOwner :判断是否是临时节点
dataLength : 数据的长度
numChildren :子节点的数量
1
get path

create -e 创建临时节点

1
create -e path data

create -s 创建顺序节点 自动累加

1
create -s path data

Zookeeper的节点特性

临时节点

持久化节点

有序节点(递增的序列号)

先有父节点,再有子节点

临时节点下不能存在子节点

同级节点下,节点名字必须是唯一

watcher通知机制

zookeeper提供了分布式数据的发布/订阅功能,zookeeper允许客户端向服务端注册一个watcher监听,当服务端的一些指定事件触发了watcher,那么服务端就会向客户端发送一个事件通知。

zookeeper提供以下几种命令来对指定节点设置监听。

get [-s] [-w] path:监听指定path节点的修改和删除事件,同样该事件也是一次性触发。

1
2
3
4
get -w /node
#在其他窗口执行下面命令,会触发相关事件
set /node 123
delete /node

ls [-s] [-W] [-R] path:监控指定path的子节点的添加和删除事件。

1
2
3
4
1s -w /node
#在其他窗口执行下面命令,会触发相关事件
create /node/node1
delete /node/node1

注意:当前命令设置的监听是一次性的,就是说一旦触发了一次事件监听,后续的事件都不会响应,当然我们可以通过重复订阅来解决

stat [-w] path:作用和get完全相同。

addWatch [-m mode] path

addWatch的作用是针对指定节点添加事件监听,支持两种模式

  • PERSISTENT,持久化订阅,针对当前节点的修改和删除事件,以及当前节点的子节点的删除和新增事件。
  • PERSISTENT_RECURSIVE,持久化递归订阅,在PERSISTENT的基础上,增加了子节点修改的事件触发,以及子节点的子节点的数据变化都会触发相关事件(满足递归订阅特性)

可以参考zookeeper 中 Watcher 通知机制的一点理解

Session会话机制

如图所示,表示Zookeeper的session会话状态机制。

首先,客户端向ZookeeperServer发起连接请求,此时状态为CONNECTING。

当连接建立好之后,Session状态转化为CONNECTED,此时可以进行数据的IO操作。

如果Client和Server的连接出现丢失,则Client又会变成CONNECTING状态。

如果会话过期或者主动关闭连接时,此时连接状态为CLOSE。

如果是身份验证失败,直接结束。

image-20210828173028504

ACL权限控制

Zookeeper作为一个分布式协调框架,内部存储了一些分布式系统运行时的状态的数据,比如master选举、比如分布式锁。

对这些数据的操作会直接影响到分布式系统的运行状态。因此,为了保证zookeeper中的数据的安全性,避免误操作带来的影响。Zookeeper提供了一套ACL权限控制机制来保证数据的安全。

使用[scheme:id:permissions]来表示acl权限

  • scheme(权限模式)

  • 标识授权策略ID(授权对象)

  • Permission:授予的权限

ZooKeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限,每个znode支持设置多种权限控制方案和多个权限,子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点。

ZK的节点有5种操作权限:CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,这5种权限简写为crwda(即:每个单词的首字符缩写)。

注:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限

身份的认证有4种方式:

  • world:默认方式,相当于全世界都能访问
  • auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd来添加当前上下文中的授权用户)
  • digest:即用户名:密码这种方式认证,这也是业务系统中最常用的
  • ip:使用Ip地址认证

getAcl获取某个节点的acl权限信息

1
getAcl path

setAcl 设置权限

1
2
3
setAcl path acl
#例如
setAcl path world:anyone:crwa #设置节点权限 crwa 不允许删除

Zookeeper可以解决那些实际问题

有序节点的使用场景

有序节点:全局ID

分布式锁

分布式队列

同级节点的唯一性

master选举

分布式锁

参考

Zookeeper基础命令操作

打赏

请我喝杯咖啡吧~

支付宝
微信