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

1. 概述

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

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

  • 维护有一个树型结构,类似于文件系统的组织形式,以名称 /的方式来组织每个节点路径;
  • 与文件系统不一样的地方在于,每个节点能够存储数据;
  • 提供了对树形结构的几个基本的读写操作,如添加节点、删除节点、获取节点数据、设置节点数据等;
  • 对这个树型结构的所有写操作都是原子性的,并且会保持全局有序;
  • 集群内数据保持一致,一个写操作需要同步到各个从节点成功后才返回写操作客户端,因此写得成本较高,这从一定程度上牺牲了可用性;
  • 客户端可以通过Watch操作来监听节点变化,节点变化后客户端会收到相关消息;

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

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

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

  • 如何对外提供地址?这个一般通过网关或者负载均衡来提供;
  • 当某个节点出异常时如何及时通知网关?
  • 扩容时新增节点如何及时通知网关?
  • 更进一步,如果我们的节点包含有一个优先级,或者说有主次之分,如何处理?
  • 如果集群内部服务调用不通过网关,如何得到调用的服务ip及端口?并且保证在某个节点挂掉时能及时收到通知?

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

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

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

  • 顺序性:所有操作都按全局一致的顺序排序,在所有节点上这个顺序都是一样的;
  • 更新原子性;
  • 一致性:不管客户端连接到的是哪个节点,它看到的数据都是一致的;
  • 可靠性:更新操作会被持久化,而且是在内存数据更新前被持久化;
  • 及时性:保证客户端看到的视图都是最新的(可能会有很短时间的延迟)
2. 存储方式2.1 存储

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

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

存储示例如下所示:

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

ZK存储方式

2.2 节点类型

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

  • 持久节点:默认的节点类型,即使客户端会话断开,节点也会存在,直到主动删除;
  • 临时节点:会话断开时即会被自动删除的节点,不能有子节点;
  • 顺序节点:顺序节点可以是持久或者临时的,创建顺序节点时,会自动在节点名称后包含一个长度为10的顺序号,如我们在根节点创建顺序节点test,并且在当前路径下没有其它的顺序节点,其路径 将会是/test0000000001,下一个的顺序号将会是0000000002。
  • TTL节点:可为节点设置TTL时间; 如果在指定时间内节点未被修改,并且其不包含有子节点,那么它将被系统打上标记并在将来某个时间删除。
2.3 节点操作

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

  • create:创建节点;
  • delete:删除节点;
  • exists:判断节点是否存在;
  • get data:获取节点关联的数据;
  • set data:设置节点关联的数据;
  • get children:获取节点的子节点列表;
  • watch: 监听节点;

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

3. 集群部署3.1 部署模式

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

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

ZK部署模式

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

  • Leader:接收更新操作的节点,同时会将更新操作推送给其它的节点;ZK只会在Leader这个节点接收更新操作,主要是为了保证操作的原子性及数据的一致性。
  • Follower:接收Leader数据、同时在Leader失败后参与Leader选举的节点;
  • Observer:只同步数据,不参与选举的节点;

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

  • 每个节点内存中都保存有一份树型数据;同时事务日志及快照等数据会进行持久化存储。正因为其数据是存储在每个节点内存中的,其效率非常高。
  • 集群中的节点彼此能够相互感知,只要集群中多数节点正常,ZK就能正常的对外服务。
  • 客户端可以从服务器端拿到所有节点的列表。
  • 客户端连接到其中某一个服务端。如果与服务端的连接断开,它会自动连接到其它的服务端。
  • 客户端的操作都是对它所连接的服务端的操作,不涉及其它节点;
3.2 会话

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

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

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

3.3 选举

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

  • LOOKING:节点选举中;
  • LEADING: Leader节点;
  • FOLLOWING: Follower节点;
  • OBSERVER: Observer节点;

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

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

  • myid: 服务器id,用户配置;
  • zxid: 当前节点的事务id,值越大说明数据越新;

它的选举原则如下:

  • 只有超过半数的服务器启动,集群才能正常工作;
  • 集群正常工作前,myid小的给myid在大的节点投票;直到选出Leader;
  • 先出Leader后,服务器状态由LOOKING向其它LEADING、FOLLOWING状态变更;

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

3.3.1 集群初始化时的选举

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

  • 节点1加入,给自己投票,票数为1;
  • 节点2加入,给自己投票,消息同时发往节点1;然后节点1发现节点2的myid比自己的大,就改投节点2,节点2得票2,节点1为0; 但过半节点数为3,因此继续选举;
  • 节点3加入,给自己投票;同理,节点1、2也改投节点3,节点3票数为3,超过半数,因此节点3被当选成Leader;其它节点变成Follower;
  • 节点4、5加入,Leader已为3,不再选举,直接是Follower,状态为FOLLOWING;
3.3.2 Leader挂掉后的选举

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

  • 节点状态变更,全部变成LOOKING;
  • 首次投票:首先每个节点都投自己一票,将自己的myid及zxid发往集群中各节点;
  • 投票变更:每个节点根据收到的其它节点信息,取最大zxid的那个节点,将自己的票投给它,将结果再次发往各节点;
  • 投票统计:每节点收到新的投票信息,进行票数的比较,选择最大票数的那个节点当成Leader;其它当成Follower,选举结束;
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说明这个条件已经满足,可以继续处理了。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页