Zookeeper入门实战

一、Zookeeper简介

Zookeeper 是一个开源的分布式协调服务, Apache Hadoop的一个子项目,采用JAVA语言开发。Zookeeper 可以用于实现分布式系统中常见的发布/订阅、负载均衡、服务发现、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

Zookeeper是一种高性能、可扩展的分布式协调服务。Zookeeper将数据存储在内存中,具有高吞吐量和低延迟特性,特别是在多读少写的时候,性能更好。但是zookeeper节点存储的数据大小有限制(官网推荐不超过1M

Zookeeper具有如下特性:

  • 顺序一致性:从一个客户端发起的事务请求,最终都会严格按照其发起顺序被应用到 Zookeeper 中;
  • 原子性:所有事务请求的处理结果在整个集群中所有机器上都是一致的;不存在部分机器应用了该事务,而另一部分没有应用的情况;
  • 最终一致性(单一视图):所有客户端看到的服务端数据模型都是一致的,即无论客户端连接哪台服务器,看到的视图是一样的;
  • 可靠性:一旦服务端成功应用了一个事务,则其引起的改变会一直保留,直到被另外一个事务所更改;
  • 实时性:一旦一个事务被成功应用后,Zookeeper 可以保证客户端立即可以读取到这个事务变更后的最新状态的数据。

二、安装使用

1. 安装部署

下载安装3.8.3,官网地址:https://zookeeper.apache.org/releases.html

  • 解压安装
tar -zxvf apache-zookeeper-3.8.3-bin.tar.gz
  • 配置修改
cd apache-zookeeper-3.8.3-bin
cp apache-zookeeper-3.8.3-bin/conf/zoo_sample.cfg apache-zookeeper-3.8.3-bin/conf/zoo.cfg
vim  apache-zookeeper-3.8.3-bin/conf/zoo.cfg

修改配置文件如下:

# Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,单位毫秒
tickTime=2000 
initLimit=10
syncLimit=5
#数据目录
dataDir=/tmp/zookeeper 
#客户端要连接的端口,即Server 监听的端口号
clientPort=2181 
#8080端口防止被tomcat占用,修改端口
admin.serverPort=8888

集群启动需要配置参数(3台服务器) ,机器分别为192.168.1.100,192.168.1.101,192.168.1.102

server.1=192.168.1.100:2888:3888
server.2=192.168.1.101:2888:3888
server.3=192.168.1.102:2888:3888
  • 启动
bin/zkServer.sh start
#查看状态
bin/zkServer.sh status 
  • 停止
bin/zkServer.sh stop

配置信息详解

  • tickTime:通信心跳数,Zookeeper服务器与客户端心跳时间,单位毫秒
  • initLimit:集群中的 Follower 与 Leader 之间初始连接时能容忍的最多心跳数(initLimit * tickTime为时间)
  • syncLimit:Leader和Follower之间同步通信的超时时间,假如响应超过syncLimit * tickTime,Leader认为Follwer死掉,从服务器列表中删除Follwer。
  • dataDir:数据文件目录路径
  • clientPort :监听客户端连接的端口
  • dataLogDir : 事物日志目录,默认跟数据文件目录一致
  • server.A=B:C:D : 集群信息配置

A 是一个数字,表示这个是第几个服务器
集群模式下配置一个myid文件,这个文件在 dataDir 目录下,这个文件里面有一个数据就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个server
B 是这个服务器的IP地址
C 是这个服务器的集群中的 Leader 服务器交换信息的端口
D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来选举时服务器互相通信的端口

2. 客户端命令

  • 启动客户端
bin/zkCli.sh
#查看命令帮助
help 
  • ls [-w] path 使用 ls 命令来查看当前 znode 中所包含的内容
  • create 普通创建节点 -s 含有序列 -e 临时(重启或超时时消失)
  • get [-w] path 获得节点的数据值
  • set 设置节点的值
  • stat path 查看节点详细信息
  • delete 删除节点
  • deleteall 递归删除节点
  • sync 同步节点
  • quit 退出

三、工作原理

Zookeeper = 文件系统 + 通知机制

从设计模式的角度来理解:Zookeeper是一个基于观察者模式的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接收观察者的注册,一旦这些数据的状态发生变化,就会通知已注册的观察者。

1.文件系统

主要用于管理(存储\读取)用户程序提交的数据

1) 数据节点

