zookeeper核心知识与投票机制详解
Zookeeper数据模型与session机制:
zookeeper的数据模型有点类似于文件夹的树状结构,每一个节点都叫做znode,每一个节点都可以有子节点和数据,就好像文件夹下面可以有文件和子文件夹。
* 每一个节点存储的数据不宜过大。
* 我们可以为节点设置相应的控制权限。
* 每个节点都带有版本号,数据变更时,版本号(乐观锁)变更。
zookeeper的客户端与服务端建立连接就会存在session机制,通过客户端向服务端ping包请求的心跳机制来检查session是否过期,session过期的时候,该session创建的所有临时节点都会被抛弃。
Zookeeper的四种类型节点:
persistent: 持久化节点
persistent_sequential: 持久化顺序节点
ephemeral: 临时节点
ephemeral_sequential:临时顺序节点
* 持久化节点只能主动调用detele方法删除
* 临时节点在创建者超时或失去连接后节点就会被删除,临时节点下面没有子节点
* 顺序节点在创建后会自动在后面添加序列号
Zookeeper集群的三种角色:
leader:一个集群有且只有一个leader节点,处理写请求,并负责进行发起投票和决议,更新系统状态。每次处理写请求的时候都会发起投票,只有过半的节点通过才能写入数据。
follower:用来处理读请求,leader会根据算法落实到某个follower节点。follower除了有投票权还具有选举权,当leader挂掉之后,follower之间就会发起投票,选举出下一任的leader。
observer:用来处理读请求,可以当成没有投票和选举资格的follower。其存在的目的就是为了协助follower来处理读请求。因为一个集群只有leader和follower的话每次节点变化都需要投票,这是很耗时间的;有这么一个只干活不投票的打酱油角色可以提高读取的吞吐量。
* zookeeper集群必须有过半的节点存活才能提供服务。那么5台的集群最多能挂2台机,6台的集群最多也只能挂2台。那么5台和6台没区别,为了节约服务器成本通常集群为奇数。而不是别人网上说的奇数台这样投票就会有一个最大值,这是错误的说法。
zookeeper的选举状态变化:
looking, 选举中状态(集群刚启动或leader宕机时,查找leader的状态)
leading, 领导者状态(若节点为leader,那么它就是leading状态)
following, 随从者状态(若节点为follower,它就会同步leader数据,成为following状态)
observing, 观察者状态(若节点为observer,它就会同步leader数据,成为observing状态)
Zookeeper如和实现数据一致性的:
zk的核心是广播机制,该机制保证了各个zk之间的数据同步(数据一致性)。zk实现的机制为ZAB协议(zk原子广播协议),主要原理是下面3中模式。
广播模式:leader写入数据时会发起提议,当大多数follower都同意之后,leader就会更新数据并广播给其他follower。
恢复模式:如果leader崩溃,这个时候就会进入恢复模式,使得整个zk集群恢复到正常的工作状态。
同步模式:新的leader选举出来后,就会进入同步模式,各个follower会去同步新的leader上的数据,当大多数节点完成了状态同步,恢复模式就结束。
Zookeeper集群的选举算法:
zookeeper集群的机器有两个核心的属性,myid和zxid。
myid:是zk集群中服务器的唯一标识,例如有3台zkserver,那么编号分别为1,2,3。
zxid:是一个64位的long类型。它会拆分成2部分,高32位表示epoch(leader标识), 低第32位表示xid(事务id)。
现在我们以3台机器的集群模拟选举过程:
1. 由于是集群初始化,前面几个节点都是投自己的票.这个时候集群还没启动过半,则这个zkserver的选举状态是looking。这时候假定epoch为123,则第一个机器的票数,epoch,myid为 1:123:1。然后将投票信息广播出去。
2. 启动第二台机器,它还是投自己的票(n台机器的集群,前面几台机器都是自己投自己)。此时它的票数,epoch,myid为 1:124:2。广播给其他节点自己的投票消息。
2.1 此时集群已经启动过半,可以提供服务了。首先会比较票数,票数多的为leader;票数一样就比较epoch,值大者(大表示数据越新)胜出;epoch相等就比较myid,myid大的胜出。
2.2 此时第二台机器就是leader,第一台机器就是follower。
3. 启动第三台机器,由于集群已经产生出leader了,所以节点三也是follower。
3.1 leader选举出来之后就会产生一个新的zxid,然后所有follower都去同步leader的zxid.其中高32的epoch表示一个新纪元(改朝换代会有新的国号嘛),低32位的xid事务id用来leader提议写操作(可以理解成一个国家的法律)。你不能拿明朝的尚方宝剑来斩清朝的官嘛!
4. 若leader无法保持连接的时候就会开始新一轮的投票, 产生新的leader和zxid,然后进行同步 .....
5.1如果之前的leader重启,那么他会成为一个follower,去同步新的leader信息
5.2如果刚才的leader只是假死,现在它复活之后还会以为自己是leader,那么它向其它follower发生请求会被拒绝。
注意: 因为ZooKeeper维护了一个叫epoch的变量, 每当新leader产生时, epoch都会递增, followers如果确认了新的leader存在, 同时也会知道其epoch的值。
它们会拒绝epoch小于现任leader的epoch的所有旧leader的任何请求.仍然会存在有部分followers不知道新leader的存在, 但肯定不是大多数, 否则新leader将无法产生.