0


Zookeeper简单使用

Zookeeper

一、zookeeper简述

大型分布式计算开源的分布式配置服务,同步服务和命令注册。

架构通过冗余实现高可用。

目标:将那些负载且容易出错的分布式一致性服务封装其拉力,构成一个高效可靠的原语集,以一系列简单易用的接口提供给用户使用。

一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命令服务、分布式协调/通知,集群管理、master选举、分布式锁和分布式队列等。

1.1 zookeeper数据结构

它提供的名称空间类似标准文件系统,k-v的形式存储。名称key由斜线 / 分割的一系列路径元素,zookeeper名称空间中的每个节点都是由一个路径标识。

1.2 CAP理论

CAP理论分布式计算系统来说,不可能同时满足三点。

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

一致性: 一致性是指数据在多个副本之间是否能够保持一致的特性,等同于所有节点访问同一份最新的数据副本。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。

可用性: 每次请求都能获取到正确的响应,但是不保证获取的数据为最新数据。

分区容错性: 分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。

在这三个基本需求中,最多只能同时满足其中的两项,P 是必须的,因此只能在 CP 和 AP 中选择,zookeeper 保证的是 CP,对比 spring cloud 系统中的注册中心 eruka 实现的是 AP。

1.3 BASE理论

BASE 是 Basically Available(基本可用)、Soft-state(软状态) 和 Eventually Consistent(最终一致性) 三个短语的缩写。

基本可用:分布式系统出现故障,允许损失部分可用性(服务降级、页面降级)。

软状态:允许分布式系统出现中间状态,而且中间状态不影响系统的可用性。

最终一致性: data replications 经过一段时间达到一致性 。

二、zookeeper数据模型znode结构详解

2.1数据模型

zookeeper中的所有存储的数据由znode组成,节点称为znode,并以key/value形式存储数据。

整体结构类似linux的文件系统模式 以树形结构存储。 其中根路径以 / 开头。

进入zookeeper安装的bin的目录,通过sh zkCli.sh 打开命令行终端,执行 “ls /”命令显示。

[gallery ids="114"]

三、zookeeper session基本原理

客户端与服务器之间的连接是基于TCP长连接,client端连接server端默认的2181端口,也就是session会话。

从第一次连接建立开始,客户端开始会话的生命周期,客户端向服务端的ping包请求,每个会话都可以设置一个超时时间。

3.1 Session的创建

sessionID:会话ID,用来唯一标识一个会话, 每次客户端创建会话的时候,zookeeper 都会为其分配一个全局唯一的 sessionID 。

timeout:会话超时时间。客户端再构造zookeeper实例时候,向服务端发送配置的超时时间,server端会根据自己的超时时间限制最终确认会话的超时时间。

TickTime:下次会话超时时间点,默认200ms。 在 zoo.cfg 配置文件中配置,便于 server 端对 session 会话实行分桶策略管理

isClosing:该属性标记一个会话是否已经被关闭,当server端检测到灰灰啊已经超时失效,该会话标记为‘已关闭’,不再处理该会话的新请求。

3.2 session的状态

connecting:连接中,session一旦建立,状态就是connecting状态,时间很短。

connected:已连接,连接成功之后的状态。

closed:已关闭,发生在session过期,一般由于网络故障客户端重连失败,服务器宕机或者客户端主动断开。

3.3 会话超时管理(分桶策略和会话激活)

leader服务再运行期间定时进行会话超时检查,时间间隔是 ExpirationInterval ,单位是毫秒。 默认值是 tickTime,每隔 tickTime 进行一次会话超时检查。

ExpirationTime 的计算方式:

 ExpirationTime = CurrentTime + SessionTimeout;
 ExpirationTime = (ExpirationTime / ExpirationInterval + 1) * ExpirationInterval;

zookeeper 运行过程中,客户端会在会话超时过期范围内向服务器发送请求(包括读和写)或者 ping 请求,俗称心跳检测完成会话激活,从而来保持会话的有效性。

会话激活流程:

[gallery ids="115"]

激活后进行迁移会话的过程,然后开始新一轮:

[gallery ids="116"]

四、zookeeper客户端基础命令使用

4.1 进入终端

首先执行命令,打开新的session会话,进入终端。一般这个脚本再zookeeper的bin目录下。

