节点信息
名称 | 说明 |
cZxid | 创建该节点所分配的全局事务id |
ctime | 创建时间 |
mZxid | 更新该节点数据所分配的全局事务id |
mtime | 更新时间 |
pZxid | 子节点的最新事务id |
cversion | 子节点版本,表示对子节点的更改次数 |
dataversion | 数据版本,数据每发生一次变化,数据版本增加1 |
aclVersion | ACL的更新次数,实际上是权限更新的次数 |
ephemeralOwner | 如果不是临时节点,则此值为0;如果是临时节点,则此值是其会话id |
dataLength | 数据的字节个数 |
numChildren | 子节点的个数 |
选举机制
一、选举机制
- 第一阶段:数据恢复阶段
每台Zookeeper服务器在启动的时候,都会从本地的数据目录中找到自己所拥有的最大事务id。 - 第二阶段:选举阶段
每一个Zookeeper的服务器都会推荐自己当leade并且提交选举协议:- 自己所拥有的最大事务id - Zxid
- 自己的选举id - myid
- 逻辑时钟值,作用是确保每一台Zookeeper服务器都会处在同一轮选举中
- 节点状态
- Looking - 选举状态
- follower - 追随者
- leader - 领导者
- observer - 观察者
二、PK原则
- 在选举的时候会先比较两个节点的最大事务id即Zxid。Zxid越大,则说明事务越新。Zxid较大的会胜出
- 如果Zxid一致,则比较选举id,选举id较大的胜出。
- 满足过半性:即超过一半的节点才能成为leader
三、过半性
- 过半选举:即只有一个节点胜过一半的节点之后才能成为leader
- 过半服务:即只有Zookeeper集群中超过一半的节点存活才能对外提供服务
- 过半操作:即只有Zookeeper集群中超过一半的节点同意才会提交请求
ZAB协议
一、概述
- ZAB(Zookeeper Atomic Broadcast)协议是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复的原子广播协议
- ZAB协议是一种特别为ZooKeeper设计的崩溃可恢复的原子消息广播算法。这个算法是一种类2PC算法,在2PC基础上做的改进
- ZAB协议包括两种基本的模式,分别是:
- 消息原子广播(保证数据一致性)
- 崩溃恢复(解决2pc算法的单点问题)
二、消息原子广播
- 在ZooKeeper中,主要依赖ZAB协议来实现分布式数据一致性,基于该协议,ZooKeeper实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性,实现分布式数据一致性的这一过程称为消息广播(原子广播)
- ZAB协议的消息广播过程使用的是原子广播协议,类似于一个二阶段提交过程。但是相较于2PC算法,不同的是ZAB协议引入了过半性思想
- ZooKeeper使用一个单一的主进程(leader服务器)来接收并处理客户端的所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以事务Proposal的形式广播到所有的副本进程(follower或observer)上去。即:所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为leader服务器,而余下的其他服务器则成为follower服务器或observer
- 具体流程:
- 针对客户端的事务请求,leader服务器会先将该事务写到本地的log文件中
- 然后,leader服务器会为这次请求生成对应的事务Proposal并且为这个事务Proposal分配一个全局递增的唯一的事务ID,即Zxid
- leader服务器会为每一个follower服务器都各自分配一个单独的队列,将需要广播的事务Proposal依次放入队列中,发送给每一个follower
- 每一个follower在收到队列之后,会从队列中依次取出事务Proposal,写道本地的事务日志中。如果写成功了,则给leader返回一个ACK消息
- 当leader服务器接收到半数的follower的ACK相应之后,就会广播一个Commit消息给所有的follower以通知其进行事务提交,同时leader自身也进行事务提交
- leader在收到Commit消息后完成事务提交
- 当然,在这种简化了的二阶段提交模型下,是无法处理Leader服务器崩溃退出而带来的数据不一致问题的,因此在ZAB协议中添加了另一个模式,即采用崩溃恢复模式来解决这个问题
- 整个消息广播协议是基于具有FIFO特性的TCP协议来进行网络通信的,因此能够很容易地保证消息广播过程中消息接收与发送的顺序性
三、崩溃恢复
- 当leader服务器出现崩溃、重启等场景,或者因为网络问题导致过半的follower不能与leader服务器保持正常通信的时候,Zookeeper集群就会进入崩溃恢复模式
- 进入崩溃恢复模式后,只要集群中存在过半的服务器能够彼此正常通信,那么就可以选举产生一个新的leader
- 每次新选举的leader会自动分配一个全局递增的编号,即epochid
- 当选举产生了新的leader服务器,同时集群中已经有过半的机器与该leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和leader服务器的数据状态保持一致
- 当集群中已经有过半的follower服务器完成了和leader服务器的状态同步,那么整个服务框架就可以进入消息广播模式了
- 当一台同样遵守ZAB协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式:找到leader所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中
简介
一、简介
- Zookeeper是根据谷歌的论文《The Chubby Lock Service for Loosely Couple Distribute System 》所做的开源实现
- Zookeeper是Apache Hadoop的子组件之一,但是不仅仅支持Hadoop,还支持绝大部分的分布式集群
- Zookeeper是一个分布式的协调服务框架,用于解决分布式环境下的一些常见问题:集群管理、统一命名服务,信息配置管理,分布式锁等等
二、分布式存在的问题
- 死锁:至少有一个线程把持了资源,但是由于线程之间的相互等待,所有线程不耗费CPU
- 活锁:所有的线程都没有把持资源而导致资源产生了浪费。而且由于线程之间一直在调度,导致CPU一直处于被占用状态。
- 分布式环境下,需要引入监控和管理节点来保证服务器之间的任务调度
- 为了防止单一监控节点带来单点问题,所以需要引入多个监控节点
- 为了防止多个监控节点之间的任务调度不同,需要在其中选举出一个主监控节点
- 确定一套选举算法
- 为了防止主节点宕机而导致所有数据丢失,需要将监控节点的数据进行统一
- 监控节点以及服务节点的统一配置
三、特点
- Zookeeper是一个树状结构(Znode树)
- 树状结构(Znode树)的根节点为 /
- Zookeeper的每一个节点称之为是znode节点
- 所有的znode节点都是从根节点开始计算
- 每一个znode节点都必须存储数据
- 每一个持久的znode节点都可以挂载子节点
- 每一个znode节点的路径都是唯一的。所以基于这一个特点,可以做集群的统一命名服务
- Znode树是维系在内存中的,即每一个znode节点中的数据也是维系在内存中,这样做的目的是方便快速查找
- 不能利用Zookeeper存储海量数据,原因:
- Znode树维系在内存中,并且多个Zookeeper存储的是相同的数据造成内存的浪费;
- Zookeeper是做分布式的协调服务而不是做存储服务
- Zookeeper提供了持久化机制,持久化的目录由zoo.cfg中的dataDir属性来决定
- Zookeeper会为每一次的事务(增加、删除、更新)提供一个全局的递增的事务id
四、节点类型
类型 | 解释 |
PERSISTENT | 持久节点 |
EPHEMERAL | 临时节点 |
PERSISTENT_SEQUENTIAL | 持久顺序节点 |
EPHEMERAL_SEQUENTIAL | 临时顺序节点 |
1 Znode
在 Zookeeper 中,znode 是一个跟 Unix 文件系统路径相似的节点,可以往这个节点存储 或获取数据。 Zookeeper 底层是一套数据结构。这个存储结构是一个树形结构,其上的每一个节点, 我们称之为“znode” zookeeper 中的数据是按照“树”结构进行存储的。而且 znode 节点还分为 4 中不同的类 型。 每一个 znode 默认能够存储 1MB 的数据(对于记录状态性质的数据来说,够了) 可以使用 zkCli 命令,登录到 zookeeper 上,并通过 ls、create、delete、get、set 等命令 操作这些 znode 节点
2 Znode 节点类型
(1)PERSISTENT 持久化节点: 所谓持久节点,是指在节点创建后,就一直存在,直到 有删除操作来主动清除这个节点。否则不会因为创建该节点的客户端会话失效而消失。
(2)PERSISTENT_SEQUENTIAL 持久顺序节点:这类节点的基本特性和上面的节点类 型是一致的。额外的特性是,在 ZK 中,每个父节点会为他的第一级子节点维护一份时序, 会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属 性,那么在创建节点过程中,ZK 会自动为给定节点名加上一个数字后缀,作为新的节点名。 这个数字后缀的范围是整型的最大值。 在创建节点的时候只需要传入节点 “/test_”,这样 之后,zookeeper 自动会给”test_”后面补充数字。
(3)EPHEMERAL 临时节点:和持久节点不同的是,临时节点的生命周期和客户端会 话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提 到的是会话失效,而非连接断开。另外,在临时节点下面不能创建子节点。 这里还要注意一件事,就是当你客户端会话失效后,所产生的节点也不是一下子就消失 了,也要过一段时间,大概是 10 秒以内,可以试一下,本机操作生成节点,在服务器端用 命令来查看当前的节点数目,你会发现客户端已经 stop,但是产生的节点还在。
(4) EPHEMERAL_SEQUENTIAL 临时顺序节点:此节点是属于临时节点,不过带 有顺序,客户端会话结束节点就消失。
五、特性总结
- 数据一致性:客户端不论连接到哪个Zookeeper节点上,展示给它都是同一个视图,即查询的数据都是一样的。这是Zookeeper最重要的性能
- 原子性:对于事务决议的更新,只能是成功或者失败两种可能,没有中间状态。 要么都更新成功,要么都不更新。即,要么整个集群中所有机器都成功应用了某一事务,要么都没有应用,一定不会出现集群中部分机器应用了改事务,另外一部分没有应用的情况。
- 可靠性:一旦Zookeeper服务端成功的应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直保留下来,除非有另一个事务又对其进行了改变。
- 实时性:Zookeeper保证客户端将在非常短的时间间隔范围内获得服务器的更新信息,或者服务器失效的信息,或者指定监听事件的变化信息。(前提条件是:网络状况良好)
- 顺序性:如果在一台服务器上消息a在消息b前发布,则在所有服务器上消息a都将在消息b前被发布。客户端在发起请求时,都会跟一个递增的命令号,根据这个机制,Zookeeper会确保客户端执行的顺序性。底层指的是Zxid。可以通过事务log来看。
- 过半性:Zookeeper集群必须有半数以上的机器存活才能正常工作。因为只有满足过半性,才能满足选举机制选出leader。因为只有过半,在做事务决议时,事务才能更新。所以一般来说,zookeeper集群的数量最好是奇数个