zookeeper理论

1.1.1    Zookeeper的保证

l         顺序性,client的updates请求都会根据它发出的顺序被顺序的处理;

l         原子性,  一个update操作要么成功要么失败,没有其他可能的结果;

l         一致的镜像,client不论连接到哪个server,展示给它都是同一个视图;

l         可靠性,一旦一个update被应用就被持久化了,除非另一个update请求更新了当前值

l         实时性,对于每个client它的系统视图都是最新的

1.1.2    Zookeeper server角色

领导者(Leader) : 领导者不接受client的请求,负责进行投票的发起和决议,最终更新状态。

跟随者(Follower): Follower用于接收客户请求并返回客户结果。参与Leader发起的投票。

观察者(observer): Oberserver可以接收客户端连接,将写请求转发给leader节点。但是Observer不参加投票过程,只是同步leader的状态。Observer为系统扩展提供了一种方法。

学习者 ( Learner ) : 和leader进行状态同步的server统称Learner,上述Follower和Observer都是Learner。

1.1.3    Zookeeper集群

通常Zookeeper由2n+1台servers组成,每个server都知道彼此的存在。每个server都维护的内存状态镜像以及持久化存储的事务日志和快照。对于2n+1台server,只要有n+1台(大多数)server可用,整个系统保持可用。

系统启动时,集群中的server会选举出一台server为Leader,其它的就作为follower(这里先不考虑observer角色)。接着由follower来服务client的请求,对于不改变系统一致性状态的读操作,由follower的本地内存数据库直接给client返回结果;对于会改变系统状态的更新操作,则交由Leader进行提议投票,超过半数通过后返回结果给client。

二.Zookeeper server工作原理

Zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式和广播模式。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数server的完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和server具有相同的系统状态。

一旦leader已经和多数的follower进行了状态同步后,他就可以开始广播消息了,即进入广播状态。这时候当一个server加入zookeeper服务中,它会在恢复模式下启动,发现leader,并和leader进行状态同步。待到同步结束,它也参与消息广播。Zookeeper服务一直维持在Broadcast状态,直到leader崩溃了或者leader失去了大部分的followers支持。

Broadcast模式极其类似于分布式事务中的2pc(two-phrase commit 两阶段提交):即leader提起一个决议,由followers进行投票,leader对投票结果进行计算决定是否通过该决议,如果通过执行该决议(事务),否则什么也不做。

广播模式需要保证proposal被按顺序处理,因此zk采用了递增的事务id号(zxid)来保证。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64为的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch。低32位是个递增计数。

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的server都恢复到一个正确的状态。

首先看一下选举的过程,zk的实现中用了基于paxos算法(主要是fastpaxos)的实现。具体如下:

1.每个Server启动以后都询问其它的Server它要投票给谁。

2.对于其他server的询问,server每次根据自己的状态都回复自己推荐的leader的id和上一次处理事务的zxid(系统启动时每个server都会推荐自己)

3.收到所有Server回复以后,就计算出zxid最大的哪个Server,并将这个Server相关信息设置成下一次要投票的Server。

4.计算这过程中获得票数最多的的sever为获胜者,如果获胜者的票数超过半数,则改server被选为leader。否则,继续这个过程,直到leader被选举出来。

此外恢复模式下,如果是重新刚从崩溃状态恢复的或者刚启动的的server还会从磁盘快照中恢复数据和会话信息。(zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复)

选完leader以后,zk就进入状态同步过程。

1.leader就会开始等待server连接

2.Follower连接leader,将最大的zxid发送给leader

3.Leader根据follower的zxid确定同步点

4.完成同步后通知follower 已经成为uptodate状态

5.Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

. ZookeeperServer工作流程

3.1.1 主线程的工作:

1. 刚开始时各个Server处于一个平等的状态peer

2. 主线程加载配置后启动。

3. 主线程启动QuorumPeer线程,该线程负责管理多数协议(Quorum),并根据表决结果进行角色的状态转换。

4. 然后主线程等待QuorumPeer线程。

3.1.2  QuorumPeer线程