/data/zookeeper/bin/

 $ sh zkCli.sh

4.2 ls命令

ls 命令查看某个路径下目录列表

 #格式
 ls path
 -- path:代表路径
 ​
 #实例,查看根目录下的文件。
 [zk: localhost:2181(CONNECTED) 0] ls /
 [zk, zookeeper, redisExpired, msg-send-task, estask, mascloud, canal-adapter, codis3, disp, otter]
 [zk: localhost:2181(CONNECTED) 1] 
 ​
 ​

4.3 ls2 命令

ls2命令用于查看某个路径下目录列表,它比ls命令列出更多的详细信息。

 #格式
 ls2 path
 --path:代表路径
 [zk: localhost:2181(CONNECTED) 3] ls2 /mascloud/conf/gw/0/e186cfc2a5ae4ffd89fd736c92e6eb4a
 []
 cZxid = 0x90008ae12
 ctime = Fri Apr 08 16:30:53 CST 2022
 mZxid = 0x90008ae12
 mtime = Fri Apr 08 16:30:53 CST 2022
 pZxid = 0x90008ae12
 cversion = 0
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 405
 numChildren = 0
 ​
 #与ls2 区别对比
 [zk: localhost:2181(CONNECTED) 4] ls /mascloud/conf/gw/0/e186cfc2a5ae4ffd89fd736c92e6eb4a     
 []
 ​
 ​

4.4 get命令

get命令用于获取节点数据和状态信息

 #格式
 get path [watch]
 -path: 路径
 -watch:对节点进行事件监听。
 ​
 [zk: localhost:2181(CONNECTED) 5] get /mascloud/conf/gw/0/e186cfc2a5ae4ffd89fd736c92e6eb4a watch
 {"accessKey":"110210","conn":2,"ecId":"mobanFIF","extProps":{"vipgw":"false"},"flowLimit":1,"flowPeriod":1000,"group":5,"gwId":"e186cfc2a5ae4ffd89fd736c92e6eb4a","host":"192.168.0.31","maxContentBytesForAsc":159,"maxContentBytesForGbk":140,"maxRetryNums":0,"maxSrcIdLength":21,"mtSrcId":"106933355632","ot":false,"port":27881,"protocol":"gw_cmpp_v2.0","secretKey":"123123","share":false,"uniqId":"110210"}
 cZxid = 0x90008ae12
 ctime = Fri Apr 08 16:30:53 CST 2022
 mZxid = 0x90008ae12
 mtime = Fri Apr 08 16:30:53 CST 2022
 pZxid = 0x90008ae12
 cversion = 0
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 405
 numChildren = 0
 ​

4.5 stat命令

stat命令用于查看节点状态信息

 #格式
 stat path [watch]
 -path:路径
 -watch:对节点进行事件监听
 ​
 [zk: localhost:2181(CONNECTED) 10] stat /mascloud watch
 cZxid = 0x100003880
 ctime = Mon Mar 28 17:02:04 CST 2022
 mZxid = 0x100003880
 mtime = Mon Mar 28 17:02:04 CST 2022
 pZxid = 0xd3016d489e
 cversion = 7
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 0
 numChildren = 3
 ​

4.6 create命令

create 命令用于创建节点并赋值

 #格式
 create [-s] [-e] path data acl
 ​
 [-s] [-e]:-s和-e都是可选的,-s代表顺序节点,注意其中-s和-e可以同时使用,并且临时节点不能再创建子节点。
 ​
 path:指定要创建节点的路径,比如/mascloud
 ​
 data:要再此节点存储的数据
 ​
 acl:访问权限相关,默认world,相关于全世界都能访问。
 ​
 ~# create -s -e /runoob 0
 ​
 注:创建的节点既是有序,又是临时节点。
 ​

4.7 set命令

set命令用于修改节点存储的数据

 #格式
 set path data [version]
 -path:节点路径
 -data:需要存储的数据
 -[version]:可选项,版本号(可用乐观锁)
 ​
 #只有正确的版本号才能设置成功
 set /runoob 0 1
 set /runoob 0 2
 set /runoob 0 6
 ​

4.8 delete命令

