1. 概述

简单来说,ZK是一个基于内存的存储系统(同时数据也会持久化到磁盘),与Redis等内存数据库在这一点上有共同点。但其文件组织与其它存储方式有比较大的差别(更加类似传统的文件系统)。

它的原理可以用以下几点来概括:

以上几点使得它非常适合做一个分布式服务的协调者,这也是它的名称的来源(动物园管理员)。

那什么是分布式服务的协调者?

假设我们启动了多个节点向外提供服务,这些节点向外提供同样的服务;那么会有以下问题需要考虑:

了解微服务的应该就知道,以上问题就是微服务注册中心所要解决的。而这恰好是ZK的一个典型的应用场景,另外还有Spring Cloud所使用的Eureka等。

分布式服务协调者所包含的含义就在于此,它使得开发人员可以专注于核心业务开发,而不需要过多地考虑其分布式特性。

总的来说,ZK有以下几种特性:

2. 存储方式2.1 存储

ZK的存储与文件系统类似,每个节点的名称由一串包含有/分隔符的字符组成,其父级是少了最后一个单词及/地串,最顶层的父级是/。 还有一点与文件系统类似的在于,如果节点有子节点,不能直接被删除。

ZK与标准文件系统不同的地方在于,每个节点都可以存储关联的数据;但每个节点关联的数据大小受限,主要用于存储元数据:如版本信息、状态信息、配置信息、位置信息等,这类元数据通常只有B或者KB级别,存储的文件大小不能超过1M。

存储示例如下所示:

zookeeper搭建模式有哪些(高并发基础Zookeeper原理及应用场景总结)(1)

ZK存储方式

2.2 节点类型

ZK中的节点可以分成以下几类:

2.3 节点操作

ZK的使用主要集中在对其树型结构中的节点操作上,主要包含以下几种操作:

这几个操作看起来很简单,但它们正好是ZK应对各种场景的基石。

3. 集群部署3.1 部署模式

ZK的集群部署模式如下图所示:

zookeeper搭建模式有哪些(高并发基础Zookeeper原理及应用场景总结)(2)

ZK部署模式

服务端一般会部署多个ZK节点,节点主要包含Leader及Follower、Observer三种。

关于集群部署的另外几个要点:

3.2 会话

客户端与某个服务器节点连接后,会创建一个连接会话;后续所有的操作都通过会话进行,直接会话断开。

ZK通过心跳检测的方式保持会话,如果心跳检测失败,那么会认为与服务器节点失去连接,客户端会尝试使用另外一个地址进行连接。因此,客户端连接时一般会指定多个节点地址。

对于那些会话中创建的临时节点,会话断开后会进行删除。

3.3 选举

ZK中节点有以下四种状态:

在集群初始化及Leader挂掉后,Followers节点会进行投票,选举出新的节点;

选举涉及到两个关键概念:

它的选举原则如下:

我们假设有5个节点,其myid分别是1、2、3、4、5,以此来分别说明初始化及Leader失败两种场景的选举方式;

3.3.1 集群初始化时的选举

此时所有节点的zxid都是0;选举过程如下:

3.3.2 Leader挂掉后的选举

如果Leader在运行期间挂掉,需要重新选举;此时会根据myid及zxid来进行选举;

4. 应用场景4.1 数据发布/订阅

典型的应用如配置中心,因为配置数据一般都很小,因此完全可以将配置信息存储在节点对应的数据中;应用启动后从对应节点获取配置数据,同时通过Watch操作进行监听,在配置发生变化时进行响应。

4.2 命名服务(服务注册与发现、负载均衡)

提供服务的应用启动时向Zookeeper指定名称的节点写入自己的URL地址;消费者订阅这个节点获取到服务对应的地址清单,最后进行相关的服务调用,同时针对多个注册服务的情况可以使用一定的负载均衡算法进行负载均衡;

4.3 Master 选举

一般用于比较简单的Master选举情况。

每个节点启动后,往ZK中的特定节点下增加临时节点,在节点异常后临时节点会被删除。

因此ZK的这个特定节点下所有的临时节点都代表创建这个临时节点的服务是在线的;这个时候可以将第一个临时节点对应的服务当成Master。

4.4 分布式锁

利用ZK所有写操作都有顺序的特点,需要加锁的应用往ZK中添加一个特定名称的节点(一个名称代表一个锁),如果添加成功说明加锁成功,添加失败说明加锁失败。

4.5 分布式协调

如假设有n个服务处理同一批任务,需要等待这n个服务都处理完成再调用其它过程;我们可以在每个服务处理完成后,往ZK下特定节点下添加一个节点;同时判断当前子节点数量,如果子节点数量为n说明这个条件已经满足,可以继续处理了。

,