zookeeper学习笔记(二)

六 ZooKeeper Shell
客户端连接 ` zkCli.sh -server {ip}`
创建节点

create [-s] [-e] {path} {data} {acl}
-s表示序列化,-e表示临时节点,若不指定则表示持久节点,path为节点路径,data为数据,acl用来进行权限控制。

zookeeper为自带节点。

读取节点
ls /

ls {path}查看指定节点下的第一级所有子节点。

get {path}获取zookeeper指定节点的数据内容和属性信息。

ls2 {path}查看指定节点的第一级所有子节点和指定节点的数据内容和属性信息。

exists测试某个位置是否存在节点

get data从一个节点读数据

sync等待传播数据

更新节点
` set {path} {data} {version}`

{version}表示数据版本,与dataVersion一致。

set data从一个节点写数据

删除节点
` delete {path} {version}`

若删除节点存在子节点,那么无法删除该节点,必须先删除子节点,再删除父节点。

quota
`setquota -n|-b {val} {path} `对节点增加限制

n:表示节点的最大个数,-1表示没有限制

b:表示数据值的最大长度,-1表示没有限制

val:子节点最大个数或数据值的最大长度

path:节点路径

listquota {path}列出指定节点的quota,output stat count默认为1,包含自己

delquota {-n|-b} {path}删除quota

超出quota限制不会报错,只会在zookeeper.out日志中提出警告信息。

其他命令
` history`列出历史命令

redo重新执行指定命令编号的历史命令,命令编号可以通过history查看

七 ZooKeeper Components
![ZooKeeper组件](https://imgconvert.csdnimg.cn/aHR0cHM6Ly96b29rZWVwZXIuYXBhY2hlLm9yZy9kb2MvY3VycmVudC9pbWFnZXMvemtjb21wb25lbnRzLmpwZw)

除请求服务器外,每个ZooKeeper服务器都复制自己每个组件的副本。

复制数据库是包含整个数据树的内存数据库。写入在应用于内存数据库之前会序列化到磁盘。

每个ZooKeeper服务器都为客户端服务。客户端连接到一台服务器以提交请求。读取请求由每个服务器数据库的本地副本提供服务,服务状态更改请求、写请求由agreement protocol处理。

作为agreement protocol的一部分,客户端的所有写请求都被转发给单一服务器leader,其余服务器称为followers,接收leader消息需求并同意消息传递。

消息传递层负责替换失败的leader并同步leader和followers。ZooKeeper使用自定义原子消息传递协议,由于消息传递层是原子的,因而本地副本不会不同。

leader收到写请求时,计算写入时的系统状态并转化成一个捕获新状态的事务。

八 ZooKeeper Watcher

ZooKeeper提供了分布式数据分布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象,当主题对象自身状态发生变化时,会通知所有的订阅者,使他们能够做出相应的处理。

ZooKeeper使用Watcher机制来实现这种分布式通知功能,允许客户端向服务端注册一个Watcher监听,当服务端的一些事件触发了这个Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。

触发事件种类:节点创建,节点删除,节点改变,子节点改变等。

过程:

  1. 客户端向服务端注册Watcher
  2. 服务端事件发生触发Watcher
  3. 客户端回调Watcher得到触发事件情况

特点:

  1. 一次性触发:事件发生触发监听后,一个Watcher event就会被发送到设置监听的客户端,结果一次性,后续发生同样事件不再触发。
  2. 事件封装:ZooKeeper使用WatchedEvent对象来封装服务端并传递,WatchedEvent包含了每一个事件的三种基本属性:通知状态(keeperState)、 事件类型(EventType)和节点路径(path)
  3. event异步发送:watcher的通知事件从服务端发送到客户端是异步的
  4. 先注册再触发:Zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发生才会触发监听,通知给客户端。

同一事件类型在不同的通知状态中代表的含义不同。

连接状态事件不需要客户端注册。

get /watch watch
#help中带有[watch]参数的命令都可以设置监听

八 Java API

  • org.apache.zookeeper.Zookeeper Zookeeper是在Java中客户端的主类,负责建立与zookeeper集群的会话,并提供方法进行操作。
  • org.apache.zookeeper.Watcher Watcher接口表示一个标准的事件处理器,其定义了事件通知相关的逻辑,包含KeeperState和EventType两个枚举类,分别代表了通知状态和事件类型,同时定义了事件的回调方法:process(WatchedEvent event)。
  • process方法事件是Watcher接口中的一个回调方法,当ZooKeeper向客户端发送一个Watcher事件通知时,客户端就会对相应的process方法进行回调,从而实现对事件的处理。
<!--	java maven依赖	-->
<dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.4.9</version>
</dependency>
//构造函数
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) throws IOException{
  this(connectString, sessionTimeout, watcher, false);
}
//查阅文档