delete命令用于删除某节点。

 delete path [version]
 ​
 -path:节点路径
 -version: 可选项,版本号(同set命令)
 ​
 #实例
 ~# ls /runoob
 ~# delete /runoob/child
 ~# get /runoob/child  (get not exist)
 ​

五、zookeeper四字命令

zookeeper支持某些特定的四字命令与其交互, 用户获取 zookeeper 服务的当前状态及相关信息,用户在客户端可以通过 telenet 或者 nc(netcat) 向 zookeeper 提交相应的命令。

 安装nc命令:
     #yum install nc        # centos
     #sudo apt install netcat  #ubuntu
 ​

四字命令格式:

 echo [ command ] | nc [ip] [port]

zookeeper常用四字命令主要如下:

四字命令使用

stat命令

stat命令用于查看zk的状态信息,

 ~$ echo stat | nc ip port
 ​

ruok命令

用于查看当前zkserver是否启动,若返回imok标识正常,

 ~$ echo ruok | nc ip port
 ​

dump 命令

用于列出未经处理的会话和临时节点。

 ~$ echo dump | nc ip port
 ​

conf命令

用于查看服务器配置

 ~$ echo cons | nc ip port
 ​

cons命令

用于展示连接到服务器的客户端信息。

 ~$ echo cons | nc ip port

envi命令

用于查看环境变量

 ~$ echo envi | nc ip port

六、zookeeper节点特性

6.1 同一级节点key名称是唯一的

 #实例
 [zk: localhost:2181(CONNECTED) 2] ls /
 [runoob, zookeeper]
 [zk: localhost:2181(CONNECTED) 3] create /runoob 2
 Node already exists: /runoob
 ​
 - 注:已存在/runoob节点,再次创建会提示已经存在

6.2 创建节点时,必须要带上全路径

 #实例
 $ ls /data
 ​
 $ create /data/mysql 0
 $ create /data/mysql/mysql01 0
 ​

6.3 session关闭,临时节点清除

 $ ls /data
 $ create -e /data/mysql02 0
 ​
 #实例
 #终端一
 [zk: localhost:2181(CONNECTED) 12] ls /data
 [mysql]
 [zk: localhost:2181(CONNECTED) 13] create -e /data/mysql02 0
 Created /data/mysql02
 ​
 ​
 #同时终端二查看该节点
 [zk: localhost:2181(CONNECTED) 1] ls /data
 [mysql, mysql02]
 ​
 #ctrl+c 关闭终端一连接后,查询终端二/data/mysql02 节点消失
 [zk: localhost:2181(CONNECTED) 6] ls /data
 [mysql]
 ​

6.4 自动创建顺序节点

 $ create -s -e /runoob 0
 [zk: localhost:2181(CONNECTED) 0] ls /
 [data, runoob, zookeeper]
 [zk: localhost:2181(CONNECTED) 1] create -s -e /runoob 0
 Created /runoob0000000002
 [zk: localhost:2181(CONNECTED) 2] create -s -e /runoob 0
 Created /runoob0000000003
 [zk: localhost:2181(CONNECTED) 3] create -s -e /runoob 0
 Created /runoob0000000004
 [zk: localhost:2181(CONNECTED) 4] create -s -e /runoob 0
 Created /runoob0000000005
 ​

6.5 watch 机制,监听节点变化

事件监听机制类似观察者模式,watch流程时客户端向服务端某个节点路径上注册一个watcher,同时客户端也会存储特定的watcher,当节点数据或子节点发生变化时,服务端通知客户端,客户端进行回调处理。特别注意:监听事件被单次触发后,事件就失效。

6.6 delete 命令只能一层一层的删除

 ls /
 delete /data
 ​
 [zk: localhost:2181(CONNECTED) 14] delete /data
 Node not empty: /data
 ​
 # 提示:新版本可以通过deleteall 命令递归删除

最后zookeeper可以应用在不同的经典应用场景

 1、数据发布/订阅
 2、负载均衡
 3、分布式协调通知
 4、集群管理
 5、master管理
 6、分布式锁
 7、分布式队列

七、zookeeper权限控制ACL

ACL权限可以针对节点设置相关读写等权限,保障数据安全性。

permissions可以指定不同的权限范围及角色