Zookeeper 数据模型是由一系列基本数据单元 Znode(数据节点) 组成的节点树,其中根节点为/。每个节点上都会保存自己的数据和节点信息。节点可以分为两大类:

持久节点:节点一旦创建,除非被主动删除,否则一直存在;

临时节点 :一旦创建该节点的客户端会话失效,则所有该客户端创建的临时节点都会被删除。

临时节点和持久节点都可以添加一个特殊的属性:SEQUENTIAL,代表该节点是否具有递增属性。如果指定该属性,那么在这个节点创建时,Zookeeper 会自动在其节点名称后面追加一个由父节点维护的递增数字。

create /book -s #创建有序的节点
create /tmp -e #创建临时节点(会话有效)

2) 节点信息

每个 ZNode 节点在存储数据的同时,都会维护一个叫做 Stat 的数据结构,里面存储了关于该节点的全部状态信息。如下:

stat /test #查看节点信息
  • cZxid - 创建节点的事务 zxid
  • cTime - znode 被创建的毫秒数(从1970 年开始)
  • mZxid - 最后更新的事务 zxid
  • mTime - 最后修改的毫秒数(从1970 年开始)
  • pZixd - 最后更新的子节点 zxid
  • cVersion - znode 子节点变化号,znode 子节点修改次数
  • dataVersion - znode 数据变化号
  • aclVersion - znode 访问控制列表的变化号
  • ephemeralOwner - 如果是临时节点,这个是 znode 拥有者的 session id。如果不是临时节点,则是 0
  • dataLength - znode 的数据长度
  • numChildren - znode 子节点的数量

2.通知机制

为用户程序提供数据节点监听服务

Zookeeper监视点(watchpoint)是一种在Zookeeper中设置的机制,用于监视和观察Znode的变化情况。在Zookeeper中,每个Znode都可以设置一个监视点,当Znode发生变化时,Zookeeper会通知设置了监视点的客户端。为了设置监视点,客户端需要向Zookeeper发送一个watch请求,指定要监视的Znode路径。当Znode发生变化时,Zookeeper会给客户端发送一个通知,客户端可以在收到通知后做出相应的处理.

建立 Zookeeper 连接时传入的 watcher;
通过 getData、exists、getChildren; 来设置watcher,而它们又各有同步和异步两种形式。Zookeeper 的所有读操作都可以设置 watch 监视点: getData, getChildren, exists. 写操作则是不能设置监视点的。

  • 监视有两种类型:数据监视点和子节点监视点。创建、删除或者设置znode都会触发这些监视点。exists,getData 可以设置数据监视点。getChildren 可以设置子节点变化。而可能监测的事件类型有: None、NodeCreated、NodeDataChanged、NodeDeleted、NodeChildrenChanged。

3.选举机制

集群角色

Zookeeper 集群中的机器分为以下三种角色:

  • Leader(领导者) :为客户端提供读写服务,并维护集群状态,它是由集群选举所产生的;
  • Follower(跟随着) :为客户端提供读写服务,并定期向 Leader 汇报自己的节点状态。同时也参与写操作“过半写成功”的策略和 Leader 的选举;
  • Observer(观察者) :为客户端提供读写服务,并定期向 Leader 汇报自己的节点状态,但不参与写操作“过半写成功”的策略和 Leader 的选举,因此 Observer 可以在不影响写性能的情况下提升集群的读性能。

Observer与Follower唯一的区别是:Observer 不参与leader选举的投票