1. 首先会从磁盘恢复zkdatabase(内存数据库),并进行快照回复。

2. 然后启动server的通信线程,准备接收client的请求。

3. 紧接着该线程进行选举leader准备,选择选举算法,启动response线程(根据自身状态)向其他server回复推荐的leaer。

4. 刚开始的时候server都处于looking状态,进行选举根据选举结果设置自己的状态和角色。

3.1.3 quorumPeer有几种状态

1. Looking: 寻找状态,这个状态不知道谁是leader,会发起leader选举

2. Observing: 观察状态,这时候observer会观察leader是否有改变,然后同步leader的状态

3. Following:  跟随状态,接收leader的proposal ,进行投票。并和leader进行状态同步

4. Leading:    领导状态,对Follower的投票进行决议,将状态和follower进行同步

当一个Server发现选举的结果自己是Leader把自己的状态改成Leading,如果Server推荐了其他人为Server它将自己的状态改成Following。做Leader的server如果发现拥有的follower少于半数时,它重新进入looking状态,重新进行leader选举过程。(Observing状态是根据配置设置的)。

3.2 Leader的工作流程:

3.2.1 Leader主线程:

1.首先leader开始恢复数据和清除session

启动zk实例,建立请求处理链(Leader的请求处理链):PrepRequestProcessor->ProposalRequestProcessor->CommitProcessor->Leader.ToBeAppliedRequestProcessor ->FinalRequestProcessor

2.得到一个新的epoch,标识一个新的leader , 并获得最大zxid(方便进行数据同步)

3.建立一个学习者接受线程(来接受新的followers的连接,follower连接后确定followers的zxvid号,来确定是需要对follower进行什么同步措施,比如是差异同步(diff),还是截断(truncate)同步,还是快照同步)

4. 向follower建立一个握手过程leader->follower NEWLEADER消息,并等待直到多数server发送了ack

5. Leader不断的查看已经同步了的follower数量,如果同步数量少于半数,则回到looking状态重新进行leaderElection过程,否则继续step5.

3.2.2 LearnerCnxAcceptor线程

1.该线程监听Learner的连接

2.接受Learner请求,并为每个Learner创建一个LearnerHandler来服务

3.2.3 LearnerHandler线程的服务流程

1.检查server来的第一个包是否为follower.info或者observer.info,如果不是则无法建立握手。

2. 得到Learner的zxvid,对比自身的zxvid,确定同步点

3.和Learner建立第二次握手,向Learner发送NEWLEADER消息

4.与server进行数据同步。

5.同步结束,知会server同步已经ok,可以接收client的请求。

6. 不断读取follower消息判断消息类型

i.           如果是LEADER.ACK,记录follower的ack消息,超过半数ack,将proposal提交(Commit)

ii.         如果是LEADER.PING,则维持session(延长session失效时间)

iii.        如果是LEADER.REQEST,则将request放入请求链进行处理–Leader写请求发起proposal,然后根据follower回复的结果来确定是否commit的。最后由FinallRequestProcessor来实际进行持久化,并回复信息给相应的response给server

3.3 Follower的工作流程:

1.启动zk实例,建立请求处理链:FollowerRequestProcessor->CommitProcessor->FinalProcessor

2.follower首先会连接leader,并将zxid和id发给leader

3.接收NEWLEADER消息,完成握手过程。

4.同leader进行状态同步

5.完成同步后,follower可以接收client的连接

5.接收到client的请求,根据请求类型

l         对于写操作, FollowerRequestProcessor会将该操作作为LEADER.REQEST发给LEADER由LEADER发起投票。

l         对于读操作,则通过请求处理链的最后一环FinalProcessor将结果返回给客户端

对于observer的流程不再赘述,observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。

三.关于Zookeeper的扩展

为了提高吞吐量通常我们只要增加服务器到Zookeeper集群中。但是当服务器增加到一定程度,会导致投票的压力增大从而使得吞吐量降低。因此我们引出了一个角色:Observer。

