Zookeeper基础学习笔记

其实网络上关于Zookeeper的文章多如牛毛,起初,我也只是想写个学习笔记,作个记录。可是既然动笔了,我想就不单是作个笔记,而是但愿写一些对读者有帮助的内容。node

Zookeeper做为一个流行的分布式协调服务,要了解他,咱们首先问本身两个问题,Why and How?咱们为何要用Zookeeper?Zookeeper是怎么工做的?web

Why(用途)

首先,咱们为何要用到Zookeeper?咱们能够把软件系统类比为一个公司,当公司规模小的时候,老板就能决定全部的事情;数据库

但当公司规模发展壮大后,老板一我的管理公司有些吃力,但又不放心把全部权力交给另一我的,这时老板想了个办法,成立了一个CEO团队,团队采用民主化运做进行集体决策。服务器

ECO团队的主要任务:网络

  1. 制定公司各项规章制度并对全公司公布
  2. 收集各部门的提交的意见,决定是否采纳
  3. 公司规章制度更新后,通知涉及的部门

相似的,Zookeeper做为分布式协调服务,他主要经过两个手段对外提供服务,即服务目录 + 通知数据结构

  1. 维护一个类文件系统的数据结构,存储信息,给业务提供服务
  2. 接收客户端提交的修改请求,并在内部同步达成一致
  3. 当信息发生变化时,消息推送给感兴趣的监听者

Zookeeper的应用场景包括:数据发布/订阅、命名服务、配置中心、分布式锁、集群管理、选主与服务发现等等。app

基本概念

先了解下Zookeeper里的一些基本概念。分布式

目录节点(znode)

Zookeeper类文件系统中的每一个节点称为znode,znode里包含了节点的自身信息和业务数据,根据节点属性,能够分为2大类,分别是持久化节点临时节点,每类下有分为普通节点按顺序编号节点,分别描述以下:性能

  1. PERSISTENT:持久化目录节点学习

    • 客户端断开后,节点依然存在
  2. PERSISTENT_SEQUENTIAL:持久化顺序编号目录节点

    • 客户端断开后,节点依然存在
    • Zookeeper会给此类节点名称进行顺序编号
  3. EPHEMERAL:临时目录节点

    • 客户端断开后,节点被删除
  4. EPHEMERAL_SEQUENTIAL:临时顺序编号目录节点

    • 客户端断开后,节点被删除
    • Zookeeper会给此类节点名称进行顺序编号

监听机制(Watcher)

客户端注册监听它关心的节点,当节点发生变化(数据改变、删除、子节点增长/删除)时,监听器会被触发,并将事件信息推送到客户端。

节点角色

Zookeeper自己做为一个分布式服务,有若干节点组成集群对外提供服务,集群节点包括Leader、Follower、Observer 3种角色。

  • Leader:领导者,为客户端写服务;维护集群状态。Leader由集群选举产生。
  • Follower:跟随者,为客户端提供读服务;按期向Leader汇报自身状态;参与写服务器过半写成功的决策和Leader选举。
  • Observer:观察者,为客户端提供读服务;按期向Leader汇报自身状态;不参与决策和选举。Observer能够在不影响写性能的状况下提高集群的读性能。

客户端会话

Zookeeper客户端经过TCP长链接链接到服务集群,会话(Session)从第一次链接开始就已经创建,以后经过心跳检测机制来保持有效的会话状态。客户端经过这个链接发送请求并接收响应,接收到Watch事件的通知。

当因为网络故障或者客户端主动断开等缘由,致使链接断开,此时只要在会话超时(Session TimeOut)时间以内从新创建链接,则以前建立的会话依然有效。

ZXID

对于每一个事务,Zookeeper都会分配一个全局惟一的事务ID(ZXID)。ZXID由64位组成。其中高32位为纪元号(Epoch:集群每选举一次Leader,纪元号加1);低32为本纪元内的事务序号(事务序号在每一个纪元会清零)

民主选举(过半机制)

所谓民主选举,是指当集群中超过一半的节点赞成一个事务时,即表示事务执行成功(不包括Observer)。Leader提交一个提案时,只要过半数节点反馈ACK,就职务提案被集群接受了,Leader不须要等待剩余节点反馈ACK,直接广播Commit消息;Leader选举和数据同步时,亦如此。

