文章目录
- 一、ZooKeeper 基本概念
- 1、ZooKeeper 是什么?
- 2、ZooKeeper 数据模型
- 3、ZooKeeper 主要特点
- 二、ZooKeeper 基本原理
- 1、ZooKeeper 系统架构
- 2、ZooKeeper角色
- 3、ZooKeeper 写数据流程
- 三、ZooKeeper 应用场景总结
- 1、统一命名服务
- 2、配置管理
- 3、集群管理
- 4、分布式通知与协调
- 5、分布式锁
- 6、分布式队列
一、ZooKeeper 基本概念
1、ZooKeeper 是什么?
ZooKeeper 是Hadoop下的一个子项目,它是一个针对大型分布式系统的可靠协调系统;它提供的功能包括:统一命名服务、配置管理、集群管理、分布式通知与协调、分布式锁和分布式队列等; 它的目标就是封装好复杂、易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心,服务生产者将自己提供的服务注册到ZooKeeper中心,服务的消费者在进行服务调用的时候先到ZooKeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据,简单示例图如下:
2、ZooKeeper 数据模型
ZooKeeper中保存数据的结构非常类似于文件系统。都是由节点组成的树形结构。不同的是文件系统是由文件夹和文件来组成的树,而ZooKeeper中是由ZNode来组成的树。
每个ZNode上都会保存自己的数据内容,同时还会保存一系列属性信息,ZNode下还可以挂载零个或多个子ZNode节点,从而组成一个树形结构。
在ZooKeeper中,Node可以分为持久节点和临时节点两类。所谓持久节点是指一旦这个ZNode被创建了,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存在ZooKeeper 上。
而临时节点就不一样了,它的生命周期和客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的所有临时节点都会被移除
与为存储设计的典型文件系统不同,ZooKeeper数据保存在内存中,这意味着ZooKeeper可以实现高吞吐量和低延迟。
ZooKeeper数据模型空间示意图如下:
通过这种树图结构的数据模型,很容易的查找到具体的某一个服务。
3、ZooKeeper 主要特点
①顺序一致性
从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到ZooKeeper中。
②原子性
所有事物请求的处理结果在整个集群中所有机器上的应用情况是一致的,即,要么整个集群中所有机器都成功应用了某一事务,要么都没有应用,一定不会出现集群中部分机器应用了改事务,另外一部分没有应用的情况。
③单一视图
无论客户端连接的是哪个ZooKeeper服务器,其看到的服务端数据模型都是一致的。
④可靠性
一旦服务端成功的应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会一直保留下来,除非有另一个事务又对其进行了改变。
⑤实时性
ZooKeeper并不是一种强一致性,只能保证顺序一致性和最终一致性,只能称为达到了伪实时性。
二、ZooKeeper 基本原理
1、ZooKeeper 系统架构
首先看一下 ZooKeeper 的架构图。
ZooKeeper的架构图中我们需要了解和掌握的主要有:
(1)ZooKeeper分为服务器端(Server) 和客户端(Client),客户端可以连接到整个 ZooKeeper服务的任意服务器上(除非 leaderServes 参数被显式设置, leader 不允许接受客户端连接)。
(2)客户端使用并维护一个 TCP 连接,通过这个连接发送请求、接受响应、获取观察的事件以及发送心跳。如果这个 TCP 连接中断,客户端将自动尝试连接到另外的 ZooKeeper服务器。客户端第一次连接到 ZooKeeper服务时,接受这个连接的 ZooKeeper服务器会为这个客户端建立一个会话。当这个客户端连接到另外的服务器时,这个会话会被新的服务器重新建立。
(3)上图中每一个Server代表一个安装ZooKeeper服务的机器,即是整个提供ZooKeeper服务的集群(或者是由伪集群组成);
(4)组成ZooKeeper服务的服务器必须彼此了解。 它们维护一个内存中的状态图像,以及持久存储中的事务日志和快照, 只要大多数服务器可用,ZooKeeper服务就可用;
(5)ZooKeeper启动时,将从实例中选举一个leader,leader 负责处理数据更新等操作,一个更新操作成功的标志是当且仅当大多数Server在内存中成功修改数据。每个Server在内存中存储了一份数据。
(6)ZooKeeper是可以集群复制的,集群间通过Zab协议(Zookeeper Atomic Broadcast)来保持数据的一致性;
(7)Zab协议包含两个阶段:leader选举阶段和Atomic Broadcast阶段。
a) 集群中将选举出一个leader,其他的机器则称为follower,所有的写操作都被传送给leader,并通过broadcast将所有的更新告诉给follower。
b) 当leader崩溃或者leader失去大多数的follower时,需要重新选举出一个新的leader,让所有的服务器都恢复到一个正确的状态。
c) 当leader被选举出来,且大多数服务器完成了 和leader的状态同步后,leader选举的过程就结束了,就将会进入到Atomic broadcast的过程。
d) Atomic Broadcast同步leader和follower之间的信息,保证leader和follower具有形同的系统状态。
2、ZooKeeper角色
启动 ZooKeeper服务器集群环境后,多个 ZooKeeper服务器在工作前会选举出一个 leader。选举出 leader 前,所有server不区分角色,都需要平等参与投票(obServer 除外,不参与投票);
选主过程完成后,存在以下几种角色:
思考:
1、为什么需要server?
①ZooKeeper 需保证高可用和强一致性;
②为了支持更多的客户端,需要增加更多的Server;
③Follower增多会导致投票阶段延迟增大,影响性能。
2、在ZooKeeper中ObServer 起到什么作用?
①ObServer不参与投票过程,只同 leader的状态 ;
②Observer接受客户端的连接,并将写请求转发给 leader节点 ;
③加入更多ObServer 节点,提高伸缩性,同时还不影响吞吐率。
3、为什么在ZooKeeper中Server 数目一般为奇数?
在ZooKeeper中 leader 选举算法采用了Zab协议。Zab核心思想是当多数 Server 写成功,则任务数据写成功。
①如果有3个Server,则最多允许1个Server 挂掉。
②如果有4个Server,则同样最多允许1个Server挂掉。 既然3个或者4个Server,同样最多允许1个Server挂掉,那么它们的可靠性是一样的,所以选择奇数个ZooKeeper Server即可,这里选择3个Server。
3、ZooKeeper 写数据流程
ZooKeeper写数据的流程图如下所示。
ZooKeeper的写数据流程主要分为以下几步:
a)、比如Client向ZooKeeper的Server1上写数据,发送一个写请求。
b)、如果Server1不是Leader,那么Server1会把接受到的请求进一步转发给Leader,因为每个ZooKeeper的Server里面有一个是Leader。这个Leader 会将写请求广播给各个Server,比如Server1和Server2, 各个Server写成功后就会通知Leader。
c)、当Leader收到大多数Server数据写成功了,那么就说明数据写成功了。如果这里三个节点的话,只要有两个节点数据写成功了,那么就认为数据写成功了。写成功之后,Leader会告诉Server1数据写成功了。
d)、Server1会进一步通知Client数据写成功了,这时就认为整个写操作成功。
三、ZooKeeper 应用场景总结
1、统一命名服务
统一命名服务的命名结构图如下所示:
1、在分布式环境下,经常需要对应用/服务进行统一命名,便于识别不同服务。
a)类似于域名与ip之间对应关系,ip不容易记住,而域名容易记住。
b)通过名称来获取资源或服务的地址,提供者等信息。
2、按照层次结构组织服务/应用名称。
a)可将服务名称以及地址信息写到ZooKeeper上,客户端通过ZooKeeper获取可用服务列表类。
2、配置管理
配置管理结构图如下所示:
1、分布式环境下,配置文件管理和同步是一个常见问题。
a)一个集群中,所有节点的配置信息是一致的,比如 Hadoop 集群。
b)对配置文件修改后,希望能够快速同步到各个节点上。
2、配置管理可交由ZooKeeper实现。
a)可将配置信息写入ZooKeeper上的一个Znode。
b)各个节点监听这个Znode。
c)一旦Znode中的数据被修改,ZooKeeper将通知各个节点。
3、集群管理
集群管理结构图如下所示:
1、分布式环境中,实时掌握每个节点的状态是必要的。
a)可根据节点实时状态做出一些调整。
2、可交由ZooKeeper实现。
a)可将节点信息写入ZooKeeper上的一个Znode。
b)监听这个Znode可获取它的实时状态变化。
3、典型应用
a)HBase中Master状态监控与选举。
4、分布式通知与协调
1、分布式环境中,经常存在一个服务需要知道它所管理的子服务的状态。
a)NameNode需知道各个DataNode的状态。
b)JobTracker需知道各个TaskTracker的状态。
2、心跳检测机制可通过ZooKeeper来实现。
3、信息推送可由ZooKeeper来实现,ZooKeeper相当于一个发布/订阅系统。
5、分布式锁
在分布式场景下,需要同步的进程可能位于不同的节点上,那么就需要使用分布式锁。
• 创建一个锁目录 /lock;
• 当一个客户端需要获取锁时,在 /lock 下创建临时的且有序的子节点;
• 客户端获取 /lock 下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁;否则监听自己的前一个子节点,获得子节点的变更通知后重复此步骤直至获得锁;
• 执行业务代码,完成后,删除对应的子节点。
6、分布式队列
分布式队列分为两种:
1、当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达,这种是同步队列。
a)一个job由多个task组成,只有所有任务完成后,job才运行完成。
b)可为job创建一个/job目录,然后在该目录下,为每个完成的task创建一个临时的Znode,一旦临时节点数目达到task总数,则表明job运行完成。
2、队列按照FIFO方式进行入队和出队操作,例如实现生产者和消费者模型。