zookeeper浅析

网友投稿 269 2022-11-25

zookeeper浅析

概述

ZooKeeper是一个分布式的,开源的分布式应用程序协调服务,它包含一个简单的原语集,属于Apache的顶级项目,可以基于它实现服务发现,配置维护,集群管理和分布式锁等。

架构

Leader:处理读写请求,处理与Follower的心跳检测,并以事务的方式处理与Follower和Observer的数据同步 Follower:直接处理读请求,对于写请求转发给 Leader,Leader选举中参与竞争和投票,与Leader维持数据同步 Observer:直接处理读请求,对于写请求转发给 Leader,Leader选举中不参与投票,与Leader维持数据同步 Client:请求发起者

概念

znode zk中数据都存储在znode中,一个znode节点可以包含子znode同时也可以包含数据,每个znode都有一个唯一的访问路径。znode主要有如下四种类型: PERSISTENT-持久化目录节点客户端与zookeeper断开连接后,该节点依旧存在 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 EPHEMERAL-临时目录节点客户端与zookeeper断开连接后,该节点被删除 EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 sessionsession是zookeeper中会话的实例载体,一个session则是指代一个客户端会话。一个会话必须包含以下几个基本的属性: sessionID : 会话的ID,用来唯一标识一个会话,每一次客户端建立连接的时候,zookeeper服务端都会给其分配一个全局唯一的sessionID timeOut:一次会话的超时时间,客户端在构造zookeeper实例的时候,会配置一个sessionTimeOut参数用于指定会话的超时的时间。zookeeper服务端会按照连接的客户端发来的timeOut参数来计算并确定超时的时间 tickTime:下一次会话超时的时间点,为了方便zookeeper对会话进行所谓的分桶策略进行管理,同时也可以实现高效的对会话的一个检查和清理。tickTime是一个13位的Long类型的数值,一般情况下这个值接近timeOut,但是并不完全相等 isCloseing:用来标记当前会话是否已经处于被关闭的状态。如果服务端检测到当前会话的超时时间已经到了,就会将isCloseing属性标记为已经关闭,这样以后即使再有这个会话的请求访问也不会被处理 watch用户可以对一个znode设置watch,当这个znode发生了变化时,例如创建、删除、数据变更、添加或移除子节点,watch API就会发出通知。但是,zookeeper的 watch有一个缺点,就是这个watch只能被触发一次,一旦发出了通知,如果还想对这个节点继续watch,用户需要重新设置watch。 zxidleader 服务器在接收到事务请求后,会为每个事务请求生成对应的 proposal 来进行广播,并且在广播事务 proposal 之前,leader 服务器会首先为这个事务 proposal 分配一个全局单调递增的唯一 ID ,我们称之为zxid。zxid就是zk中的事务编号,是一个8字节的整型数字,一共有64位长度,前32位用来记录epoch,后32位就是用来计数。每一次写请求都会增加后32位,每一次leader选举会增加前32位,每次增加都是+1。 myid启动配置zoo.cfg中有一项 dataDir 指定了数据存放的路径,在此路径下新建一个文本文件,命名为myid, 文本内容就是一个数字,这个数字就是当前节点的myid,用来唯一标识一个节点。 节点的状态在zab协议中,是通过自身的状态来区分自己的角色的。在组成zab协议的所有进程启动的时候,初始化状态都是 LOOKING 状态,此时进程组中不存在leader,选举之后才有,在进行选举成功后,就进入消息广播模式,此时 zookeeper 集群中的角色状态就不再是 LOOKING 状态。在运行期间各个进程可能出现以下三种状态之一: LOOING:处在这个状态时,会进入 Leader 选举状态 FOLLOWER:Follower 服务器和 Leader 服务器保持同步时的状态 LEADING:Leader 服务器作为主进程领导者的状态 prososalleader服务器将客户端事务请求转化成一个事务prososal 核心zab协议 zookeeper分布式服务能够满足CAP理论中的CP,即能保证一致性和分区容忍性,但是不是保证可用性。像在leader选举的过程中,服务是不可用的。而zookeeper是采用zab(Zookeeper Atomic Broadcast)原子消息广播协议来保证CP。zab在工作的过程中,会有两种模式的切换:崩溃恢复模式和消息广播模式。 在进入崩溃恢复模式时 zookeeper集群会进行 leader 选举,一般有两种情况会发生选举: 当服务器启动时期会进行 Leader 选举。 当服务器运行期 Leader 服务器的出现网络中断、崩溃退出、重启等异常情况,或者当集群中半数的服务器与该 Leader 服务器无法通信时,进入崩溃恢复模式,开始 Leader 选举。 选举出 Leader 服务器后,会进入消息广播模式,开始接收处理客户端的请求。 恢复模式 崩溃恢复模式下 leader 选举的过程细节如下: 检测节点处于 LOOKING 阶段,开始选举 leader发起投票时有两种情况: 在服务启动的初始阶段,每个服务器都会投票给自己以(myid,zxid)的信息形式发送,那初始阶段没有 zxid 值,就会发送(myid,0) 在服务器运行期间,每个服务器上的 zxid 都有值,且 zxid 都不相同,所以就正常发送(myid,zxid) 各节点收到信息后将收到的(myid,zxid)和自己的比较。会比较epoch、写请求操作数、myid三个字段,依次比较谁大谁就更有资格成为leader 然后判断是否有半数的机器投票选出 leader,如果否,在进入新一轮投票,直到选出 选出 leader 后,其他节点就变成 follower 角色,并向 leader 发送自己服务器的最大 zxid ,leader 服务器收到后会和自己本地的提议缓存队列进行比较,判断使用那种策略进行同步 当同步完成,集群就可以正常的处理请求了,就进入消息广播模式了 消息广播模式 主要过程如下: leader 服务器接收到请求后在进行广播事务 proposal 之前会为这个事务分配一个 ZXID,再进行广播。 leader 服务器会为每个 follower 服务器都各自分配一个单独的队列,然后将需要广播的事务 proposal 依次放入这些队列中去,并根据 FIFO 策略进行消息的发送。 每个follower 服务器在接收到后都会将其以事务日志的形式写入到本地磁盘中,并且在成功写入后返回leader 服务器一个 ACK 响应。 当有超过半数的服务器 ACK 响应后,leader 就会广播一个 commit 消息给所有的 follower 服务器,follower 接收到后就完成对事务的提交操作。 应用场景 发布订阅 作为配置中心,来存放服务的配置 命名服务 命名服务是指通过指定的名字来获取资源或者服务的地址,提供者的信息。简单来说使用Zookeeper做命名服务就是用路径作为名字,路径上的数据就是其名字指向的实体,例如url地址。 集群管理 集群中的所有节点都注册到zk中,并添加watch机制。能够实现集群节点数量,在线状态,上下线状态等的自动发现。 分布式通知/协调 ZooKeeper 中特有 watcher 注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。 master选举 利用zooKeeper的一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建 /currentMaster 节点,最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很轻易的在分布式环境中进行集群选取了。 分布式锁 锁服务可以分为两类,一个是保持独占,另一个是控制时序。 独占所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。 控制时序/distribute_lock节点已预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。zk的父节点(/distribute_lock)维持一份 sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。 分布式队列 队列方面,简单地讲有两种,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行。对于第一种先迚先出队列,和分布式锁服务中的控制时序场景基本原理一致,这里不再赘述。第二种队列其实是在 FIFO 队列的基础上作了一个增强。通常可以在 /queue 这个 znode 下预先建立一个/queue/num 节点,并且赋值为 n(或者直接给/queue 赋值 n),表示队列大小,之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了。这种用法的典型场景是,分布式环境中,一个大任务 Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList 下建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL),当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了。 优缺点 优点 高可靠 应用广泛,比较成熟 支持监听事件 API简单 缺点 对于每个 watch 请求,zookeeper 都会打开一个新的 socket 连接,这样 zookeeper 就需要实时管理很多 socket 连接,比较复杂

总结

zookeeper是一款成熟的协调服务,应用广泛。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【大数据公司研究】第三方大数据公司是如何赚钱的,以个推公司为例
下一篇:使用FastAPI构建机器学习微服务
相关文章

 发表评论

暂时没有评论,来抢沙发吧~