zookeeper整理

zookeeper

应用场景

统一配置管理

分布式环境下,配置文件同步非常常见

  • 在一个集群中,一般要求所有节点的配置信息都是一致的
  • 对配置文件修改后,希望能快速同步到各个节点上

zookeeper可以作为一个分布式的配置中心:

  • 可将配置信息写入zookeeper的一个ZNode
  • 各个客户端服务器监听这个ZNode(watch机制)
  • 一旦ZNode中的数据被修改,zookeeper将通知各个客户端服务器

在这里插入图片描述

统一集群管理

在分布式环境中,实时掌握每个节点的状态是必要的,节点可根据其他节点的实时状态做出一些调整

zookeeper可以实现实时监控节点状态变化

  • 可将节点信息写入zookeeper上的一个ZNode
  • 监听这个ZNode可获取他的实时状态变化(watch机制)

服务注册和服务发现

服务命名

命名服务也是分布式系统中比较常见的一类场景,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象,其中较为常见的是一些分布式服务框架中的服务地址列表,通过使用命名服务客户端应用能够制定名字来获取资源的实体、服务地址和提供者的信息等。

服务注册

服务注册就是在服务启动后向zookeeper中注册一个临时节点ZNode,将服务的URL端口等信息写入到该节点中

服务发现

其他客户端可以通过服务名找到相关ZNode节点,获取url地址信息,进行服务消费

分布式锁

zk中的分布式锁其实就是zk上的一个临时顺序节点

当需要获取锁时,就在这个锁节点下创建一个临时顺序节点,当存在多个客户端同时来获取锁,就按顺序依次创建多个临时顺序节点,但只有排列序号第一的那个节点才能获取到锁,其他节点按顺序监听前一个节点的变化,当被监听节点释放锁时即临时顺序节点被删除了,监听者就可以马上获取到锁。

lock

原理:即为啥使用临时顺序节点可以实现分布式锁?

客户端可以指定 zk 创建一个有序节点,此节点将自动在客户端指定的节点名后面添加一个单调递增序号来确保多个客户端同时创建相同的节点名时能够创建成功,并且保障越早创建的节点的序号越小。利用该特性可以实现锁的互斥性和公平性,即同一时刻只有一个客户端能够成功获取到锁(序号最小的一个获取到锁),获取锁失败的节点可以按照创建顺序进行锁等待。

img

zookeeper架构特点

在这里插入图片描述

  • zookeeper集群中一个leader节点,多个follower节点(一般为奇数个)组成的集群
  • 集群中只要有半数以上的节点存活,zookeeper集群就能正常服务
  • 全局数据一致:每个zookeeper节点保存一份相同的数据副本,客户端无论连接哪一个节点,读到的数据都是一致的,数据同步的时间很快(数据量小)
  • 更新请求顺序进行,来自同一个客户端的更新请求按其发送顺序依次执行
  • 数据更新的原子性:一次数据更新,要么成功,要么失败

数据结构

在这里插入图片描述

zookeeper数据结构和unix文件系统很类似,整体上可以看作一棵树,每个节点称作一个ZNode,每一个ZNode默认能够存储MB的数据,每个ZNode都可以通过其路径唯一标识

节点类型

ZNode有三种类型:

  • 持久节点:客户端即使断开连接,节点还是会存在
  • 临时节点:客户端断开连接后,节点会被zookeeper自动删除
  • 顺序节点:每次创建顺序节点时,ZooKeeper都会在路径后面自动添加上10位的数字,从1开始,最大是2147483647 (2^32-1),每个顺序节点都有一个单独的计数器,并且单调递增,由zookeeper的leader节点维护

节点数据结构

img

  • data: ZNode存储的数据信息,每个节点数据最大不超过1MB

  • ACL(Access Control List): 记录访问权限,哪些人或哪些IP可访问本节点

  • child: 当前节点的子节点

  • stat: 各种元数据,比如事务ID、版本号、时间戳、大小等

leader选举

半数机制

  • 集群中半数以上机器存活,集群可用,所有zookeeper适合安装奇数台服务器

zookeeper在配置文件中没有显示指定主从服务器,所以leader服务器是在内部选举产生的,leader选举也是保证分布式数据一致性的关键所在

为什么需要leader选举?

  • 像redis集群,可以直接通过配置文件去直接指定master/slave,但是这有一个缺陷:如果主节点只有一台服务器,主节点挂掉了,就无法有机制能保证进行主从切换,尽管redis中可以通过哨兵,但是如果有一种机制可以自动进行选主,会更加方便

