zookeeper详解(从入门到实战)

一、zookeeper简介
  zookeeper是一个开源的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。zookeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
  zookeeper是一个典型的分布式数据一致性的解决方案。分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。zookeeper可以保证如下分布式一致性特性。
  1.顺序一致性
  从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到zookeeper中。
  2.原子性
  所有事务请求的结果在集群中所有机器上的应用情况是一致的,也就是说要么整个集群所有集群都成功应用了某一个事务,要么都没有应用,一定不会出现集群中部分机器应用了该事务,而另外一部分没有应用的情况。
  3.单一视图
  无论客户端连接的是哪个zookeeper服务器,其看到的服务端数据模型都是一致的。
  4.可靠性
  一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非有另一个事务又对其进行了变更。
  5.实时性
  通常人们看到实时性的第一反应是,一旦一个事务被成功应用,那么客户端能够立即从服务端上读取到这个事务变更后的最新数据状态。这里需要注意的是,zookeeper仅仅保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
二、为什么需要zookeeper
2.1 举个例子说明

  一个团队里面,需要一个leader,想问关于这个团队的一切事情,首先就会去找这个leader,因为他知道的最多,而且他的回答最靠谱。
  比如产品经理A过来要人,leader发现B最近没有项目安排,于是把B安排给了A的项目;
  过了一会,另一个产品C也过来要人,leader发现刚刚把B安排走了,已经没人,于是就跟C说,人都被你们产品要走了,你们产品自己去协调去。
  如果leader这时候忘了B已经被安排走了,把B也分配给C,那到时两个产品就要打架了。
  这就是leader在团队里的协调作用。
在这里插入图片描述
  上面的例子我们基本能理解leader在团队中的作用,协调者,在分布式系统中,也需要这样的协调者,来回答系统下各个节点的提问。
2.2 分布式协调系统
  比如我们搭建了一个数据库集群,里面有一个Master,多个Slave,Master负责写,Slave只读,我们需要一个系统,来告诉客户端,哪个是Master。
在这里插入图片描述
  有人说,很简单,我们把这个信息写到一个Java服务器的内存就好了,用一个map,key:master,value:master机器对应的ip每次请求这个服务器获取就可以了。那么问题来了,这个是单机,一旦这个机器挂了,就完蛋了,客户端将无法知道到底哪个是Master。
于是我们可以对协调系统进行扩展,扩展结构如下:
在这里插入图片描述
  这下问题来了,如果我们在其中一台机器修改了Master的ip,数据还没同步到其他两台,这时候客户端过来查询,如果查询走的是另外两台还没有同步到的机器,就会拿到旧的数据,往已经不是Master的机器写数据,最终会导致数据写入失败。
  所以我们需要这个存储Master信息的服务器集群,做到当信息还没同步完成时,不对外提供服务,阻塞住查询请求,等待信息同步完成,再给查询请求返回信息。这样一来,请求就会变慢,变慢的时间取决于什么时候这个集群认为数据同步完成了。
  假设这个数据同步时间无限短,比如是1微妙,可以忽略不计,那么其实这个分布式系统,就和我们之前单机的系统一样,既可以保证数据的一致,又让外界感知不到请求阻塞,同时,又不会有SPOF(Single Point of Failure)的风险,即不会因为一台机器的宕机,导致整个系统不可用。这样的系统,就叫分布式协调系统。谁能把这个数据同步的时间压缩的更短,谁的请求响应就更快,谁就更出色,Zookeeper就是其中的佼佼者。它用起来像单机一样,能够提供数据强一致性,但是其实背后是多台机器构成的集群,不会有SPOF。
  其实就是CAP理论中,满足CP,不满足A的那类分布式系统。
  如果把各个节点比作各种小动物,那协调者,就是动物园管理员,这也就是Zookeeper名称的由来了,从名字就可以看出来它的雄心勃勃。
三、为什么zookeeper节点是奇数?
  我们知道,在每台机器数据保持一致的情况下,zookeeper集群可以保证,客户端发起的每次查询操作,集群节点都能返回同样的结果。
  但是对于客户端发起的修改、删除等能改变数据的操作呢?集群中那么多台机器,你修改你的,我修改我的,最后返回集群中哪台机器的数据呢?
  这就是一盘散沙,需要一个领导,于是在zookeeper集群中,leader的作用就体现出来了,只有leader节点才有权利发起修改数据的操作,而follower节点即使接收到了客户端发起的修改操作,也要将其转交给leader来处理,leader接收到修改数据的请求后,会向所有follower广播一条消息,让他们执行某项操作,follower执行完后,便会向 leader回复执行完毕。当 leader收到半数以上的 follower的确认消息,便会判定该操作执行完毕,然后向所有 follower广播该操作已经生效。
  所以zookeeper集群中leader是不可缺少的,但是 leader节点是怎么产生的呢?其实就是由所有follower节点选举产生的,而且leader节点只能有一个。
  这个时候回到我们的话题,为什么zookeeper节点数是奇数,我们下面来一一来说明:
  3.1 容错率
  首先从容错率来说明:(需要保证集群能够有半数进行投票)
  2台服务器,至少2台正常运行才行(2的半数为1,半数以上最少为2),正常运行1台服务器都不允许挂掉,但是相对于 单节点服务器,2台服务器还有两个单点故障,所以直接排除了。
  3台服务器,至少2台正常运行才行(3的半数为1.5,半数以上最少为2),正常运行可以允许1台服务器挂掉
  4台服务器,至少3台正常运行才行(4的半数为2,半数以上最少为3),正常运行可以允许1台服务器挂掉
  5台服务器,至少3台正常运行才行(5的半数为2.5,半数以上最少为3),正常运行可以允许2台服务器挂掉
  3.2 防脑裂
  脑裂集群的脑裂通常是发生在节点之间通信不可达的情况下,集群会分裂成不同的小集群,小集群各自选出自己的leader节点,导致原有的集群出现多个leader节点的情况,这就是脑裂。
  3台服务器,投票选举半数为1.5,一台服务裂开,和另外两台服务器无法通行,这时候2台服务器的集群(2票大于半数1.5票),所以可以选举出leader,而 1 台服务器的集群无法选举。
  4台服务器,投票选举半数为2,可以分成 1,3两个集群或者2,2两个集群,对于 1,3集群,3集群可以选举;对于2,2集群,则不能选择,造成没有Master节点。
  5台服务器,投票选举半数为2.5,可以分成1,4两个集群,或者2,3两集群,这两个集群分别都只能选举一个集群,满足zookeeper集群搭建数目。
  以上分析,我们从容错率以及防止脑裂两方面说明了3台服务器是搭建集群的最少数目,4台发生脑裂时会造成没有leader节点的错误。
