欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Zookeeper机制和应用场景

程序员文章站 2022-07-14 23:50:11
...

Zookeeper简介

Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等等。

  • Zookeeper就是用来做第三方的,起作用只有俩个。
    1、管理(存储、读取)用户提交的数据。
    2、并为数据提供监听功能。(监听服务器是有正常)

  • Zookeeper本来就是一个分布式集群(只要有半数以上的节点存活,zookeeper就能正常*服务)

  • Zookeeper服务的场景涵盖:主从协调、服务器节点的动态上下线、同意配置管理、分布式共享锁、同意服务名称。

  • Keepalived也是一种保护数据的软件,通过建立虚拟的ip地址来访问别人,而不是用作服务器来让客户端进行访问。所以在保护服务器数据时这个没用。

Zookeeper基本概念

zk角色

Zookeeper中的角色主要有以下三类,如下表所示:
Zookeeper机制和应用场景

zk service网络结构

Zookeeper的工作集群可以简单分成两类,一个是Leader,唯一一个,其余的都是follower,这样才能确定Leader是通过内部选举确定的。
Zookeeper机制和应用场景

工作流程
Leader工作流程 

—恢复数据;
—维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
—Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。

PING 消息是指Learner的心跳信息;
REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;
ACK消息是Follower的对提议 的回复,超过半数的Follower通过,则commit该提议;
REVALIDATE消息是用来延长SESSION有效时间。

Leader的工作流程简图具体如下所示:
Zookeeper机制和应用场景

Follower工作流程 

Follower主要有四个功能:
— 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
— 接收Leader消息并进行处理;
— 接收Client的请求,如果为写请求,发送给Leader进行投票;
— 返回Client结果。

  • Follower的消息循环处理如下几种来自Leader的消息:
    — PING消息: 心跳消息;
    — PROPOSAL消息:Leader发起的提案,要求Follower投票;
    — COMMIT消息:服务器端最新一次提案的信息;
    — UPTODATE消息:表明同步完成;
    — REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
    — SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
    Follower的工作流程简图具体如下所示:
    · Zookeeper机制和应用场景
zk读写数据

1、Zookeeper是一个由多个server组成的集群
2、 一个leader,多个follower
3、每个server保存一份数据副本
4、 全局数据一致
5、 分布式读写
6、 更新请求转发,由leader实施
ps:其实写数据的时候不是要保证所有zk节点都写完才响应,而是保证一半以上的节点写完了就把这次变更更新到内存,并且当做最新命名空间的应用。所以在读数据的时候可能会读到不是最新的zk节点,这时候只能通过sync()解决。这里先不考虑了,假设整个zk service都是同步meta信息的,后面的文章再讨论。

Zookeeper的选举机制

一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。

系统默认的选举算法为fast paxos。

 

Zookeeper leader 的fast paxos选举 
 
  • 半数通过
    – 3台机器 挂一台 2>3/2
    – 4台机器 挂2台 2!>4/2
  
  • A提案说,我要选自己,B你同意吗?C你同意吗?B说,我同意选A;C说,我同意选A。(注意,这里超过半数了,其实在现实世界选举已经成功了。
   但是计算机世界是很严格,另外要理解算法,要继续模拟下去。)
  • 接着B提案说,我要选自己,A你同意吗;A说,我已经超半数同意当选,你的提案无效;C说,A已经超半数同意当选,B提案无效。
  • 接着C提案说,我要选自己,A你同意吗;A说,我已经超半数同意当选,你的提案无效;B说,A已经超半数同意当选,C的提案无效。
  • 选举已经产生了Leader,后面的都是follower,只能服从Leader的命令。
  
而且这里还有个小细节,就是其实谁先启动谁当头。

下面是fast paxos选举流程图:
  Zookeeper机制和应用场景

 

Zookeeper leader 的basic paxos选举

我们先弄懂什么的zxid然后再看basic paxos算法的逻辑:
zxid

  • ZooKeeper状态的每一次改变, 都对应着一个递增的Transaction id, 该id称为zxid. 由于zxid的递增性质, 如果zxid1小于zxid2, 那么zxid1肯定先于zxid2发生.
  
  创建任意节点, 或者更新任意节点的数据, 或者删除任意节点, 都会导致Zookeeper状态发生改变, 从而导致zxid的值增加.

basic paxos选举流程
  • 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  • 选举线程首先向所有Server发起一次询问(包括自己);
  • 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  • 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  • 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。

通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于 n+1.每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信 息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。
  Zookeeper机制和应用场景

同步流程

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

  • leader等待server连接;
  • Follower连接leader,将最大的zxid发送给leader;
  • Leader根据follower的zxid确定同步点;
  • 完成同步后通知follower 已经成为uptodate状态;
  • Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

同步的具体流程图如下所示:
Zookeeper机制和应用场景

常规疑问

