写点什么

Zookeeper 数据存储源码剖析

作者:极客罗杰
  • 2023-12-11
    上海
  • 本文字数:1969 字

    阅读完需:约 6 分钟

Zookeeper数据存储源码剖析

相信使用过 Zookeeper 的同学都觉得 Zookeeper(简称 ZK)是万精油,知道很多地方能用到它,实际上 ZK 主流应用场景有七种分布式协调,数据存储,命名服务,分布式锁,队列,负载均衡,生成分布式 id。本文会着重介绍 ZK 的数据存储源码剖析并介绍 ZK 数据存储应用案例。

一、Zookeeper 介绍

ZooKeeper 是一个分布式的、开源的分布式应用程序协调服务。

Zookeeper 是一个高可用的分布式管理和协调框架,基于 ZAB(Zookeeper Atomic Broadcast)算法即原子消息广播协议的实现。可以在分布式环境中实现应用配置管理、统一命名服务、状态同步服务等功能。

ZooKeeper 包含一个简单的原语集,提供 Java 和 C 的编程接口。

       Zookeeper 中的角色:

1 Leader 领导者

zookeeper 集群主节点,负责响应所有变更请求即写请求。

2 Follower 跟随者

响应读请求,处理 leader 提议,参与 leader 选举。

3 Observer 观察者

  应用场景是在 zookeeper 集群读负载高,可部署 observer,响应读请求,但不参与 leader 选举。

Zookeeper 的设计目标是为了在分布式环境种协调各个进程,它本身也支持集群模式,ZK 集群模式如下图所示:


目前官方最新 ZK 版本是 3.9.0。


二、Zookeeper 数据存储源码剖析

相信大家不会陌生用 Zookeeper 作配置中心,一些优秀的微服务框架是用 Zookeeper 作为配置中心,如:spring cloud zookeeper。但对其原理可能未必了解,实际其还是把 Zookeeper 用作数据存储。下面就来介绍下 Zookeeper 数据存储工作原理,可用简单归结为:ZNode 文件系统+Watcher 监听机制。我们先来了解下 ZK 文件系统。

       要了解 ZK 数据存储原理,先要了解 ZK 内存数据结构。Zookeeper 的数据模型是一种典型树形结构,并且有它的继承性的命名空间,如下图所示:


与标准文件系统不同,每个根节点和子节点都能保存数据。因为 Zookeeper 当初设计目标是用于分布式协调包含状态,配置,位置信息等,所以它通常存储数据量不太大,默认是 1MB 数据。

其中节点称作 ZNode,它可用被唯一标识的路径访问。ZNode 有 4 种类型:

1 短暂(ephemeral):会话结束后,节点不存在即生命周期是会话。

2 持久(persistent):会话结束后,节点存在。

3 持久有序的(persistent_sequential):创建节点时会使用一个单调递增数字,会话结束后,节点存在。

4 临时有序的(ephemeral_sequential):创建节点时会使用一个单调递增数字,会话结束后,节点不存在即生命周期是会话。

       接下来讲一下 Zookeeper 监听机制,ZK 允许客户端向服务端的某一个 Znode 注册 Watcher 监听即订阅事件,当服务端的指定事件触发了这个 Watcher,服务端会向指定客户端发送一个事件通知来实现分布式的通知功能,比如:数据改变、节点新增、子目录节点增加等,然后客户端根据 Watcher 通知状态和事件类型做出业务上的改变,如下原理图所示:

下面本文从 ZK 源代码角度,来剖析存储原理,让读者从更深层次了解 Zookeeper 原理。我们从大家最熟悉的 ZNode 开始,来看看 ZNode 的数据结构,在 Zookeeper 源码中 ZNode 实际是 DataNode:

如上代码块中 data[]数组是用来存放 ZNode 节点数据,acl 是用来控制权限,stat 存放此节点统计信息,而 children 存储此 ZNode 节点孩子路径。

       而包含 ZNode 的 DataTree 抽象代表了 Zookeeper 的树形结构:

如上代码块中 nodes 是用来存储 ZK 的树形结构,是一个 Map 数据接口,key 路径,value 是 DataNode 即 ZNode 节点,另外它是一个 ConcurrentHashMap,故 ZK 支持并发。此外 rootZookeeper 定义了 zookeeper 根路径/,同 Unix/Linux 根路径相同。

       Zookeeper 其他信息如会话,提交日志和 DataTree 一并都是存储在 ZKDatabase 里,源代码如下图所示:


       综上,ZKDatabase 存储 DataTree,DataTree 通过 map 路径映射形式存储 ZNode,这是 Zookeeper 存储原理源代码层面剖析。

三、Zookeeper 数据存储应用案例

一个经典的应用案例是 spring cloud zookeeper,spring cloud 是一个成功的微服务解决方案,ZK 能与 spring cloud 集成构建大型分布式应用。spring cloud zookeeper 实现 ServiceRegistry 接口,具备服务发现,注册能力,并且能与其他 spring cloud 组件像负载均衡 Ribbon,声明式 API Feign,智能网关 Zull 协同工作。

另一个经典的应用案例是 Dubbo,Dubbo 是一个阿里巴巴开源的 RPC 调用方式的微服务解决方案,Dubbo 中的通过配置 Zookeeper 为注册协议,从而能以 ZK 为注册中心,实现微服务命名空间,负载均衡,分布式协调等功能。

       综上,由于 ZK 其可靠性,高性能,适合存储数据量小的特点,非常适合应用于注册中心,所以以上两个主流微服务解决方案注册中心均采用 ZK。另外 ZK 在分布式环境下还有诸多应用场景分布式锁,消息队列等,但它也非银色子弹,从另一个角度其特点也正是它的局限,譬如:节点存储容量限制,集群选主耗时略长等缺点,所以对于 ZK 应用要掌握它原理并结合业务场景才能正确高效地使用,这也是作者撰写本文的初衷之一。

发布于: 刚刚阅读数: 4
用户头像

极客罗杰

关注

还未添加个人签名 2021-04-11 加入

还未添加个人简介

评论

发布
暂无评论
Zookeeper数据存储源码剖析_极客罗杰_InfoQ写作社区