zookeeper学习

canal利用zookeeper进行服务协调,选举主节点,实现系统的高可用,这里深入了解zk,包括特性,适用场景和原理。

概述

Zookeeper是一个分布式的协调服务。实质是提供了一个类似与linux的树形文件系统,客户端可添加子节点,对其赋值,监听节点变动。通过这些操作可完成不同的功能,包括服务发现,选主节点,分布式锁,命名服务等。

概念

节点类型

zk是一个树形结构,节点具有不同的特性,包括:

  • 临时:与客户端会话生命周期相同,如果客户端断开连接,临时节点被删除。临时节点不可设置子节点
  • 永久:需要手动删除
  • 有序:按客户端访问顺序被zk分配有序的节点名称。可用于公平锁的实现。
  • 无序
订阅与通知

客户端可订阅节点,如果该节点被修改,删除或子节点变动,zk会通知客户端相应变化。一旦变更被通知,需要重新设置watch。
利用watch机制可进行主节点选举。多个客户端竞争建立/leader临时节点,如果建立失败,订阅leader节点。如果主节点挂掉,会话消失,leader节点被删除,此时订阅该leader的从节点竞争建立/leader临时节点,建立成功的晋升为主节点对外提供服务。失败的节点仍监听leader节点,担任从节点。利用节点的有序性可实现主节点的公平选举或公平锁。

会话

会话即客户端维持与zk的一个长连接。会话期间服务端向客户端发出心跳以表明客户端还存活。如果超时时间内未检测到心跳,则释放会话,删除客户端建立的临时节点。如果客户端连接的zk节点挂掉,会话会平移到正常提供服务的节点,客户端不会有感知。

事务

zk会保证客户端的更新要么都成功,要么都失败

ACL

zk的权限控制

特性

  1. 最终一致性:客户端不管连接哪个server,最终会得到同样的视图。即集群内各个节点的状态最终是一致的。因为数据修改时,leader得到半数以上follower的ack即commit,因此有的节点数据更新会滞后,但最终会保持一致。
  2. 可靠性:如果消息被一台机器commit,最终会被所有机器commit。如果消息在一台机器commit后,leader挂掉需重新选举leader。新leader规定是zxid最大,即拥有最新commit数据的节点。
  3. 原子性:更新只能成功或失败,没有中间状态
  4. 顺序性:一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;如果消息a在消息b前被同一个发送者发布,则a必将排在b前面。由zxid和队列保证。

这些特性主要有zab协议保证。

场景:

  • 集群管理,主节点选举
  • 分布式锁
  • 服务发现
  • 配置中心
  • 分布式队列

已使用的组件:Hadoop,hbase,dubbo,kafka,canal

ZAB协议

zab协议是zookeeper原子广播协议,规定了zk集群事务请求的处理方式以及如何保证数据一致性。使用Leader来接收并处理客户端的更新请求,通过二阶段提交的方式广播至所有的Follower。当leader崩溃时,由恢复模式不会影响已经commit的数据。任意节点均可处理读请求。
zab协议主要包含两种模式:恢复模式(选主+数据恢复)和广播模式(数据同步)。当服务初始化或者leader崩溃后,zookeeper会进入恢复模式选举leader,leader被选举出来后,将自身最新的数据同步至follower,恢复模式就结束了。广播模式使用2pc模式,保证leader和Server具有相同的系统状态。

Zk具有以下三种角色:

  • Leader:一个集群中只有一个leader,维持和follower,observer的心跳,完成写读操作,写完后广播到其他节点
  • Follower:完成读请求,将写请求转到leader,当一段时间接收不到心跳时进入选主状态
  • Observer:和follower功能相似,但不能选主

zk处理写请求
image.png

原子广播模式:
  1. 客户端请求zk服务,如果zk处理节点不是leader,则转发到leader进行写操作
  2. leader将事务请求转为proposal并为其分配全局唯一单调递增zxid
  3. leader为每个follower分配单独的队列,将proposal放入队列中,按FIFO原则异步发送至follow
  4. follower收到prososal后写入本地日志文件,写入成功后响应ack给leader
  5. 当leader收到半数folloer响应的ack后,会认为发送成功,向follower发送commit消息。同时响应给客户端结果
  6. follower收到commit后,会提交本地事务,数据更新成功。

注意:

  • 原子广播模式规定zk如何处理数据更新事务。类似二阶段事务提交,但不同的是当超过半数follower ack后,leader即认为数据写入成功并commit。可提高事务处理的性能。
  • Leader 服务器与每一个 Follower 服务器之间都维护了一个单独的 FIFO 消息队列进行收发消息,做到异步解耦。如果使用同步的方式会引起阻塞,性能要下降很多。
  • Zxid:zk对客户端的写请求转为proposal进行广播,leader为每次proposal分配全局唯一单调递增的事务ID,即zxid。Zxid是一个64为数字,低32位为单调递增的计数器,每次事务请求会自增1。高32位为epoch,代表leader周期,每新选举一次leader,epoch自增1表明进入新的leader周期,并将低32位清零。follower只会听从最高epoch的leader。zxid和FIFO队列保证事务的有序性。
恢复模式

会触发恢复模式的场景:

  • Leader宕机
  • 集群初始化
  • 被分区的两个集群重新合并
  • 集群中不存在超过半数的服务器与Leader保存正常通信

崩溃恢复流程是主节点选举,数据恢复。
新的主节点要求:

  1. 需要保证新的主节点的数据是最新的,即含有最大的 zxid,不能包含未提交的Proposal。之后将数据同步到其他节点,即数据恢复,以确保被一个节点commit的数据会被所有节点接受
  2. 新选举出来的 Leader 不能包含未提交的 Proposal
  3. Leader 选举算法不仅仅需要让 Leader 自己知道自己已经被选举为 Leader ,同时还需要让集群中的所有其他机器也能够快速感知到选举产生的新 Leader 服务器。

步骤:

  1. 选举:Fast Leader Election(快速选举)。选举拥有最新Proposal history (lastZxid最大)的节点作为 Leader,成为 Leader 的条件:

    1. 选 epoch 最大的
    2. 若 epoch 相等,选 zxid 最大的
    3. 若 epoch 和 zxid 相等,选择 server_id 最大的(zoo.cfg中的myid)
  2. 恢复:利用 Leader最新的Proposal历史,同步集群中所有的副本
  3. 广播:到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 Leader 可以进行消息广播。

java客户端

推荐使用curator

参考:

zookeeper:
https://www.jianshu.com/p/2bceacd60b8a
https://dbaplus.cn/news-141-1875-1.html
https://draveness.me/zookeeper-chubby/
curator:
https://www.jianshu.com/p/ae0c1fbbff3c

你可能感兴趣的:(zookeeper)