7.1 ACL命令行

  • getAcl命令:获取某个节点的acl权限信息
 [zk: localhost:2181(CONNECTED) 6] getAcl /zk/codis/db_cmas/proxy
 'world,'anyone
 : cdrwa
 [zk: localhost:2181(CONNECTED) 7] ls /
 [zk, zookeeper, redisExpired, msg-send-task, estask, mascloud, canal-adapter, codis3, disp, otter]
 ​
  • setAcl命令:设置某个节点的acl权限信息
 setAcl path acl
  • addauth命令:输入认证授权信息,注册时输入明文密码,加密形式保存。
 addauth scheme auth

7.2ACL构成

zookeeper的acl通过【scheme:id : permissions】来构成权限列表。

1、scheme:代表采用的某种权限机制,包括world、auth、digest、IP、super几种。

2、id:代表允许访问的用户。

3、permissions:权限组合字符串,由cdrwa组成,其中每个字母代表支持不同权限,创建权限create(c)、删除权限delete(d)、读权限read(r)、写权限write(w)、管理权限admin(a)。

world实例

查看默认节点权限,在更新节点permissions权限部分crwa,结果删除节点失败。

 $ getAcl /data/mysql
 ​
 $ setAcl /data/mysql world:anyone:crwa
 ​
 $delete /data/mysql
 ​
 #实例
 [zk: localhost:2181(CONNECTED) 36] getAcl /data/mysql
 'world,'anyone
 : cdrwa
 [zk: localhost:2181(CONNECTED) 37] setAcl /data/mysql world:anyone:crwa
 [zk: localhost:2181(CONNECTED) 38] 
 [zk: localhost:2181(CONNECTED) 39] delete /data/mysql
 Node not empty: /data/mysql
 ​
 [zk: localhost:2181(CONNECTED) 44] delete /data/mysql/myslq01 
 Insufficient permission : /data/mysql/myslq01
 ​

auth实例

auth用于授予权限,注意需要先创建用户

 $setAcl /data/mysql/mysql01 auth:user1:123456:cdrwa
 $addauth digest user1:123456
 $setAcl /data/mysql/mysql01 auth:user1:123456:cdrwa
 $getAcl /data/mysql/mysql01
 ​
 [zk: localhost:2181(CONNECTED) 45] setAcl /data/mysql/myslq01 auth:user1:123456:cdrwa
 Acl is not valid : /data/mysql/myslq01
 [zk: localhost:2181(CONNECTED) 46] addauth digest user1:123456
 [zk: localhost:2181(CONNECTED) 47] setAcl /data/mysql/myslq01 auth:user1:123456:cdrwa
 [zk: localhost:2181(CONNECTED) 48] getAcl /data/mysql/myslq01 
 'digest,'user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s=
 : cdrwa
 [zk: localhost:2181(CONNECTED) 49] 
 ​

digest实例

退出当前用户,重新连接终端,digest可用于账号密码登陆和验证。

 #提示:加密密码是上一步创建的。
 $ ls /runoob
 $ create /runoob/child01 runoob
 $ getAcl /runoob/child01
 $ setAcl /runoob/child01 digest:user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s=:cdra
 $ getAcl /runoob/child01
 $ addauth digest user1:123456
 $ getAcl /runoob/child01
 ​
 [zk: localhost:2181(CONNECTED) 0] getAcl /runoob/child01 
 Insufficient permission : /runoob/child01
 [zk: localhost:2181(CONNECTED) 1] addauth digest user1:123456
 [zk: localhost:2181(CONNECTED) 2] getAcl /runoob/child01 
 'digest,'user1:HYGa7IZRm2PUBFiFFu8xY2pPP/s=
 : cdrwa
 [zk: localhost:2181(CONNECTED) 3] 
 ​

IP实例

限制IP地址的访问权限,把权限设置给IP地址为192.168.3.7后,IP为192.168.3.38已经没有访问权限

 create /runoob/ip 0
 getAcl /ruboob/ip
 setAcl /ruboob/ip ip:192.168.3.7:cdrwa
 get /runoob/ip
 ​
 [zk: localhost:2181(CONNECTED) 4] create /runoob/ip 0
 Created /runoob/ip
 [zk: localhost:2181(CONNECTED) 5] getAcl /runoob/ip 
 'world,'anyone
 : cdrwa
 [zk: localhost:2181(CONNECTED) 7] setAcl /runoob/ip ip:10.0.0.200:cdrwa
 [zk: localhost:2181(CONNECTED) 8] get /runoob/ip
 Insufficient permission : /runoob/ip
 ​