1、 为什么zookeeper集群的数目,一般为奇数个?
  •Leader选举算法采用了Paxos协议;
  •Paxos核心思想:当多数Server写成功,则任务数据写成功如果有3个Server,则两个写成功即可;如果有4或5个Server,则三个写成功即可。
  •Server数目一般为奇数(3、5、7)如果有3个Server,则最多允许1个Server挂掉;如果有4个Server,则同样最多允许1个Server挂掉由此,
   我们看出3台服务器和4台服务器的的容灾能力是一样的,所以为了节省服务器资源,一般我们采用奇数个数,作为服务器部署个数。
2、Zookeeper 的数据模型 
  » 层次化的目录结构,命名符合常规文件系统规范
  » 每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识
  » 节点Znode可以包含数据和子节点,但是EPHEMERAL类型的节点不能有子节点
  » Znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本
  » 客户端应用可以在节点上设置监视器
  » 节点不支持部分读写,而是一次性完整读写
3、Zookeeper 的节点
  » Znode有两种类型,短暂的(ephemeral)和持久的(persistent)
  » Znode的类型在创建时确定并且之后不能再修改
  » 短暂znode的客户端会话结束时,zookeeper会将该短暂znode删除,短暂znode不可以有子节点
  » 持久znode不依赖于客户端会话,只有当客户端明确要删除该持久znode时才会被删除
  » Znode有四种形式的目录节点
  » PERSISTENT(持久的)
  » EPHEMERAL(暂时的)
  » PERSISTENT_SEQUENTIAL(持久化顺序编号目录节点)
  » EPHEMERAL_SEQUENTIAL(暂时化顺序编号目录节点)
应用篇
分布式系统的运行是很复杂的,因为涉及到了网络通信还有节点失效等不可控的情况。下面介绍在最传统的master-workers模型,主要可以会遇到什么问题,传统方法是怎么解决以及怎么用zookeeper解决。
Master节点管理
集群当中最重要的是Master,所以一般都会设置一台Master的Backup。
Backup会定期向Master获取Meta信息并且检测Master的存活性,一旦Master挂了,Backup立马启动,接替Master的工作自己成为Master,分布式的情况多种多样,因为涉及到了网络通信的抖动,针对下面的情况:
1. Backup检测Master存活性传统的就是定期发包,一旦一定时间段内没有收到响应就判定Master Down了,于是Backup就启动,如果Master其实是没有down,Backup收不到响应或者收到响应延迟的原因是因为网络阻塞的问题呢?Backup也启动了,这时候集群里就有了两个Master,很有可能部分workers汇报给Master,另一部分workers汇报给后来启动的Backup,这下子服务就全乱了。
· Backup是定期同步Master中的meta信息,所以总是滞后的,一旦Master挂了,Backup的信息必然是老的,很有可能会影响集群运行状态。
解决问题:
Master节点高可用,并且保证唯一。
Meta信息的及时同步。
* Zookeeper Master选举 *
  Zookeeper会分配给注册到它上面的客户端一个编号,并且zk自己会保证这个编号的唯一性和递增性,N多机器中只需选出编号最小的Client作为Master就行,并且保证这些机器的都维护一个一样的meta信息视图,一旦Master挂了,那么这N机器中编号最小的胜任Master,Meta信息是一致的。
集群worker管理
集群中的worker挂了是很可能的,一旦worker A挂了,如果存在其余的workers互相之间需要通信,那么workers必须尽快更新自己的hosts列表,把挂了的worker剔除,从而不在和它通信,而Master要做的是把挂了worker上的作业调度到其他的worker上。同样的,这台worker重新恢复正常了,要通知其他的workers更新hosts列表。传统的作法都是有专门的监控系统,通过不断去发心跳包(比如ping)来发现worker是否alive,缺陷就是及时性问题,不能应用于在线率要求较高的场景
解决问题:
集群worker监控。
* Zookeeper监控集群 *
  利用zookeeper建立znode的强一致性,可以用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。
分布式锁
在一台机器上要多个进程或者多个线程操作同一资源比较简单,因为可以有大量的状态信息或者日志信息提供保证,比如两个A和B进程同时写一个文件,加锁就可以实现。但是分布式系统怎么办?需要一个三方的分配锁的机制,几百台worker都对同一个网络中的文件写操作,怎么协同?还有怎么保证高效的运行?
解决问题:
高效分布式的分布式锁
Zookeeper分布式锁
  分布式锁主要得益于ZooKeeper为我们保证了数据的强一致性,zookeeper的znode节点创建的唯一性和递增性能保证所有来抢锁的worker的原子性。
配置文件管理
集群中配置文件的更新和同步是很频繁的,传统的配置文件分发都是需要把配置文件数据分发到每台worker上,然后进行worker的reload,这种方式是最笨的方式,结构很难维护,因为如果集群当中有可能很多种应用的配置文件要同步,而且效率很低,集群规模一大负载很高。还有一种就是每次更新把配置文件单独保存到一个数据库里面,然后worker端定期pull数据,这种方式就是数据及时性得不到同步。
解决问题:
统一配置文件分发并且及时让worker生效
Zookeeper发布与订阅模型
  发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。