提案和事务

Zookeeper收到客户端的一个写请求,称为提案(Proposal),把一个提案提交到集群并应用生效的过程,叫事务

How(ZAB协议)

下面咱们再来看下,做为一个CEO团队,它是如何运做的。做为一个优秀的管理团队,他的运做要知足CAP原则,即:

  • 一致性:团队成员达成一致
  • 可用性:不能某人离职了就玩不转了
  • 分区容错性:紧急状态下联系不上所有成员的时候要能决策重要事项)

团队经过如下几条规则确保CAP:

  1. 团队成员人数不能太少,至少要3人及以上
  2. 由团队成员民主(过半数赞成)选举产生一个首席CEO,根据任人惟贤能上能下的宗旨,首席CEO干的很差了,可由团队从新选举产生。
  3. 公司全部的决策,由首席CEO从各部门收集后产生提案,并由CEO团队民主表决经过。

Zookeeper的工做原理,和以上相似。主要依赖ZAB(ZooKeeper Atomic Broadcast)一种支持崩溃恢复的原子广播协议来完成。

ZAB的特性

  1. 一致性保证

    1. 可靠提交(Reliable Delivery):若是一个事务被Leader提交了,那么最终必定会被全部的节点提交
    2. 全局有序(Total Order):假设A、B两个事务,Leader先提交了A,再提交B,那么能够保证全部节点都以先A后B的顺序提交
    3. 因果有序(Causal Order):若是发送者在事务A提交后再发送B,那么B一定在A以后执行
  2. 只要过半节点启动,系统就能正常运行
  3. 当节点下线后重启,必须保证能恢复到当前正在执行的事务

ZAB协议有两种工做模式,分别是广播模式和恢复模式。

  1. 恢复模式:集群启动后,先经过恢复模式选出Leader,并完成节点间数据同步;
  2. 广播模式:恢复完成后,系统进入广播模式,开始接受客户端请求,并确保节点间数据同步。

广播模式(Broadcast)

广播模式主要用来实现集群节点间数据的同步,每一个同步操做定义为一个事务,使用两阶段提交协议完成事务提交,以客户端写数据为例进行说明事务操做:

  1. Leader从客户端接受写请求(若是Follower接受到写请求,会转发给Leader)
  2. Leader生成一个新提案(Proposal),并为提案分配ZXID,启动提案提交事务
  3. Leader将提案发送给全部Follower
  4. Follower将接收到的提案加入历史队列(History Queue),并给Leader回复ACK
  5. 当Leader收到过半Follower的ACK后,Leader Commit提案,并向Follower广播提案Commit请求
  6. Follower接收到提案Commit请求后,Commit本地的提案,事务结束

两阶段提交协议

根据全局有序的规则,Follower提交事务时,须要经过历史队列,确认此提案的ZXID是不是最小的,最小才提交,否则就等待其余ZXID更小的事务先提交

恢复模式(Recovery)

当整个集群在启动时,或者Leader失联后,ZAB协议就会进入恢复模式,恢复模式的流程以下:

  1. 集群经过过民主举机制产生新的Leader,纪元号加1,开始新纪元
  2. 其余节点重新的Leader同步状态
  3. 过半节点完成状态同步,退出恢复模式,进入消息广播模式

Leader选举流程

Leader选举是集群正常运行的前提,当集群启动或Leader失联后,就会进入Leader选举流程。
选举期间,集群间经过选票(Vote) 进行进行互相选举,选票主要包含两个信息:

  1. 节点ID:集群配置文件中预配置的每一个节点的ID
  2. ZXID:节点已经Commit的最大提案的ID

选举流程:

  1. 全部节点进入LOOKING状态
  2. 每一个节点广播携带自身ID和ZXID的选票,投票推举本身为Leader
  3. 节点接收其余节点发送的选票,把选票信息和本身推举的选票进行PK(选票中ZXID大者胜出,ZXID相同,则ID大者胜出)
  4. 若是外部选票获胜,则保存此选票信息,并把选票广播出去(同意该选票)
  5. 循环上述3-4步骤
  6. 当有选票获得超过半数节点同意,且该选票的全部者也同意该选票,则选举成功,该选票全部者成为Leader
  7. Leader切换为LEADING,Follower切换为FOLLOWING,Observer切换为OBSERVING状态,选举结束,进入数据同步流程。

