hadoop-05

  1. 1. Zookeeper分布式协调服务
    1. 1.1. 初识Zookeeper
      1. 1.1.1. Zookeeper的简介
      2. 1.1.2. Zookeeper的特性
      3. 1.1.3. Zookeeper集群角色
    2. 1.2. 数据模型
      1. 1.2.1. 数据存储结构
      2. 1.2.2. Znode的类型
      3. 1.2.3. Znode的属性
    3. 1.3. Zookeeper的Watcher机制
      1. 1.3.1. Watch机制的简介
      2. 1.3.2. Watch机制的特点
      3. 1.3.3. Watch机制的通知状态和事件类型
    4. 1.4. Zookeeper的选举机制
      1. 1.4.1. 选举机制的简介
      2. 1.4.2. 选举机制的类型
        1. 1.4.2.1. 全新集群选举
        2. 1.4.2.2. 非全新集群选举
    5. 1.5. Zookeeper分布式集群部署
    6. 1.6. Zookeeper的Shell操作
      1. 1.6.1. Zookeeper Shell介绍
    7. 1.7. Zookeeper的Java API操作
      1. 1.7.1. Zookeeper Java API介绍
    8. 1.8. Zookeeper典型应用场景
      1. 1.8.1. 数据发布与订阅
      2. 1.8.2. 统一命名服务
      3. 1.8.3. 分布式锁

Zookeeper分布式协调服务

Apache Zookeeper旨在减轻构建健壮的分布式系统的服务。Zookeeper是基于分布式计算的核心概念而设计的,主要目的是给开发人员提供一套容易理解和开发的接口,从而简化分布式系统构建的服务。

初识Zookeeper

Zookeeper的简介

Zookeeper是一个分布式协调服务的开源框架,它是由Google的Chubby开源实现。Zookeeper主要用来解决分布式集群中应用系统的一致性问题和单点故障问题,例如如何避免同时操作同一数据造成脏读的一致性问题等。

Zookeeper的特性

Zookeeper具有全局数据一致性、可靠性、顺序性、原子性以及实时性,可以说Zookeeper的其他特性都是为满足Zookeeper全局数据一致性这一特性。

Zookeeper集群角色

Zookeeper集群是一个主从集群,它一般是由一个Leader(领导者)和多个Follower(跟随者)组成。此外,针对访问量比较大的Zookeeper集群,还可新增Observer(观察者)。Zookeeper集群中的三种角色各司其职,共同完成分布式协调服务。

  • Leader
    Leader是Zookeeper集群工作的核心,也是事务性请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性,同时负责进行投票的发起和决议,以及更新系统状态。
  • Follower
    Follower负责处理客户端的非事务(读操作)请求,如果接收到客户端发来的事务性请求,则会转发给Leader,让Leader进行处理,同时还负责在Leader选举过程中参与投票。
  • Observer
    Observer负责观察Zookeeper集群的最新状态的变化,并且将这些状态进行同步。对于非事务性请求可进行独立处理;对于事务性请求,则会转发给Leader服务器进行处理。它不参与任何形式的投票,只提供非事务性的服务。

数据模型

数据存储结构

Zookeeper是由节点组成的树,树中的每个节点被称为—Znode。每个节点都可以拥有子节点。每一个Znode默认能够存储1MB的数据,每个Znode都可以通过其路径唯一标识,如图中第三层的第一个Znode,,它的路径是/app1/p_1。Zookeeper数据模型中每个Znode都是由三部分组成,分别是stat、data、children。

Znode的类型

Znode的类型在创建时被指定,一旦创建就无法改变。
Znode有两种类型,分别是临时节点和永久节点。

  • 临时节点
    该生命周期依赖于创建它们的会话,一旦会话结束,临时节点将会被自动删除,也可以手动删除。虽然每个临时的Znode都会绑定一个客户端,但它们对所有的客户端还是可见的。需要注意的是临时节点不允许拥有子节点。
  • 永久节点
    该生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,它们才能被删除。

Znode的属性

Zookeeper中的每个Znode都包含了一系列的属性,具体属性如下所示。

属性名称 相关说明
dataVersion 数据版本号
aclVersion ACL版本号
ephemeralOwner 如果此节点为临时节点,那么该值代表这个节点拥有者的会话ID;否则值为0
dataLength 节点数据域长度
numChildren 节点拥有的子节点个数
dataVersion 数据版本号
aclVersion ACL版本号
ephemeralOwner 如果此节点为临时节点,那么该值代表这个节点拥有者的会话ID;否则值为0
dataLength 节点数据域长度
numChildren 节点拥有的子节点个数

Zookeeper的Watcher机制

Watch机制的简介

在ZooKeeper中,引入了Watch机制来实现这种分布式的通知功能。ZooKeeper允许客户端向服务端注册一个Watch监听,当服务端的一些事件触发了这个Watch,那么就会向指定客户端发送一个事件通知,来实现分布式的通知功能。

Watch机制的特点

  • 一次性触发
  • 事件封装
  • 异步发送
  • 先注册再触发

Watch机制的通知状态和事件类型

同一个事件类型在不同的连接状态中代表的含义有所不同。
常见的连接状态和事件类型如下所示。

连接状态 状态含义 事件类型 事件含义
Disconnected 连接失败 NodeCreated 节点被创建
SyncConnected 连接成功 NodeDataChanged 节点数据变更
AuthFailed 认证失败 NodeChildrentChanged 子节点数据变更
Expired 会话过期 NodeDeleted 节点被删除

Zookeeper的选举机制

选举机制的简介

