Zookeeper机制和应用场景

Zookeeper简介

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

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

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

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

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

Zookeeper基本概念

zk角色

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

zk service网络结构

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

工作流程
Leader工作流程 

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

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

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

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机制和应用场景_第4张图片
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机制和应用场景_第5张图片

 

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机制和应用场景_第6张图片

同步流程

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

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

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

常规疑问

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节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。

你可能感兴趣的:(工作流程,应用场景,选举机制,Zookeeper,大数据)