Observers 的需求源于 ZooKeeper  follower服务器在上述工作流程中实际扮演了两个角色。它们从客户端接受连接与操作请求,之后对操作结果进行投票。这两个职能在 ZooKeeper集群扩展的时候彼此制约。如果我们希望增加 ZooKeeper 集群服务的客户数量(我们经常考虑到有上万个客户端的情况),那么我们必须增加服务器的数量,来支持这么多的客户端。然而,从一致性协议的描述可以看到,增加服务器的数量增加了对协议的投票部分的压力。领导节点必须等待集群中过半数的服务器响应投票。于是,节点的增加使得部分计算机运行较慢,从而拖慢整个投票过程的可能性也随之提高,投票操作的会随之下降。这正是我们在实际操作中看到的问题——随着 ZooKeeper 集群变大,投票操作的吞吐量会下降。

所以需要增加客户节点数量的期望和我们希望保持较好吞吐性能的期望间进行权衡。要打破这一耦合关系,引入了不参与投票的服务器,称为 Observers。 Observers 可以接受客户端的连接,将写请求转发给领导节点。但是,领导节点不会要求 Observers 参加投票。相反,Observers 不参与投票过程,仅仅和其他服务节点一起得到投票结果。

这个简单的扩展给 ZooKeeper 的可伸缩性带来了全新的镜像。我们现在可以加入很多 Observers 节点,而无须担心严重影响写吞吐量。规模伸缩并非无懈可击——协议中的一歩(通知阶段)仍然与服务器的数量呈线性关系。但是,这里的穿行开销非常低。因此可以认为在通知服务器阶段的开销无法成为主要瓶颈。

上图显示了一个简单评测的结果。纵轴是从一个单一的客户端发出的每秒钟同步写操作的数量。横轴是 ZooKeeper 集群的尺寸。蓝色的是每个服务器都是 voting 服务器的情况,而绿色的则只有三个是 voting 服务器,其它都是 Observers。图中看到,扩充 Observers,写性能几乎可以保持不变,但如果同时扩展 voting 节点的数量的话,性能会明显下降。显然 Observers 是有效的。因此Observer可以用于提高Zookeeper的伸缩性。

此外Observer还可以成为特定场景下,广域网部署的一种方案。原因有三点:1.为了获得更好的读性能,需要让客户端足够近,但如果将投票服务器分布在两个数据中心,投票的延迟太大会大幅降低吞吐,是不可取的。因此希望能够不影响投票过程,将投票服务器放在同一个IDC进行部署,Observer可以跨IDC部署。2. 投票过程中,Observer和leader之间的消息、要远小于投票服务器和server的消息,这样远程部署对带宽要求就较小。3.由于Observers即使失效也不会影响到投票集群,这样如果数据中心间链路发生故障,不会影响到服务本身的可用性。这种故障的发生概率要远高于一个数据中心中机架间的连接的故障概率,所以不依赖于这种链路是个优点。

Znodes

每个节点在zookeeper中用znode表示。znodes 包含数据变更和acl变更的版本号。znode同样包含时间戳。版本号和时间戳用来帮助zookeeper验证缓存或者协调更新。每次znode数据发生变化都会使版本号增加。例如,每次client接受数据时都会接收到数据的版本号。当client更新或者删除数据时必须给znode提供数据的版本号。如果提供的版本号与实际的版本号不匹配,更新操作会失败。

znode是程序访问的主要实体类。包含如下特性:

Watches

clients 可以为znode设置watch。znode发生改变将会触发watch。当一个watch触发,zookeeper会向client发送通知。

Data Access

在namespace中存储在每个znode上的数据发生的读写操作都是原子性的。读一个znode上的全部数据或者替换掉全部数据都是原子性的。每个znode都有一个Access Contron List(ACL)用来约束哪些人可以执行相应操作。