Zookeeper为了保证各节点的协同工作,在工作时需要一个Leader角色,而Zookeeper默认采用FastLeaderElection算法,且投票数大于半数则胜出的机制。

  • 服务器ID
    设置集群myid参数时,参数分别为服务器1、服务器2、服务器3,编号越大FastLeaderElection算法中权重越大。
  • 选举ID
    选举过程中,Zookeeper服务器有四种状态,分别为竞选状态、随从状态、观察状态、领导者状态。
  • 逻辑时钟
    逻辑时钟被称为投票次数,同一轮投票过程中逻辑时钟值相同,逻辑时钟起始值为0,每投一次票,数据增加。与接收到其它服务器返回的投票信息中数值比较,根据不同值做出不同判断。
  • 数据ID
    是服务器中存放的最新数据版本号,该值越大则说明数据越新,在选举过程中数据越新权重越大。

选举机制的类型

Zookeeper选举机制有两种类型,分别为全新集群选举和非全新集群选举。全新集群选举是新搭建起来的,没有数据ID和逻辑时钟的数据影响集群的选举;非全新集群选举时是优中选优,保证Leader是Zookeeper集群中数据最完整、最可靠的一台服务器。

全新集群选举

  1. 服务器1启动,先给自己投票;其次,发投票信息,由于其它机器还没有启动所以它无法接收到投票的反馈信息,因此服务器1的状态一直属于竞选状态。
  2. 服务器2启动,先给自己投票;其次,在集群中启动Zookeeper服务的机器发起投票对比,它会与服务器1交换结果,由于服务器2编号大,服务器2胜出,服务器1会将票投给服务器2,此时服务器2的投票数并没有大于集群半数,两个服务器状态依旧是竞选状态。
  3. 服务器3启动,先给自己投票;其次,与之前启动的服务器1、2交换信息,服务器3的编号最大,服务器3胜出,服务器1、2会将票投给服务器3,此时投票数正好大于半数,所以服务器3成为领导者状态,服务器1、2成为追随者状态。
  4. 服务器4启动,先给自己投票;其次,与之前启动的服务器1、2、3交换信息,尽管服务器4的编号大,但是服务器3已经胜,所以服务器4只能成为追随者状态。
  5. 服务器5启动,同服务器4一样,均成为追随者状态。

非全新集群选举

  1. 统计逻辑时钟是否相同,逻辑时钟小,则说明途中可能存在宕机问题,因此数据不完整,那么该选举结果被忽略,重新投票选举。
  2. 统一逻辑时钟后,对比数据ID值,数据ID反应数据的新旧程度,因此数据ID大的胜出。
  3. 如果逻辑时钟和数据ID都相同的情况下,那么比较服务器ID(编号),值大则胜出。

Zookeeper分布式集群部署

Zookeeper分布式集群部署指的是ZooKeeper分布式模式安装。Zookeeper集群搭建通常是由2n+1台服务器组成,这是为了保证 Leader 选举(基于Paxos算法的实现)能够通过半数以上台服务器选举支持,因此,ZooKeeper集群的数量一般为奇数台。

Zookeeper的Shell操作

Zookeeper Shell介绍

Zookeeper命令行工具类似于Linux的Shell环境,能够简单地实现对Zookeeper进行访问、数据创建、数据修改等的一系列操作。

常用命令 命令描述
ls / 使用ls命令来查看Zookeeper中所包含的内容
ls2 / 查看当前节点数据并能看到更新次数等数据
create /zk “test” 在当前目录创建一个新的Znode节点“zk”以及与它关联的字符串
get /zk 获取zk所包含的信息
set /zk “zkbak” 对zk所关联的字符串进行设置
delete /zk 将节点Znode删除
rmr 将节点Znode递归删除
help 帮助命令

Zookeeper的Java API操作

Zookeeper Java API介绍

Zookeeper API包含五个包:

  • org.apache.zookeeper
  • org.apache.zookeeper.data
  • org.apache.zookeeper.server
  • org.apache.zookeeper.server.quorum
  • org.apache.zookeeper.server.upgrade

org.apache.zookeeper包含Zookeeper类,这也是编程时最常用的类文件,Zookeeper类提供的常用Java API方法。

方法名称 方法描述
create 创建节点
delete 删除节点
exists 判断节点是否存在
get/setData 获取/修改节点数据
getChildren 获取指定节点下的所有子节点列表

Zookeeper典型应用场景

数据发布与订阅

数据发布与订阅模型,即所谓的全局配置中心,顾名思义就是发布者将需要全局统一管理的数据发布到Zookeeper节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。

  • 应用中用到的一些配置信息放到Zookeeper上进行集中管理。
  • 分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在Zookeeper的一些指定节点,供各个客户端订阅使用。
  • 分布式日志收集系统中,这个系统的核心工作是收集分布在不同机器的日志。
  • 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息的发问。

统一命名服务

命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源服务的地址,提供者等信息。

分布式锁

  • 分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性。
  • 锁服务可以分为两类,一个是保持独占,另一个是控制时序。
  • 所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个客户端可以成功获得这把锁,从而执行相应操作;控制时序则是所有试图来获取锁的客户端,最终都会被执行,存在全局时序,客户端在临时非序列化节点下创建临时序列化节点,根据序列号大小进行时序性操作。

当所有客户端都去创建临时非序列化节点,那么最终成功创建的客户端也拥有了这把锁,拥有了访问该数据的权限,当操作完毕后,断开与Zookeeper连接,那该临时节点就会被删除,如果其他客户端需要操作这个文件,客户端只需监听这个目录是否存在即可。