九 选举机制

默认算法FastLeaderElection,投票数大于半数则胜出。

服务器id编号越大权重越大。数据version越大数据越新,权重越大。逻辑时钟:投票次数,投票次数越多权重越大。

  • logicClock 每个服务器会维护一个自增的整数,名为logicClock,它表示这是该服务器发起的第多少轮投票
  • state 当前服务器的状态
  • self_id 当前服务器的myid
  • self_zxid 当前服务器上所保存的数据的最大zxid
  • vote_id 被推举的服务器的myid
  • vote_zxid 被推举的服务器上所保存的数据的最大zxid

选举状态:

  1. LOOKING 竞选状态
  2. FOLLOWING 随从状态,同步leader状态,参与投票
  3. OBSERVING 观察状态,同步leader状态,不参与投票
  4. LEADING 领带者状态

投票流程

自增选举轮次
Zookeeper规定所有有效的投票都必须在同一轮次中。每个服务器在开始新一轮投票时,会先对自己维护的logicClock进行自增操作。

初始化选票
每个服务器在广播自己的选票前,会将自己的投票箱清空。该投票箱记录了所收到的选票。例:服务器2投票给服务器3,服务器3投票给服务器1,则服务器1的投票箱为(2, 3), (3, 1), (1, 1)。票箱中只会记录每一投票者的最后一票,如投票者更新自己的选票,则其它服务器收到该新选票后会在自己票箱中更新该服务器的选票。

发送初始化选票
每个服务器最开始都是通过广播把票投给自己。

接收外部投票
服务器会尝试从其它服务器获取投票,并记入自己的投票箱内。如果无法获取任何外部投票,则会确认自己是否与集群中其它服务器保持着有效连接。如果是,则再次发送自己的投票;如果否,则马上与之建立连接。

判断选举轮次
收到外部投票后,首先会根据投票信息中所包含的logicClock来进行不同处理

  • 外部投票的logicClock大于自己的logicClock。说明该服务器的选举轮次落后于其它服务器的选举轮次,立即清空自己的投票箱并将自己的logicClock更新为收到的logicClock,然后再对比自己之前的投票与收到的投票以确定是否需要变更自己的投票,最终再次将自己的投票广播出去。
  • 外部投票的logicClock小于自己的logicClock。当前服务器直接忽略该投票,继续处理下一个投票。
  • 外部投票的logickClock与自己的相等。当时进行选票PK。

选票PK
选票PK是基于(self_id, self_zxid)与(vote_id, vote_zxid)的对比

  • 外部投票的logicClock大于自己的logicClock,则将自己的logicClock及自己的选票的logicClock变更为收到的logicClock
  • 若logicClock一致,则对比二者的vote_zxid,若外部投票的vote_zxid比较大,则将自己的票中的vote_zxid与vote_myid更新为收到的票中的vote_zxid与vote_myid并广播出去,另外将收到的票及自己更新后的票放入自己的票箱。如果票箱内已存在(self_myid, self_zxid)相同的选票,则直接覆盖
  • 若二者vote_zxid一致,则比较二者的vote_myid,若外部投票的vote_myid比较大,则将自己的票中的vote_myid更新为收到的票中的vote_myid并广播出去,另外将收到的票及自己更新后的票放入自己的票箱

统计选票
如果已经确定有过半服务器认可了自己的投票(可能是更新后的投票),则终止投票。否则继续接收其它服务器的投票。

更新服务器状态
投票终止后,服务器开始更新自身状态。若过半的票投给了自己,则将自己的服务器状态更新为LEADING,否则将自己的状态更新为FOLLOWING

全新集群选举

比较服务器id,得票过半获胜

非全新集群选举

  1. 逻辑时钟小的选举结果被忽略,重新投票
  2. 统一逻辑时钟后,数据id大的胜出
  3. 数据id相同的情况下,服务器id大的胜出;根据这个规则选出leader

十 应用

  1. 命名服务:通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者信息等。
  2. 分布式锁:保持独占(客户端在zk集群上创建临时节点,先创建的服务器保持连接,通过zk访问数据文件,断开后其他服务器监听回调创建节点)、控制时序(创建序列化节点)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值