zookeeper 的 leader 选举存在两个阶段,一个是服务器启动时 leader 选举,另一个是运行过程中 leader 服务器宕机。在分析选举原理前,先介绍几个重要的参数。

  • 服务器 ID(myid):编号越大在选举算法中权重越大

  • 事务 ID(zxid):值越大说明数据越新,权重越大

  • 逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加(Zxid的高32位)

  • 选举状态

  • LOOKING: 竞选状态

  • FOLLOWING: 随从状态,同步 leader 状态,参与投票

  • OBSERVING: 观察状态,同步 leader 状态,不参与投票

  • LEADING: 领导者状态

1) 启动选举机制

假设5个节点(Server1,Server2,Server3, Server4, Server5)

  • 节点启动时: 加载本地快照文件及事务日志,恢复内存数据,所有节点都会进入 LOOKING 状态。
  • 发送选举消息:每个节点会向其他节点发送选举消息,它们会将自己的信息包括自己的 myid(唯一标识)和 ZXID(事务 ID)发送给其他节点。
  • 接收选举消息:节点会接收其他节点发送的选举消息,并比较其中的信息。
  • 选举算法执行:节点会根据选举算法来决定谁将成为领导者。通常情况下,节点会选择具有最大 ZXID 值的节点作为领导者。如果多个节点的 ZXID 值相同,则选择 myid 值更大的节点作为领导者。
  • 收到选举结果:一旦一个节点收到过半节点的选票(反馈),它会成为领导者,其他节点则成为追随者。
  • 同步数据:新选举出的Leader会以自己数据为基准,结合各个Follower的本地提交数据,确定给具体Follower回滚哪些数据和同步哪些数据

整个选举流程是自动进行的,ZooKeeper 内部实现了选举算法和消息交换机制。一旦选举完成,领导者节点将负责处理客户端请求,并保持与其他节点的心跳连接以维持集群的正常运行。

2) 非第一次启动选举机制(恢复模式)

当Leader 宕机以后,Follower节点都会变成LOOKING节点, 会触发选举机制, ZXID值大的胜出,ZXID值相同,myid值大的胜出.

ACL

Zookeeper 采用 ACL(Access Control Lists) 策略来进行权限控制,类似于 UNIX 文件系统的权限控制。它定义了如下五种权限(简写cdrwa):

  • CREATE:允许创建子节点;
  • READ:允许从节点获取数据并列出其子节点;
  • WRITE:允许为节点设置数据;
  • DELETE:允许删除子节点;
  • ADMIN:允许为节点设置权限。

Zookeeper的权限控制是基于znode节点的,需要对每个节点设置权限
五种权限认证模式:

  1. world 权限模式: 默认模式每个客户端都设置一样cdrwa 权限
#创建默认/test节点, 未设置权限默认是world模式
create /test hello 
#获取/test节点的ACL
getAcl /test 
  1. auth 权限模式:
#设置auth之前,先添加账号:密码,比如test:test@2024
addauth digest test:test@2024 
#设置/test节点设置test账号cdrwa权限, 只有登录test 账号的客户端才能cdrwa 节点/test
setAcl /test auth:test:cdrwa
#客户端登录test账号
addauth digest test:test@2024
  1. digest 权限模式:

digest授权模式基于账号密码的授权模式,与Auth模式类似,只是他设置权限之前不需要使用
addauth digest username:password进行权限用户添加。直接使用命令 setAcl path digest:username:password:acl 进行授权就行。只是这里的密码要使用加密后的密码,不能使用明文密码

#计算密文
echo -n test:test@2024 | openssl dgst -binary -sha1 | openssl base64
##得到OiTewOYRV8qivsx7WoXjiR0+6VI=
setAcl /test digest:test:OiTewOYRV8qivsx7WoXjiR0+6VI=:cdrwa
  1. ip权限模式:
#只能127.0.0.1 客户端cdrwa 节点/test
setAcl /test  ip:127.0.0.1:cdrwa 
  1. 管理员模式:
    需要重启zk,在 zkEnv.sh 添加如下行
export SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=admin:YyNjoNUGKrgkriwbwIhqA7oK/jo= $SERVER_JVMFLAGS" 

#计算密文
echo -n admin:test@2024 | openssl dgst -binary -sha1 | openssl base64
  • 同时设置多个权限模式( 逗号分隔)