Zookeeper不是用来做数据库或者存贮大对象的。相反,它只负责协调数据。数据可以来自配置表单、结构化信息等等。这些数据的有一个共同的特点那就是都很小:以Kb为测量单位。Zookeeper的client和server的实现类都会验证znode存储的数据是否小于1M,但是数据应该比平均值小的多。操作大数据将会触发一些消耗时间的额外操作并且影响潜在的操作,因为需要额外的时间在网络和存储介质上转移数据。如果有大数据需要存储,通常的办法是把这些数据存储在专门的大型文件系统上,例如NFS或者HDFS,然后把存储介质的位置存在zookeeper上。

Ephemeral Nodes

zookeeper有一种znode是ephemeral nodes。这些znode只在session存在期间有效。当session结束的时候这些ephemeral nodes被删除。所以ephemeral znodes不能有子节点。

Sequence Nodes -- Unique Naming

当创建一个znode时候,你也可以要求zookeeper在path的结尾单调递增。计数器对每一个znode来说都是唯一的。计数器使用%010d格式化--例如<path>0000000001。注意:计数器使用一个singed int(4bytes)来存储下一个序列值。所以计数器达到2147483647 后会溢出。

zookeeper的每个节点可以有如下三种角色:

1.leader和follower

ZooKeeper需要在所有的服务(可以理解为服务器)中选举出一个Leader,然后让这个Leader来负责管理集群。此时,集群中的其它服务器则成为此Leader的Follower。并且,当Leader故障的时候,需要ZooKeeper能够快速地在Follower中选举出下一个Leader。这就是ZooKeeper的Leader机制,下面我们将简单介绍在ZooKeeper中,Leader选举(Leader Election)是如何实现的。

此操作实现的核心思想是:首先创建一个EPHEMERAL目录节点,例如“/election”。然后。每一个ZooKeeper服务器在此目录下创建一个SEQUENCE|EPHEMERAL类型的节点,例如“/election/n_”。在SEQUENCE标志下,ZooKeeper将自动地为每一个ZooKeeper服务器分配一个比前一个分配的序号要大的序号。此时创建节点的ZooKeeper服务器中拥有最小序号编号的服务器将成为Leader。

在实际的操作中,还需要保障:当Leader服务器发生故障的时候,系统能够快速地选出下一个ZooKeeper服务器作为Leader。一个简单的解决方案是,让所有的follower监视leader所对应的节点。当Leader发生故障时,Leader所对应的临时节点将会自动地被删除,此操作将会触发所有监视Leader的服务器的watch。这样这些服务器将会收到Leader故障的消息,并进而进行下一次的Leader选举操作。但是,这种操作将会导致“从众效应”的发生,尤其当集群中服务器众多并且带宽延迟比较大的时候,此种情况更为明显。

在Zookeeper中,为了避免从众效应的发生,它是这样来实现的:每一个follower对follower集群中对应的比自己节点序号小一号的节点(也就是所有序号比自己小的节点中的序号最大的节点)设置一个watch。只有当follower所设置的watch被触发的时候,它才进行Leader选举操作,一般情况下它将成为集群中的下一个Leader。很明显,此Leader选举操作的速度是很快的。因为,每一次Leader选举几乎只涉及单个follower的操作。

2.Observer

observer的行为在大多数情况下与follower完全一致, 但是他们不参加选举和投票, 而仅仅接受(observing)选举和投票的结果.

时间: 2024-10-13 16:18:08

zookeeper理论的相关文章

分布式选举算法

分布式选举算法-Paxos (2011-03-20 10:12:56) 转载▼ http://blog.sina.com.cn/s/blog_4b6e0fbb0100q9zh.html 标签: 文化 分类: 计算机杂文 (ZZ)分布式选举算法-Paxos 技术日志 2009-12-04 10:42:05 阅读589 评论0   字号:大中小 订阅 在分布式算法领域,有个非常重要的算法叫Paxos, 它的重要性有多高呢,Google的Chubby [1]中提到 all working protoc

2018大数据学习路线从入门到精通

最近很多人问小编现在学习大数据这么多,他们都是如何学习的呢.很多初学者在萌生向大数据方向发展的想法之后,不免产生一些疑问,应该怎样入门?应该学习哪些技术?学习路线又是什么?今天小编特意为大家整理了一份大数据从入门到精通的学习路线.并且附带学习资料和视频.希望能够帮助到大家.大数据学习资料分享群:119599574 第一阶段:Linux理论 (1)Linux基础:(2)Linux-shell编程:(3)高并发:lvs负载均衡:(4)高可用&反向代理 第二阶段:Hadoop理论 (1)hadoop-

