介绍

ZooKeeper 是一个开源的分布式协调框架,是Apache Hadoop 的一个子项目,主要

用来解决分布式集群中应用系统的一致性问题。Zookeeper 的设计目标是将那些复杂且容

易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的

接口提供给用户使用。

ZooKeeper本质上是一个分布式的小文件存储系统(Zookeeper=文件系统+监听机制)。

官方:https://zookeeper.apache.org/

ZooKeeper数据结构

ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个节

点称做一个 ZNode。

ZooKeeper的数据模型是层次模型,层次模型常见于文件系统。层次模型和key-value模型

是两种主流的数据模型。ZooKeeper使用文件系统模型主要基于以下两点考虑:

1. 文件系统的树形结构便于表达数据之间的层次关系

2. 文件系统的树形结构便于为不同的应用分配独立的命名空间( namespace )

ZooKeeper的层次模型称作Data Tree,Data Tree的每个节点叫作Znode。不同于文件系

统,每个节点都可以保存数据,每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode

都可以通过其路径唯一标识,每个节点都有一个版本(version),版本从0开始计数。

可以创建如下四种节点:

  1. 持久节点:节点创建后会一直存在zookeeper服务器上,直到主动删除

  2. 持久顺序节点:每个节点都会为它的一级子节点维护一个顺序

  3. 临时节点:临时节点的生命周期和客户端的会话保持一致。当客户端会话失效,该节点自动清理

  4. 临时顺序节点:在临时节点上多了一个顺序的特性

Zookeeper客户端命令

# 连接远程的zookeeper server
bin/zkCli.sh ‐server ip:port

#创建持久节点
create /servers xxx
#创建临时节点
create ‐e /servers/host xxx
#创建临时有序节点
create ‐e ‐s /servers/host xxx
#创建容器节点
create ‐c /container xxx
# 创建ttl节点,TTL节点: 带过期时间节点,默认禁用,需要在zoo.cfg中添加extendedTypesEnabled=true 开启。 注意:ttl不能用于临时节点
create ‐t 10 /ttl

命令基本语法

功能描述

help

显示所有操作命令

ls [-s] [-w] [-R] path

使用 ls 命令来查看当前 znode 的子节点 [可监听]

-w: 监听子节点变化

-s: 节点状态信息(时间戳、版本号、数据大小等)

-R: 表示递归的获取

create [-s] [-e] [-c] [-t ttl] path [data] [acl]

创建节点,默认持久节点

-s : 创建有序节点。

-e : 创建临时节点。

-c : 创建一个容器节点。t ttl] : 创建一个TTL节点, -t 时间(单位毫秒)。

data:节点的数据,可选,如果不使用时,节点数据

就为null。

acl:访问控制

get [-s] [-w] path

获取节点数据信息

-s: 节点状态信息(时间戳、版本号、数据大小等)

-w: 监听节点变化

set [-s] [-v version] path data

设置节点数据

-s:表示节点为顺序节点

-v: 指定版本号

getAcl [-s] path

获取节点的访问控制信息

-s: 节点状态信息(时间戳、版本号、数据大小等)

setAcl [-s] [-v version] [-R] path acl

设置节点的访问控制列表

-s:节点状态信息(时间戳、版本号、数据大小等)

-v:指定版本号

-R:递归的设置

stat [-w] path

查看节点状态信息

delete [-v version] path

删除某一节点,只能删除无子节点的节点。

-v: 表示节点版本号

deleteall path

递归的删除某一节点及其子节点

setquota -n|-b val path

对节点增加限制

n:表示子节点的最大个数

b:数据值的最大长度,-1表示无限制

讲解如何安装与配置 Zookeeper,涵盖本地、docker、kubernetes 等环境。以下仅为快速示例安装指南,如想搭建生产可用集群请参考 Zookeeper 官方文档。

节点状态说明

stat /services/xpos-cif-srv

属性说明:

  • cZxid :Znode创建的事务id。

  • ctime:节点创建时的时间戳。

  • mZxid :Znode被修改的事务id,即每次对znode的修改都会更新mZxid。对于zk来说,每次的变化都会产生一个唯一的事务id,zxid(ZooKeeper Transaction Id),通过zxid,可以确定更新操作的先后顺序。例如,如果zxid1小于zxid2,说明zxid1操作先于zxid2发生,zxid对于整个zk都是唯一的,即使操作的是不同的znode。

  • pZxid: 表示该节点的子节点列表最后一次修改的事务ID,添加子节点或删除子节点就会影响子节点列表,但是修改子节点的数据内容则不影响该ID(注意: 只有子节点列表变更了才会变更pzxid,子节点内容变更不会影响pzxid)

  • mtime:节点最新一次更新发生时的时间戳.

  • cversion :子节点的版本号。当znode的子节点有变化时,cversion 的值就会增加1。

  • dataVersion:数据版本号,每次对节点进行set操作,dataVersion的值都会增加1(即使设置的是相同的数据),可有效避免了数据更新时出现的先后顺序问题。ephemeralOwner:如果该节点为临时节点, ephemeralOwner值表示与该节点绑定的session id。如果不是, ephemeralOwner值为0(持久节点)。在client和server通信之前,首先需要建立连接,该连接称为session。连接建立后,如果发生连接超时、授权失败,或者显式关闭连接,连接便处于closed状态, 此时session结束。

  • dataLength : 数据的长度

  • numChildren :子节点的数量(只统计直接子节点的数量)