四、zookeeper工作原理
4.1 zookeeper的角色

在这里插入图片描述
在这里插入图片描述
4.2 zookeeper的读写机制
  1)Zookeeper是一个由多个server组成的集群
  2)一个leader,多个follower
  3)每个server保存一份数据副本
  4)全局数据一致
  5)分布式读写
  6)更新请求转发,由leader实施
4.3 zookeeper的保证
  1)更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行
  2)数据更新原子性,一次数据更新要么成功,要么失败
  3)全局唯一数据视图,client无论连接到哪个server,数据视图都是一致的
  4)实时性,在一定事件范围内,client能读到最新数据
4.4 zookeeper节点数据操作流程
在这里插入图片描述
注:
  1)在client向follwer发出一个写的请求
  2)follwer把请求发送给leader
  3)leader接收到以后开始发起投票并通知follwer进行投票
  4)follwer把投票结果发送给leader
  5)leader将结果汇总后如果需要写入,则开始写入同时把写入操作通知给follwer,然后commit;
  6)follwer把请求结果返回给client
follower主要有四个功能:
  1)向leader发送请求(ping消息、request消息、ack消息、revalidate消息);
  2)接收leader消息并进行处理;
  3)接收client的请求,如果为写请求,发送给leader进行投票;
  4)返回client结果。
follower的消息循环处理如下几种来自leader的消息:
  1)ping消息:心跳消息;
  2)proposal消息:leader发起的提案,要求follower投票;
  3)commit消息:服务器端最新一次提案的信息;
  4)uptodate消息:表明同步完成;
  5)revalidate消息:根据leader的revalidate结果,关闭待revalidate的session还是允许其接受消息;
  6)sync消息:返回sync结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
4.5 zookeeper的zxid
  znode节点的状态信息中包含zxid, 那么什么是zxid呢?
  zookeeper状态的每一次改变, 都对应着一个递增的transaction id, 该id称为zxid. 由于zxid的递增性质, 如果zxid1小于zxid2, 那么zxid1肯定先于zxid2发生.
  创建任意节点, 或者更新任意节点的数据, 或者删除任意节点, 都会导致zookeeper状态发生改变, 从而导致zxid的值增加.
4.6 zookeeper工作原理
  1)zookeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式和广播模式。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数follwer的完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和follwer具有相同的系统状态
  2)一旦leader已经和多数的follower进行了状态同步后,他就可以开始广播消息了,即进入广播状态。这时候当一个server加入zookeeper服务中,它会在恢复模式下启动,发现leader,并和leader进行状态同步。待到同步结束,它也参与消息广播zookeeper服务一直维持在broadcast状态,直到leader崩溃了或者leader失去了大部分的followers支持。
  3)广播模式需要保证proposal被按顺序处理,因此zk采用了递增的事务id号(zxid)来保证。所有的提议(proposal)都在被提出的时候加上了zxid。
实现中zxid是一个64为的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch。低32位是个递增计数。
  4)当leader崩溃或者leader失去大多数的follower,这时候zookeeper进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的server都恢复到一个正确的状态。 
  5)每个server启动以后都询问其它的server它要投票给谁。
  6)对于其他server的询问,server每次根据自己的状态都回复自己推荐的leader的id和上一次处理事务的zxid(系统启动时每个server都会推荐自己)
  7)收到所有Server回复以后,就计算出zxid最大的哪个server,并将这个server相关信息设置成下一次要投票的server。
  8)计算这过程中获得票数最多的的sever为获胜者,如果获胜者的票数超过半数,则改server被选为leader。否则,继续这个过程,直到leader被选举出来  
  9)leader就会开始等待server连接
  10)follower连接leader,将最大的zxid发送给leader
  11)leader根据follower的zxid确定同步点
  12)完成同步后通知follower 已经成为uptodate状态
  13)follower收到uptodate消息后,又可以重新接受client的请求进行服务了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值