leader选举时机:

  • 服务器初始化启动
  • 服务器运行期间和leader服务器断开连接

服务器的四种状态:

LOOKING:寻找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入Leader选举状态。

FOLLOWING:跟随者状态。表明当前服务器角色是Follower。

LEADING:领导者状态。表明当前服务器角色是Leader。

OBSERVING:观察者状态。表明当前服务器角色是Observer。

投票数据结构

id:被推举的Leader的SID。

zxid:被推举的Leader事务ID。

electionEpoch:逻辑时钟,用来判断多个投票是否在同一轮选举周期中,该值在服务端是一个自增序列,每次进入新一轮的投票后,都会对该值进行加1操作。

peerEpoch:被推举的Leader的epoch。

state:当前服务器的状态。

算法步骤:

  • 选举阶段

    • 所有节点处于Looking状态,各自依次发起投票,投票包含自己的服务器SID和最新事务ID(ZXID)。
    • 如果发现别人的ZXID比自己大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大的ZXID所属节点。
    • 每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准Leader,状态变为Leading。其他节点的状态变为Following。
  • 发现阶段

    • 为了防止某些意外情况,比如因网络原因在上一阶段产生多个Leader的情况。

    • Leader集思广益,接收所有Follower发来各自的最新epoch值。Leader从中选出最大的epoch,基于此值加1,生成新的epoch分发给各个Follower。

    • 各个Follower收到全新的epoch后,返回ACK给Leader,带上各自最大的ZXID和历史事务日志。Leader选出最大的ZXID,并更新自身历史日志。

  • 同步阶段

    • Leader刚才收集得到的最新历史事务日志,同步给集群中所有的Follower。只有当半数Follower同步成功,这个准Leader才能成为正式的Leader

watch机制原理

zookeeper允许客户端在指定节点上注册watches,在某些指定事件触发的时候,zookeeper服务端会将事件异步通知到注册watch的客户端上

一次watch事件只会被触发一次,如果节点再次发生变化,除非之前有重新设置过watches,不然不会收到通知

watch监听的节点更改有两类:

  • ZNode节点数据的更改
  • ZNode下子节点的更改

监听分析

  • zk客户端创建时会创建两个线程
    • 一个负责网络连接通信的connect线程
    • 一个负责监听的listen线程
  • 通过connect线程将注册的监听事件发送给zookeeper
  • zookeeper服务端会在注册监听器列表中新增相应的监听事件
  • 通过监听数据或者路径变化,只要有变化就会异步将消息通知给listen线程,通知后移除监听事件
    • get path
    • is path
  • listen线程内部调用process方法将监听结果反馈给客户端,客户端删除watch

写数据请求

zookeeper集群中的角色

  • leader:负责集群内部投票的发起和决议,更新系统状态,接收响应客户端的请求
  • follower:接收和响应客户端的请求,发起投票,参与集群内部投票
  • observer:接收和响应客户端的请求,不参与投票,只会同步leader的状态

leader和follow都可以接收客户端的请求,但是follow只能处理非事务即读请求,所有的写请求必须交给leader去处理

  • 客户端发出写入数据请求给任意Follower。

  • Follower把写入数据请求转发给Leader。

  • Leader采用二阶段提交方式,先发送Propose广播给Follower。

  • Follower接到Propose消息,写入日志成功后,返回ACK消息给Leader。

  • Leader接到半数以上ACK消息,返回成功给客户端,并且广播Commit请求给Follower

在这里插入图片描述

ZAB协议

ZAB协议是为分布式协调服务zookeeper专门设计的一种支持崩溃恢复的一致性协议,保证了集群各个节点的数据同步,有两种模式:恢复和广播

广播模式

广播模式类似于分布式事务中的两阶段提交,zookeeper中一次写操作就是一个事务

img

  • zookeeper集群节点收到客户端的写请求
  • follow节点将写请求转发给leader节点
  • leader节点先将更新持久化到本地磁盘
  • leader节点将此次更新请求发给follow,进入收集follow的ack流程
  • follow接收到leader节点的更新请求,成功将修改持久化到本地磁盘,发送ACK给leader
  • 当leader收到超半数以上的ack时,就会广播事务提交消息给follow
  • 当follow收到commit后,就会进行一个数据的同步

恢复模式

当集群中的leader节点故障或者服务启动时,ZAB就会进入恢复模式,做一个数据同步

猜你喜欢

转载自blog.csdn.net/weixin_41922289/article/details/107898206