监听通知(watcher)机制

  • 一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。

  • Zookeeper采用了 Watcher机制实现数据的发布订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时例如节点内容改变、节点下的子节点列表改变等,会实时、主动通知所有订阅者。

  • watcher机制事件上与观察者模式类似,也可看作是一种观察者模式在分布式场景下的实现方式。

watcher的过程:

1. 客户端向服务端注册watcher

2. 服务端事件发生触发watcher

3. 客户端回调watcher得到触发事件情况

注意:Zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发送才会触

发监听,通知给客户端。

支持的事件类型:

  • None: 连接建立事件

  • NodeCreated: 节点创建

  • NodeDeleted: 节点删除

  • NodeDataChanged:节点数据变化

  • NodeChildrenChanged:子节点列表变化

  • DataWatchRemoved:节点监听被移除

  • ChildWatchRemoved:子节点监听被移除

特性 :

  • 一次性触发: watcher是一次性的,一旦被触发就会移除,再次使用时需要重新注册

  • 客户端顺序回调: watcher回调是顺序串行执,只有回调后客户端才能看到最新的数据状态。一个watcher回调逻辑不应该太多,以免影响别的watcher行

  • 轻量级 : WatchEvent是最小的通信单位,结构上只包含通知状态、事件类型和节点路径,并不会告诉数据节点变化前后的具体内容

  • 时效性: watcher只有在当前session彻底失效时才会无效,若在session有效期内快速重连成功,则watcher依然存在,仍可接收到通知;

#监听节点数据的变化
get ‐w path
stat ‐w path
#监听子节点增减的变化
ls ‐w path

实践1:

保证组里面只有一个master的设计思路

#master1
 create ‐e /master "m1:2223"

 #master2
 create ‐e /master "m2:2223" # /master已经存在,创建失败
 Node already exists: /master
 #监听/master节点
 stat ‐w /master
#当master2收到/master节点删除通知后可以再次发起创建节点操作
 create ‐e /master "m2:2223"

master监控worker状态的设计思路

 #master服务
 create /workers
 #让master服务监控/workers下的子节点
 ls ‐w /workers

 #worker1
reate ‐e /workers/w1 "w1:2224" #创建子节点,master服务会收到子节点变化通知

 #master服务
 ls ‐w /workers
 #worker2
 create ‐e /workers/w2 "w2:2224" #创建子节点,master服务会收到子节点变化通知

 #master服务
 ls ‐w /workers
 #worker2
 quit #worker2退出,master服务会收到子节点变化通知

应用场景

ZooKeeper适用于存储和协同相关的关键数据,不适合用于大数据量存储。

有了上述众多节点特性,使得 zookeeper 能开发不出不同的经典应用场景,比如:

  • 注册中心

  • 数据发布/订阅(常用于实现配置中心)

  • 负载均衡

  • 命名服务

  • 分布式协调/通知

  • 集群管理

  • Master选举

  • 分布式锁

  • 分布式队列

本地下载

下载Zookeeper

请到 Apache Zookeeper 下载页面 下载最新版本的 zookeeper 发行包。

解压下载的 zookeeper 包:

tar -zxvf apache-zookeeper-3.8.3.tar.gz
cd apache-zookeeper-3.8.3

启动 Zookeeper

在启动 zookeeper 之前,首先需要在根目录以下位置创建文件 conf/zoo.cfg

tickTime=2000
clientPort=2181
admin.enableServer=false

以下是一些参数的详细解释:

  • tickTime : Zookeeper 用到的基本时间设置,tickTime 为心跳检测间隔, 2*tickTime 是最大 session 超时时间等(单位是毫秒 ms)。

  • clientPort : 监听端口,客户端可通过这个端口方案 zookeeper server

  • admin.enableServer:运维端口,默认为 8080,建议关闭防止和 Spring Web 应用程序冲突

接下来,可以以 standalone 模式启动 Zookeeper 了:

bin/zkServer.sh start
# 默认加载配置路径conf/zoo.cfg
# bin/zkServer.sh start conf/zoo.cfg

# 查看zookeeper状态
bin/zkServer.sh status

#widnow启动zkServer.cmd

测试连接到 ZooKeeper

运行以下命令,连接到刚刚启动的 zookeeper server:

# 连接远程的zookeeper server
# 命令格式: bin/zkCli.sh ‐server ip:port

$ bin/zkCli.sh -server 127.0.0.1:2181

连接成功后,可看到以下输出:

Connecting to localhost:2181
...
Welcome to ZooKeeper!
JLine support is enabled
[zkshell: 0]

执行以下命令查看根节点内容:

[zkshell: 8] ls /
[zookeeper]

docker

使用 docker 启动 zookeeper,请首先确保您已经在本地机器正确 下载页面 安装 docker。

运行以下命令启动 zookeeper server:

docker run --name some-zookeeper -p 2181:2181 -e JVMFLAGS="-Dzookeeper.admin.enableServer=false" --restart always -d zookeeper:3.8.3

如果你要指定 /conf 配置文件,可通过 mount 本地文件到 docker 容器:

$ docker run --name some-zookeeper --restart always  -e JVMFLAGS="-Dzookeeper.admin.enableServer=false" -d -v $(pwd)/zoo.cfg:/conf/zoo.cfg

kubernetes

您可以使用 Dubbo 社区提供的示例配置快速安装 Zookeeper 到 Kubernetes 集群。

kubectl apply -f https://raw.githubusercontent.com/apache/dubbo-kubernetes/master/deploy/kubernetes/zookeeper.yaml

文章作者: 刘同学
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 刘同学的小站
中间件
喜欢就支持一下吧