zookeeper 基本知识介绍

原创
2017/03/21 20:40
阅读数 310

zookeeper是hadoop的一个子项目,它与hadoop有密切的关系但确没有任何的依赖,是来协调处理分布式任务的, 分布式的应用程序可以基于它,实现同步服务,配置服务,命名服务等功能

设计的目标

  1.1 操作简单: zookeeper 主要通过多层次的命名空间来协调处理分布式任务,一个命名空间就是一个数据寄存器,称为znode,节点数据保存在内存中,所以可以实现高吞吐和低延时

 1.2 自我复制:如下图

                                                                                (图一)

Zookeeper 主要是在各个Server间复制数据的,Zookeeper集群里面的服务之间是互相透明的,都知道彼此的存在,它们在各自的内存从维持了一个状态图像,以及持久存储中的事务日志和快照,也就是说集群中的任何一台server里面的节点数据与其他server里面的数据都是一致的,所以当集群中某一台server 出现故障的时候,client 会自动连接到另外一个server ,正是因为这样所以保证了它的高可用

1.3 有序:Zookeeper 通过更新一个计数器来反映Zookeeper的事务顺序,简单来说就是给每次写请求都生成一个有序的zxid,执行的时候按照数字的顺序去执行同步

1.4 快速:是指读取数据的性能,因为集群的所有server 数据视图是一致的,所以可以由很多节点去提供读取服务

数据模型和多层次的名词空间

zookeeper 的多层次命名空间就像常见的文件系统,每个节点的路径是唯一的,如下图

                                  (图二)

节点

我所理解的zookeeper节点分为两类

1.持久化节点(zookeeper节点),如图二所示,是通过树一样的结构来进行维护的,每个节点通过路径来标示和访问,除此之外每个节点还有有自身的一些基本信息,数据,数据长度,创建时间,修改时间是不是很像文件无论Linux 还是windows 一个文件夹的基本信息,因为节点下面可以挂子节点所有又可以看成一个目录,此类zonde,通过管理包含数据,ACL,时间戳的版本号数据结构,来实现缓存生效以及协调更新,而且每一个zonde数据的写都是原子性操

2.临时节点 ,此节点的生命周期是client 与服务建立连接后 产生session后生成,当session的生命周期结束,这些临时节点也将被删除,这种临时节点在某些场合也发挥着非常重要的作用,例如分布式锁的场景

节点数据的update 和watch

zookeeper 支持watch 的即支持监听的,client 可以在zonde上设置watch。当zonde变更的时,watch 将被触发并移除。当watch 被触发后,client就会收到一个数据吧,说明zonde已经改变了同时将本地的zonde数据更新与zookeeper里面的同步,如果是client 与zoookeeper server之间的连接被断开,则client 将接受本地通知,同时zookeeper 服务也会将这个client重可以用的ip列表中自动移除,正是基于这种可以实时监听节点数据变回并能及时通知客户端,因此zookeeper才成为诸多项目的服务注册中心

保证

1.Sequential Consistency-顺序一致性:clinet 的更新将在他们应用时按照顺序进行发送,即先请求先执行时有序的

2.Atomicity 原子性(这个很重要):更新非成功即失败,不会存在中间状态

3.Single System Image 单一系统映像:一个client 将看到相同的服务视图,不管它连接的是集群中的那一个server,原因就是前面说的自我复制

4.Reliability 可靠性(类似持久化):一旦更新已被提交应用,它会从那个时候一直持续,知道client再次更新为止

基于上面4点,我们可以看出zookeeper 是强一致性的,因此在CAP 里面它是CP的,A 是被舍弃了的

内部工作原理

 zookeeper 的核心就是消息处理的原子性,能够保持所有的server 同步

它是通过以下几点来保证消息处理的原子性

1.可靠的消息传递---如过一个消息被某个server接收,那么其他的server肯定也收到了这条消息(广播)

2.顺序接受---如果消息a先于b被某个server接收,那么其他server接收a都会先于b ,a和b同时传递的话,要么a在前要么b在前,不会出现并行或混乱冲突的情况

3.因果关系--如果消息a先于b,b又先于c,那么a肯定是先c的

基于上面我们知道,zookeeper  server接收到的消息顺序就是client发送出来的顺序,加上zookeeper对消息处理本质上就是对zonde数据的处理是原子性操作的,所以才说zookeeper 处理消息时原子性的

zookeeper 整个消息的处理流程如下图,

1.Lead 发送提议(你可以理解成消息)给所有的server的是顺序发送的,所以server 接收到请求也是顺序接收的

2.server 顺序的处理接收的消息,这就意味着每个消息必须被顺序的确认,从而leader也是顺序的接收到确认的消息

3.一旦法定人数的follower 返回ack 同意这个提议,leader 提交自身改条提议的事务,持久化事务日志,同时leader会发布一个commit 消息给所有的server

4.commit 消息会被server 顺序的处理,提交commit 消息对应的事务,持久化数据

leader激活条件:

1.leader的zxid必须是follower 中最高的

2.将法定数量的server提交给leader

正是这个激活条件,所以整个选举Leader的过程就是一个比较zxid 大小的过程,例如 3.4.0后的Zookeeper的版本只保留了TCP版本的FastLeaderElection选举算法 规则如下

    vote_sid:接收到的投票中所推举Leader服务器的SID。
    vote_zxid:接收到的投票中所推举Leader服务器的ZXID。
    self_sid:当前服务器自己的SID。
    self_zxid:当前服务器自己的ZXID
    每次对收到的投票的处理,都是对(vote_sid, vote_zxid)和(self_sid, self_zxid)对比的过程。
    规则一:如果vote_zxid大于self_zxid,就认可当前收到的投票,并再次将该投票发送出去。
    规则二:如果vote_zxid小于self_zxid,那么坚持自己的投票,不做任何变更。
    规则三:如果vote_zxid等于self_zxid,那么就对比两者的SID,如果vote_sid大于self_sid,那么就认可当前收到的投票,并再次将该投票发送出去。
    规则四:如果vote_zxid等于self_zxid,并且vote_sid小于self_sid,那么坚持自己的投票,不做任何变更。

第一次选举,每个follower 都提议将自己做为主节点,向其他server发送提议,这个时候自己也会接收到其它server发过来的提议,然后根据上述规则,进行比较,再重新发送选举消息,进行第二次选举

如上图这是一个最简单的场景,当A 发出提议的时候,它会改变掉B,C 的第一次提议,在一轮选举结束后,最终B,C 的提议都会变成A ,所以A成为新的leader

展开阅读全文
打赏
1
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
1
分享
返回顶部
顶部