八、zookeeper数据同步流程

在zookeeper中,主要依赖ZAB协议来实现分布式数据一致性

ZAB协议分两部分:

  • 消息广播
  • 崩溃恢复

8.1 消息广播

zookeeper使用单一的主进程Leader来接收和处理客户端所有事务请求,并采用ZAB协议的原子广播协议,将事务请求以Proposal提议广播到所有Follower节点,当集群中有过半的Follower服务器进行正确的ACK反馈,那么Leader就会再次向所有的Folloer服务器发送commit消息,将此次提案进行提交。这个过程简称为2pc事务提交,注:Observer节点只负责同步leader数据,不参与2PC数据同步过程。

8.2崩溃恢复

正常情况消息广播情况下能运行良好,但是一旦Leader服务器出现崩溃,或者由于网络原理导致leader服务器失去了过半 Follower的通信,那么就会进入崩溃恢复模式,需要选举出一个新的leader服务器。这个过程可能会出现两种数据不一致性的隐患,这就需要ZAB协议的特性进行避免。

1、leader服务器将消息commit发出后,立即崩溃

2、leader服务器刚提交proposal后,立即崩溃。

ZAB协议的恢复模式使用策略:

1、选举zxid最大的节点作为新的leader

2、新leader将事务日志中尚未提交的消息进行处理。

九、Zookeeper Leader选举原理

zookeeper的leader选举存在两个阶段,一个服务器启动时leader选举,另一个是运行过程中leader服务器宕机。

  • 服务器Id(myid):服务器的唯一标识(SID),通过配置 myid 文件指定,集群中唯一,当ZXID一样时,myid大的节点优先选为Leader ,编号越大在选举算法中权重越大。
  • 事务ID(zxid-zookeeper transaction id):每个改变 Zookeeper状态的操作都会形成一个对应的zxid,ZXID最大的节点优先选为Leader。值越大说明数据越新,权重越大。
  • 逻辑时钟 (epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加 。

选举状态:

  • LOOKing:竞选状态。
  • Following:随从状态,同步leader状态,参与投票。
  • observing:观察状态,同步leader状态,不参与投票
  • leading:领导者状态

9.1 服务器启动时的leader选举

节点启动的时候都looking观望状态,下面就是开始进行选举主流程。以下三台组成集群为例。当几台服务器server启动时,机器之间可以相互通信,进入leader选举过程。

1、每台的server发出一个投票,由于初始情况,server1 和server2都将自己作为leader服务器进行投票,每次投票包含所推举的服务器myid、zxid、epoch,使用(myid,zxid)表示,此时server1投票为(1,0),server2投票为(2,0),然后将各自投票发送给集群中其它机器。

2、接收来自各个服务器的投票。集群中的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(epoch)、是否来自looking状态的服务器。

3、分别处理投票。针对每一次投票,服务器都需要将其它服务器的投票和自己的投票进行对比,对比规则如下:

  • 优先比较epoch
  • 检查zxid,比较zxid大的服务器优先作为leader
  • 如果zxid相同,那么就比较myid,myid较大的服务器作为leader服务器

4、统计投票。每次投票后,服务器统计投票信息,判断是都有过半机器接收到相同的投票信息。server1、server2都统计出集群中有两台机器接收(2,0)的投票信息,此时已经选出了server2为leader节点。

5、改变服务器状态。一旦确定了leader,每个服务器响应更新自己的状态,如果是leader,变更leading。此时server3继续启动,直接加入变更自己为following。

9.2、运行过程中的leader选举

当集群中leader服务器出现宕机或者不可用情况时,整个集群无法对外提供服务,进入新一轮的leader选举。

1.变更状态。leader挂后,其它非oberver服务器将自身服务器状态变更为looking。

2.每个server发出一个投票。在运行期间,每个服务器上zxid可能不同。

3.处理投票

4.统计投票

5.改变服务器状态

标签: java 网络 分布式

本文转载自: https://blog.csdn.net/qq_51552268/article/details/127302894
版权归原作者 ehuo_ 所有, 如有侵权,请联系我们删除。

“Zookeeper简单使用”的评论:

还没有评论