zookeeper和Eureka对CAP理论的支持

著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性).A(可用性)和P(分区容错性).由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡.在此Zookeeper保证的是CP, 而Eureka则是AP. Zookeeper保证CP 当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用.也就是说,服务注册功能对可用性的要求要高于一致性.但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失

ZooKeeper应用理论及其应用场景

ZooKeeper Client APIZooKeeper Client Library提供了丰富直观的API供用户程序使用,下面是一些常用的API: ● create(path, data, flags): 创建一个ZNode, path是其路径,data是要存储在该ZNode上的数据,flags常用的有: PERSISTEN, PERSISTENT_SEQUENTAIL, EPHEMERAL, EPHEMERAL_SEQUENTAIL ● delete(path, version): 删除一

Zookeeper笔记1-CAP/BASE理论

CAP理论,指的是在一个分布式系统中,不可能同时满足Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性)这三个基本需求,最多只能满足其中的两项. 1.一致性: 指数据在多个副本之间是否能够保持一致的特性.当执行数据更新操作后,仍然剋保证系统数据处于一致的状态. 2.可用性(高可用): 系统提供的服务必须一直处于可用的状态.对于用户的每一个操作请求总是能够在"有限的时间内"返回结果.这个有限时间是系统设计之初就指定好

Zookeeper简单介绍

转自:ZooKeeper学习第一期---Zookeeper简单介绍 一.分布式协调技术 在给大家介绍ZooKeeper之前先来给大家介绍一种技术--分布式协调技术.那么什么是分布式协调技术?那么我来告诉大家,其实分布式协调技术 主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果.这时,有人可能会说这个简单,写一个调 度算法就轻松解决了.说这句话的人,可能对分布式系统不是很了解,所以才会出现这种误解.如果这些进程全部是跑在一台机上的

《从PAXOS到ZOOKEEPER分布式一致性原理与实践》pdf

下载地址:网盘下载 内容简介  · · · · · · <Paxos到Zookeeper:分布式一致性原理与实践>从分布式一致性的理论出发,向读者简要介绍几种典型的分布式一致性协议,以及解决分布式一致性问题的思路,其中重点讲解了Paxos和ZAB协议.同时,本书深入介绍了分布式一致性问题的工业解决方案--ZooKeeper,并着重向读者展示这一分布式协调框架的使用方法.内部实现及运维技巧,旨在帮助读者全面了解ZooKeeper,并更好地使用和运维ZooKeeper.全书共8章,分为五部分:第一

CAP理论 (转)

CAP理论在互联网界有着广泛的知名度,知识稍微宽泛一点的工程师都会把其作为衡量系统设计的准则.大家都非常清楚地理解了CAP:任何分布式系统在可用性.一致性.分区容错性方面,不能兼得,最多只能得其二,因此,任何分布式系统的设计只是在三者中的不同取舍而已. 事实上,让人吃惊的是,CAP在国外的响力完全不如所想,相反还伴随着诸多的争论.下面我们系统地阐述一下CAP的来龙去脉. 1.CAP的历史 1985年Lynch证明了异步通信中不存在任何一致性的分布式算法(FLP Impossibility)的同时

01.ZooKeeper简介

什么是ZooKeeper Zookeeper是用Java开发的一个分布式协调服务,就是为用户的分布式应用程序提供协调服务.应用程序可以在Zookeeper集群上注册当前的节点数据,当节点数据发生更改时,ZooKeeper还会通知应用程序. ZooKeeper的应用场景 配置文件管理(如:Solor集群的索引配置文件) 服务器状态感知(告诉客户端有哪些服务器可用) 主从协调(服务器内部选举出master节点) 分布式共享锁 统一名称服务 ZooKeeper特性 ZooKeeper是为别的分布式程序