setAcl /test ip:127.0.0.1:cdrwa,auth:test:cdrwa,world:anyone:cdrwa,digest:test:OiTewOYRV8qivsx7WoXjiR0+6VI=:cdrwa

写数据流程

  • 1.当事务请求发送到Follower服务器节点,请求会先转发给Leader节点;
  • 2.Leader节点把写请求转化成一个事务Proposal(提议),并把这个 Proposal 分发给集群中的所有 Follower 节点;
  • 3.如果过半的Follower节点同意(返回ACK),Leader 就会再次向所有的Follower 节点发送 Commit 消息,要求各个 Follower 节点对前面的一个 Proposal 进行提交;
  • 4.把最后的结果同步给Observer节点;
  • 5、把写数据的最终结果返回给客户端;

读数据流程

由于数据一致性,所有每个节点的数据是一样,随便访问哪个节点(不管是Leader还是Follow)读取数据都行,也就是说,任务节点都可以去处理读请求, 无须转发, 提高负载能力.

4. ZAB 协议

Zab协议是为分布式协调服务Zookeeper专门设计的一种 支持崩溃恢复 的 原子广播协议 ,是Zookeeper保证数据一致性的核心算法。它借鉴了Paxos算法,但又不是完完全全的按照Paxos算法去实现的,解决了一些Paxos算法的问题.Zab协议有两种模式:1.恢复模式(选主)2.广播模式(同步)

Paxos算法

paxos算法是分布式中保证一致性的一种算法,引入了半数原则,它可以保证在节点失效、网络分区、网络延迟等情况下各个节点状态的一致性;有三个版本:Basic Paxos , Multi PaxosFast Paxos(ZAB协议就基于Fast Paxos的)

四、Springboot集成

curator 是针对zookeeper 的客户端程序

五、使用场景

1.配置管理

数据的发布/订阅系统,通常也用作配置中心。将数据发布到ZooKeeper节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。

2.命名服务

在分布式系统中,通常需要一个全局唯一的名字,如生成全局唯一的订单号等,Zookeeper 可以通过顺序节点的特性来生成全局唯一 ID,从而可以对分布式系统提供命名服务。

3.Master选举

分布式系统一个重要的模式就是主从模式 (Master/Salves),Zookeeper 可以用于该模式下的 Matser 选举。可以让所有服务节点去竞争性地创建同一个 ZNode,由于 Zookeeper 不能有路径相同的 ZNode,必然只有一个服务节点能够创建成功,这样该服务节点就可以成为 Master 节点。

4. 分布式锁

可以通过 Zookeeper 的临时节点和 Watcher 机制来实现分布式锁,这里以排它锁为例进行说明:

分布式系统的所有服务节点可以竞争性地去创建同一个临时 ZNode,由于 Zookeeper 不能有路径相同的 ZNode,必然只有一个服务节点能够创建成功,此时可以认为该节点获得了锁。其他没有获得锁的服务节点通过在该 ZNode 上注册监听,从而当锁释放时再去竞争获得锁。锁的释放情况有以下两种:

当正常执行完业务逻辑后,客户端主动将临时 ZNode 删除,此时锁被释放;
当获得锁的客户端发生宕机时,临时 ZNode 会被自动删除,此时认为锁已经释放。
当锁被释放后,其他服务节点则再次去竞争性地进行创建,但每次都只有一个服务节点能够获取到锁,这就是排他锁。

5.集群管理

Zookeeper 还能解决大多数分布式系统中的问题:

如可以通过创建临时节点来建立心跳检测机制。如果分布式系统的某个服务节点宕机了,则其持有的会话会超时,此时该临时节点会被删除,相应的监听事件就会被触发。
ls

分布式系统的每个服务节点还可以将自己的节点状态写入临时节点,从而完成状态报告或节点工作进度汇报。

通过数据的订阅和发布功能,Zookeeper 还能对分布式系统进行模块的解耦和任务的调度。

通过监听机制,还能对分布式系统的服务节点进行动态上下线,从而实现服务的动态扩容。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容