赞
踩
Zookeeper作为一个优秀高效且可靠的分布式协调框架,ZooKeeper 在解决分布式数据一致性问题时并没有直接使用Paxos算法 ,而是专门定制了一致性协议叫做 ZAB(ZooKeeper Automic Broadcast) 原子广播协议,该协议能够很好地支持 崩溃恢复 ;
一:Zookeeper应用场景
统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。
(1)统一配置管理
①分布式环境下,配置文件同步非常常见:
1)一般要求一个集群中,所有节点的配置信息是一致的,比如Kafka集群;
2)对配置文件修改后,希望能够快读同步到各个节点上;
②配置管理可交由Zookeeper实现:
1)可将配置信息写入Zookeeper上的一个Znode节点上;
2)各个客户端服务器监听这个Znode;
3)一旦Znode中的数据被修改了,Zookeeper将通知给各个客户端服务器;
(2)统一集群管理
③在分布式环境中,实时掌握每个节点的状态是必要的:
1)可根据节点实时状态做出一些调整;
④Zookeeper可以实现实时监控节点状态变化:
1)可将节点信息写入Zookeeper上的一个Znode节点上;
2)监听这个Znode可获取它的实时状态变化;
(3)软负载均衡
⑤在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新客户端请求;
二:Zookeeper的特点
(1)一个领导者leader,多个跟随者follower组成的集群;
(2)集群中只要半数以上节点存活,Zookeeper集群就能正常服务;
(3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接哪个Server,数据都是一致的;
(4)数据更新原子性:一次数据更新要么成功,要么失败;
(5)更新请求顺序进行:来自同一个Client的更新请求,按其发送顺序一次执行;
(6)实时性:在一定时间范围内,Client能读到最新的数据;
ls path:查看当前znode的子节点;
create:创建;
get path:获得节点的值;
set:设置节点的具体值;
stat:查看节点状态;
delete:删除节点;
deleteall:递归删除节点;
(1)首先有一个main()线程;
(2)在main()线程中创建Zookeeper客户端,这时就会创建两个线程,一个负责网络连接通信(connect)、一个负责监听(listen);
(3)通过connect线程将注册的监听事件发送给Zookeeper;
(4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中;
(5)Zookeeper监听到有数据或路径变化,就会将这个消息发送给listen线程;
(6)listen线程内部调用了process()方法进行处理;
(1)Paxos算法,是一种基于消息传递且具有高度容错性的一致性算法;
(2)Paxos算法解决的问题:就是如何在一个分布式系统中对某个数据值达成一致,并且保证不论发生任何异常(机器宕机、网络异常),都不会破坏整个系统的一致性;
(3)Paxos算法的描述:
①在一个Paxos系统中,首先将所有节点划分为提议者(Proposers)、接收者(Acceptors)和学习者(Learners),每个节点都可以身兼数职;
②一个完整的Paxos算法流程分为3个阶段:
1)Prepare阶段:
a.提议者(Proposers)向多个接收者(Acceptors)发出提议(Propose),请求承诺(Promise);
b.接收者(Acceptors)针对收到的提议(Propose)请求,进行承诺(Promise);
2)Accept阶段:
a.提议者(Proposers)收到多数接收者(Acceptors)承诺的提议(Propose)后,正式向接收者(Acceptors)发出提议(Propose);
b.接收者(Acceptors)针对收到的提议(Propose)请求,进行接收(Accept)处理;
3)Learn阶段:
a.提议者(Proposers)将形成的决议发送给所有的学习者(Learners);
(4)Paxos算法缺点
①当系统中有一个以上的提议者(Proposers)时,多个提议者(Proposers)之间相互争夺接收者(Acceptors),造成迟迟无法达成一致的情况,针对此情况,一种改进的Paxos算法被提出:从系统中选出一个节点作为Leader,只有Leader能够发起提议。这样,一次Paxos流程中,只有一个提议者,不会出现活锁的情况;
(1)什么是ZAB协议?
ZAB(ZooKeeper Atomic Broadcast原子广播)协议是为分布式协调服务ZooKeeper框架专门设计的一种支持崩溃恢复的原子广播协议。在ZooKeeper中,主要依赖ZAB协议来实现分布式数据一致性,基于ZAB协议,ZooKeeper实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性;
(2)ZAB的特点
基于该协议,Zookeeper设计为只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader客户端将数据同步到其他Follower节点。即Zookeeper只有一个Leader可以发起提案。
(3)ZAB协议内容
ZAB协议包括两种基本的模式:消息广播、崩溃恢复;
(1)消息广播概念:
①当集群中已经有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。 当一台同样遵守ZAB协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式:找到Leader所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去;
(2)消息广播流程
①客户端发起一个写操作请求;
②Leader服务器将客户端的请求转化为事务提案(Proposal),同时为每个事务提案(Proposal)分配一个全局的ID,即zxid;
③Leader服务器为每个Follower服务器分配一个单独的队列,然后将需要广播的提案(Proposal)依次放到队列中去,并且根据FIFO策略进行消息发送;
④Follower接收到提案(Proposal)后,会首先将其以事务日志的方式写入本地磁盘中,写入成功后向Leader反馈一个Ack响应消息;
⑤Leader接收到超过半数以上Follower的Ack响应消息后,即认为消息发送成功,可以发送commit消息;
⑥Leader向所有Follower广播commit消息,同时自身也会完成事务提交。Follower 接收到commit消息后,会将上一条事务提交;
总结:Zookeeper采用Zab协议的核心,就是只要有一台服务器提交了提案(Proposal),就要确保所有的服务器最终都能正确提交提案(Proposal);
问题:当出现以下2种情况,可能会造成数据不一致问题:(1)Leader 发起一个事务提案(Proposal)后就宕机,Follower都没有提案(Proposal);(2)Leader收到半数ACK后宕机,没来得及向Follower发送Commit;为解决此问题,Zab引入了崩溃恢复模式;
(3)崩溃恢复概念:
① 当整个服务框架在启动过程中,或是当Leader服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的Leader服务器。当选举产生了新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。其中,所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和Leader服务器的数据状态保持一致;
(4)崩溃恢复流程
崩溃恢复主要包括两部分:Leader选举和数据恢复;
① Leader选举,Zab协议需要保证选举出来的Leader需要满足以下条件:
1)新选举出来的Leader不能包含未提交的提案(Proposal),即新Leader必须都是已经提交了提案(Proposal)的Follower服务器节点;
2)新选举的Leader节点中含有最大的zxid,这样做的好处是可以避免Leader服务器检查提案(Proposal)的提交和丢弃工作;
② Zab如何数据同步?
1)完成Leader选举后,在正式开始工作之前(接收事务请求,然后提出新的提案(Proposal)),Leader服务器会首先确认事务日志中的所有的提案(Proposal)是否已经被集群中过半的服务器Commit;
2)Leader服务器需要确保所有的Follower服务器能够接收到每一条事务的提案(Proposal),并且能将所有已经提交的事务提案(Proposal)应用到内存数据中。等到Follower 将所有尚未同步的事务提案(Proposal)都从Leader 服务器上同步过,并且应用到内存数据中以后,Leader才会把该Follower加入到真正可用的Follower列表中;
Zookeeper的核心是原子广播,这个机制保证了各个服务器之间的数据同步。实现这个机制的协议叫做ZAB协议。ZAB协议有两种模式:恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃之后后,ZAB就进入了恢复模式,当领导者被选举出来,且大多数服务器完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader 和 server 具有相同的系统状态;
Zookeeper保证数据一致性用的是ZAB协议,通过这个ZAB协议来进行Zookeeper集群间的数据同步,来保证数据的一致性;
Zookeeper写数据的机制是客户端把写请求发送到leader节点上,leader节点会把数据通过提案(proposal)请求发送给所有节点,所有到节点接收到数据以后,都会写到自己的本地磁盘上,写好了之后会发送一个ACK请求给leader,leader只要接收到过半的节点发送回来ACK确认响应,就会发送提交(commit)消息给各个节点,各个节点就会把消息放入到内存中(放内存是为了保证高性能),该消息就会用户可见了;
那么这个时候,如果Zookeeper要想保证数据一致性,就需要考虑如下两个情况:
情况1:leader执行提交(commit)了,还没来得及给follower发送提交(commit)的时候,leader宕机了,这个时候如何保证消息的一致性?
情况2:客户端把消息写到leader了,但是leader还没发送提案(proposal)消息给其他节点,这个时候leader宕机了,leader宕机后恢复的时候,此消息又该如何处理?
解决方案1:ZAB的崩溃恢复机制
针对情况一,当leader宕机以后,Zookeeper会选举出来新的leader,新的leader启动之后要到磁盘上面去检查是否存在没有提交(commit)的消息,如果存在,就继续检查看其它follower有没有对这条消息进行了提交(commit),如果有过半节点对这条消息进行了ACK确认,但是没有提交(commit),那么新对leader要完成提交(commit)的操作;
解决方案2:ZAB恢复中删除数据机制
针对情况二,客户端把消息写到leader了,但是leader还没发送提案(proposal)消息给其他节点,这个时候leader宕机了,这个时候对于用户来说,这条消息是写失败的。假设过了一段时间以后leader节点又恢复了,不过这个时候它角色就变为了follower了,它在检查自己磁盘的时候会发现自己有一条消息没有进行提交(commit),此时就会检测消息的编号,消息是有编号的,由高32位和低32位组成,高32位是用来体现是否发生过leader切换的,低32位就是展示消息的顺序的。这个时候当前的节点就会根据高32位知道目前leader已经切换过了,所以就把当前的消息给删除掉,然后从新的leader中进行同步数据,这样就保证了数据的一致性;
CAP理论告诉我们,一个分布式系统不可能同时满足以下三种:
① 一致性(C:Consistency)
② 可用性(A:Available)
③ 分区容错性(P:Partition Tolerance)
这三个基本需求,最多只能同时满足其中的两项,因为P是必须的,因此往往选择就在CP或者AP中;
(1)一致性
在分布式环境中,一致性是指数据在多个副本之间是否能够保持数据一致的特性。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态;
(2)可用性
可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果;
(3)分区容错性
分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障;
ZooKeeper保证的是CP:
(1)ZooKeeper不能保证每次服务请求的可用性。(注:在极端环境下,ZooKeeper可能会丢弃一些请求,消费者程序需要重新请求才能获得结果)。所以说,ZooKeeper不能保证服务可用性;
(2)进行Leader选举时集群都是不可用;
半数机制:集群中半数以上机器存活,集群可用。所以Zookeeper适合安装奇数台服务器。
假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么。
(1)服务器1启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是LOOKING状态。
(2)服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1、2还是继续保持LOOKING状态。
(3)服务器3启动,根据前面的理论分析,服务器3成为服务器1、2、3中的Leader,而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的Leader。
(4)服务器4启动,根据前面的分析,理论上服务器4应该是服务器1、2、3、4中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它成为Follower。
(5)服务器5启动,同4一样成为Follower。
Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理架构,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应;
客户端会对某个Znode节点建立一个watcher事件,当该Znode节点发生变化时,这些客户端会收到Zookeeper的通知,然后客户端可以根据Znode节点变化来做出业务上的改变;
Znode有两种类型:
短暂(ephemeral):客户端和服务器端断开连接后,创建的节点自己删除;
持久(persistent):客户端和服务器端断开连接后,创建的节点不删除;
细分:
(1)普通持久节点;
(2)带序号持久节点;
(3)普通临时节点;
(4)带序号临时节点;
ZooKeeper集群在宕掉几个ZooKeeper服务器之后,如果剩下的ZooKeeper服务器个数大于宕掉的个数的话整个ZooKeeper才依然可用。
假如我们的集群中有n台ZooKeeper服务器,那么也就是剩下的服务数必须大于n/2。假如我们有3台,那么最大允许宕掉1台ZooKeeper服务器,如果我们有4台的的时候也同样只允许宕掉1台。假如我们有5台,那么最大允许宕掉2台ZooKeeper服务器,如果我们有6台的的时候也同样只允许宕掉2台。
综上所述,我们发现2n和2n-1的容忍度是一样的,都是n-1。所以,何必增加那一个不必要的ZooKeeper服务器呢?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。