数据同步流程,是要以Leader数据为基础,让集群数据达到一致状态。

数据同步流程

  1. 新Leader把本地快照加载到内存,并经过日志应用快照以后的全部事务,确保Leader数据库是最新的
  2. Follower和Observer把自身的ZXID和Leader的ZXID进行比较,肯定每一个节点的同步策略
  3. 根据同步策略,Leader把数据同步到各节点
  4. 每一个节点同步结束后,Leader向节点发送NEWLEADER指令
  5. 同步完成的节点返回ACK
  6. 当Leader收到过半节点反馈的ACK时,认为同步完成
  7. Leader向节点发送UPTODATE指令,通知集群同步完成,开始对外服务
遗留问题
根据ZAB协议,Leader已经Commit的事务,从新选主后,要能在新集群生效。可是有一种状况,对于一个提案Px,原Leader向集群广播提案并收到了过半Follower的ACK,此时Leader会自身先执行Commit再向集群广播Commit,但还将来得及向集群广播Commit消息,Leader就挂了。
此后经过选举,原Follower成为了新Leader,新Leader中Px确定是未Commit的,系统如何保证Px生效呢? 这个还没看研究源码,有知道请告知下!!

典型应用场景

数据发布/订阅

数据的发布/订阅系统,一般也用做配置中心。在分布式系统中,你可能有成千上万个服务节点,若是想要对全部服务的某项配置进行更改,因为数据节点过多,你不可逐台进行修改,而应该在设计时采用统一的配置中心。以后发布者只须要将新的配置发送到配置中心,全部服务节点便可自动下载并进行更新,从而实现配置的集中管理和动态更新。
Zookeeper经过Watcher机制能够实现数据的发布和订阅。分布式系统的全部的服务节点能够对某个ZNode注册监听,以后只须要将新的配置写入该ZNode,全部服务节点都会收到该事件。

命名服务

在分布式系统中,一般须要一个全局惟一的名字,如生成全局惟一的订单号等,Zookeeper能够经过顺序节点的特性来生成全局惟一ID,从而能够对分布式系统提供命名服务。

Master选举

分布式系统一个重要的模式就是主从模式(Master/Salves),Zookeeper能够用于该模式下的Matser选举。可让全部服务节点去竞争性地建立同一个ZNode,因为Zookeeper不能有路径相同的ZNode,必然只有一个服务节点可以建立成功,这样该服务节点就能够成为Master节点。

分布式锁

能够经过Zookeeper的临时节点和Watcher机制来实现分布式锁,这里以排它锁为例进行说明:
分布式系统的全部服务节点能够竞争性地去建立同一个临时ZNode,因为Zookeeper不能有路径相同的ZNode,必然只有一个服务节点可以建立成功,此时能够认为该节点得到了锁。其余没有得到锁的服务节点经过在该ZNode上注册监听,从而当锁释放时再去竞争得到锁。锁的释放状况有如下两种:

  1. 当正常执行完业务逻辑后,客户端主动将临时ZNode删除,此时锁被释放;
  2. 当得到锁的客户端发生宕机时,临时ZNode会被自动删除,此时认为锁已经释放。

当锁被释放后,其余服务节点则再次去竞争性地进行建立,但每次都只有一个服务节点可以获取到锁,这就是排他锁。

集群管理

Zookeeper还能解决大多数分布式系统中的问题:
如能够经过建立临时节点来创建心跳检测机制。若是分布式系统的某个服务节点宕机了,则其持有的会话会超时,此时该临时节点会被删除,相应的监听事件就会被触发。

  1. 分布式系统的每一个服务节点还能够将本身的节点状态写入临时节点,从而完成状态报告或节点工做进度汇报。
  2. 经过数据的订阅和发布功能,Zookeeper还能对分布式系统进行模块的解耦和任务的调度。
  3. 经过监听机制,还能对分布式系统的服务节点进行动态上下线,从而实现服务的动态扩容。

参考材料

  1. 分析Zookeeper的一致性原理
相关文章
相关标签/搜索