应用协调服务&&ZooKeeper&&基础使用

概述

分布式系统是由多个节点协同工作的系统,它们可以提供高可用性、高性能和高扩展性的服务。然而,分布式系统也面临着很多挑战,如网络延迟、节点故障、数据一致性等。为了解决这些问题,分布式系统需要一个协调服务来管理节点之间的通信和协作。
ZooKeeper 就是一个高性能的分布式应用协调服务。
Java开源工具库使用之ZooKeeper
详解Zookeeper(铲屎官)在中间件的应用和在Spring Boot业务系统中实现分布式锁和注册中心的解决方案
一文让你搞懂 zookeeper

数据模型

ZooKeeper存储的数据是以树形结构组织的节点(ZNode),每个节点都有一个唯一路径(path)标识,并包含一些元数据(metadata)和可选值(value)。每个节点还可以有子节点(child node),形成层次关系。客户端可以通过路径来访问或操作节点。ZNode 的路径由斜杠分隔,并且必须是绝对路径(不能使用相对路径)。ZNode 的名称可以包含 Unicode 字符。
在这里插入图片描述
每个 ZNode 都有一个状态结构(stat),用于记录该 ZNode 的元数据信息,例如创建时间、修改时间、版本号、子节点数量等。ZooKeeper 客户端可以通过这些信息来判断 ZNode 的变化,并做出相应的操作。
ZooKeeper 支持四种类型的 ZNode:

  1. 临时节点(Ephemeral ):节点的生命周期依赖于创建它们的会话,一旦会话结束,临时节点将被自动删除。
  2. 永久节点(Persistent ):该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。
  3. 序列化节点(Sequence ):Znode还有一个序列化的特性,如果创建的时候指定的话,该Znode的名字后面会自动追加一个不断增加的序列号。它的格式为10位数字,没有数值的数位用0补充,例如:0000000001。
  4. 临时顺序节点:基本特性同临时节点,增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。

每个Znode由3部分组成:

  • stat:此为状态信息, 描述该Znode的版本权限等信息;
  • data:与该Znode关联的数据;
  • children:该Znode下的子节点;

每一个ZNode默认能够存储 1MB 的数据,可见Zookeeper并不适合用于存储大量数据,只适用于存储关键的配置数据和集群数据。
它的作用主要是用来维护和监控你存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。

会话管理

ZooKeeper与客户端之间维持着会话(session),客户端需要定期向服务器发送心跳包(ping)来保持会话有效。如果客户端与服务器失去联系超过指定时间,则会话失效,并且该客户端创建或持有的临时节点(ephemeral node)也会被删除。临时节点是一种特殊类型的节点,它只存在于创建它或持有它 的客户端有效期内,在客户端断开连接后自动消失。临时节点不能有子节点。
ZooKeeper 会话是指客户端和服务器之间的一种连接状态,用于保证客户端的请求和响应的一致性。每个 ZooKeeper 会话都有一个唯一的 64 位标识符(session id),以及一个超时时间(session timeout)。

  • Session id:是由服务器在客户端第一次连接时分配给客户端的,用于标识该客户端的身份。如果客户端断开连接后重新连接到另一个服务器,它会发送自己的 session id 给新的服务器,以便继续之前的会话。
  • Session timeout:是由客户端在创建 ZooKeeper 实例时指定的,用于告诉服务器该客户端多久没有发送心跳包就认为是失效了。如果服务器在 session timeout 时间内没有收到客户端的任何消息,它会认为该客户端已经断开连接,并且删除其相关的临时 ZNode 和监听事件。

ZooKeeper 客户端需要定期向服务器发送心跳包(ping),以维持自己的会话状态。如果客户端因为网络故障或其他原因无法与当前服务器通信,它会尝试连接到其他可用的服务器,并且恢复自己的会话状态。
ZooKeeper 客户端可以通过注册 Watcher 来监听 ZNode 的变化事件,并且在事件发生时得到通知。Watcher 只能触发一次,如果客户端想要持续监听 ZNode 的变化,需要重新注册 Watcher。Watcher 的注册和触发都是在 ZooKeeper 会话中进行的,如果 ZooKeeper 会话失效了,Watcher 的注册和触发也就无效了。
在这里插入图片描述

一致性保证

ZooKeeper 是一个分布式协调服务,它需要在多个服务器节点之间同步数据,并且保证客户端能够访问到最新的数据。为了实现这一目标,ZooKeeper 提供了以下几种一致性保证:

  • 原子性(Atomicity):每个更新操作(创建、删除、修改 ZNode)都是原子的,要么成功要么失败。
  • 顺序性(Ordering):每个更新操作都有一个全局唯一的事务编号(zxid),用于表示该操作在整个集群中的顺序。客户端可以通过 zxid 来判断 ZNode 的变化情况。
  • 单一系统映像(Single System Image):无论客户端连接到哪个服务器节点,它都能看到相同的数据视图。
  • 可靠性(Reliability):如果一个更新操作成功完成了,那么它会被持久化到所有服务器节点上,并且不会被撤销。
  • 实时性(Timeliness):客户端能够在一个有限的时间内访问到最新的数据。

ZooKeeper 的一致性保证是基于领导者选举和 ZAB 协议实现的。领导者选举是指集群中的服务器节点通过投票机制选择出一个 leader 节点,负责处理所有的写请求和协调其他节点的状态。ZAB 协议是指 ZooKeeper 原子广播协议,用于在 leader 和 follower 节点之间传输和同步数据。
ZooKeeper 的一致性保证并不是强一致性(Strong Consistency),而是顺序一致性(Sequential Consistency)。这意味着不同的客户端可能会看到不同版本的数据,但是他们看到的数据变化顺序是相同的。这样做可以提高读取效率和容错能力,但也可能带来一些问题,例如脑裂现象(Split Brain)。因此,在使用 ZooKeeper 时需要注意避免这些问题,并且合理设置超时时间和重试次数等参数。
ZooKeeper 通过使用 Quorum 算法来防止脑裂现象。Quorum 算法的基本思想是要求集群中的大多数节点(超过一半)能够正常通信和工作,才能进行领导者选举和状态变化广播。因此,ZooKeeper 集群的节点数应该是奇数,以避免出现平局。如果某个子集的节点数不满足 Quorum 条件,那么它就不能产生领导者节点,也不能处理客户端的请求。
ZooKeeper 保证了以下三种顺序:

  • 全局顺序:所有服务器按照相同的顺序执行相同的请求。
  • 因果顺序:如果一个事件A在另一个事件B之前发生,则任何观察到B的客户端也必然观察到A。
  • 客户端顺序:对于同一个客户端发出的请求,任何服务器都按照该客户端发送请求的顺序来执行。

特点

待补充:服务的突出特点

适用场景:

  • 数据发布/订阅:可以作为配置中心,实现配置信息的集中式管理和动态更新。发布者将数据发布到 ZooKeeper 的节点上,订阅者通过监听器获取数据的变化,从而实现数据的同步和共享。
    • Hadoop、HBase、Kafka 等分布式系统都使用 ZooKeeper 作为配置中心,实现配置信息的集中式管理和动态更新。例如,HBase 中的 HMaster 节点会将集群的元数据信息(如 RegionServer 列表、Region 分布情况等)存储在 ZooKeeper 的节点上,客户端和其他 RegionServer 节点可以通过 ZooKeeper 获取这些信息,并在发生变化时及时更新。
  • 负载均衡:可以作为服务注册中心,实现服务的发现和负载均衡。服务提供者将自己的地址信息注册到 ZooKeeper 的节点上,服务消费者通过 ZooKeeper 获取可用的服务列表,并根据一定的策略选择合适的服务提供者。
    • Dubbo、Spring Cloud 等微服务框架都使用 ZooKeeper 作为服务注册中心,实现服务的发现和负载均衡。例如,Dubbo 中的服务提供者会将自己的地址信息注册到 ZooKeeper 的节点上,服务消费者会通过 ZooKeeper 获取可用的服务列表,并根据一定的策略(如随机、轮询、最少活跃等)选择合适的服务提供者。
  • 命名服务:可以作为命名服务,实现分布式系统中唯一标识符的生成和管理。利用 ZooKeeper 的顺序节点特性,可以保证每个节点都有一个全局唯一且有序的名称。
    • SolrCloud 是一个分布式搜索平台,它使用 ZooKeeper 作为命名服务,实现分布式系统中唯一标识符的生成和管理。例如,SolrCloud 中每个集合(collection)都有一个唯一的名称,每个分片(shard)都有一个唯一的编号,每个副本(replica)都有一个唯一的 ID。这些名称、编号和 ID 都是通过 ZooKeeper 的顺序节点特性生成和存储的。
  • 分布式协调/通知:可以实现分布式协调/通知机制,实现分布式系统中各个组件之间的协作和状态同步。利用 ZooKeeper 的临时节点特性,可以实现故障检测和恢复;利用 ZooKeeper 的监听器特性,可以实现事件驱动和消息通知。
    • Storm 是一个分布式实时计算框架,它使用 ZooKeeper 作为分布式协调/通知机制,实现分布式系统中各个组件之间的协作和状态同步。例如,Storm 中有一个 Nimbus 节点负责管理整个集群,并将任务分配给多个 Supervisor 节点;Supervisor 节点负责启动和停止 Worker 进程;Worker 进程负责执行具体的计算任务。这些节点之间都需要通过 ZooKeeper 来进行通信和协调 。
  • 集群管理:可以作为集群管理工具,实现集群中各个节点的监控和管理。利用 ZooKeeper 的元数据存储特性,可以存储集群中各个节点的状态信息;利用 ZooKeeper 的 ZAB 协议特性,可以保证集群中各个节点之间的数据一致性。
    • Redis 是一个高性能的内存数据库,它支持主从复制和哨兵模式来实现高可用性。Redis 使用 ZooKeeper 作为集群管理工具,实现集群中各个节点的监控和管理。例如,在哨兵模式下,哨兵节点会将自己注册到 ZooKeeper 的临时节点上,并定期向其发送心跳;当主节点故障时,哨兵节点会通过 ZooKeeper 进行领导者选举,并通知其他哨兵节点切换从节点为主节点 。
  • Master 选举:Master 选举机制,实现分布式系统中主从模式下主节点的选取和切换。利用 ZooKeeper 的临时顺序节点特性,可以保证在多个候选者中只有一个能够成为主节点,并在主节点故障时进行重新选举。
  • 分布式锁:可以作为分布式锁服务,实现分布式系统中对共享资源的互斥访问。利用 ZooKeeper 的临时顺序节点特性,可以保证在多个请求者中只有一个能够获得锁,并在持有锁的请求者释放或断开连接时进行锁释放。
  • 分布式队列:可以作为分布式队列服务,实现分布式系统中对任务或消息的先进先出(FIFO)或优先级处理。利用 ZooKeeper 的顺序节点特性,可以保证队列中元素按照插入顺序或优先级顺序排列,并支持并发地插入或删除操作。

相关概念

待补充:

优缺比较

优点:

  • 简单的分布式协调过程:ZooKeeper 提供了一个简单的数据模型,基于树形结构的 znode 节点,可以存储数据和元数据,并支持临时节点、顺序节点等类型。ZooKeeper 还提供了一些原语操作,如创建、删除、读取、写入等,以及一些高级功能,如监听器、订阅者等。
  • 高度同步的工作方式:ZooKeeper 保证了所有节点之间的数据一致性,通过 ZAB 协议实现了领导者选举和事务日志复制。ZooKeeper 还支持互斥和协作之间的服务器进程。
  • 多样化的分布式场景应用:ZooKeeper 可以用于实现各种分布式场景下的功能和服务,如配置管理、命名服务、集群管理、负载均衡、锁服务、队列服务等。
  • 成熟的开源社区和生态系统:ZooKeeper 是 Apache 的顶级项目之一,有着广泛的用户群和活跃的开发者社区。ZooKeeper 还有很多基于它开发的框架和库,如 Curator(一个 Java 库),提供了很多分布式 ZooKeeper 模式的实现。

缺点:

  • 低效的写入性能:由于 ZooKeeper 需要保证所有节点之间的强一致性,因此每次写入操作都需要经过领导者节点的确认,并复制到所有跟随者节点上。这样就增加了写入操作的延迟和开销,并降低了吞吐量。
  • 有限的存储容量:由于 ZooKeeper 的数据都存储在内存中,因此受到内存大小的限制。如果数据量过大或者节点数量过多,可能会导致内存不足或者 GC 压力过大。
  • 缺乏动态扩容能力:由于 ZooKeeper 需要维护所有节点之间的状态信息,并保证领导者选举和事务日志复制等机制正常运行,因此不能随意地增加或减少节点数量。如果需要扩容或缩容集群规模,需要进行手动操作,并可能会影响集群稳定性。

搭建集群

通用集群

集群架构

Zookeeper 是由多个服务器(server)组成的集群(ensemble),每个服务器都存储着相同的数据,并通过 ZAB (ZooKeeper Atomic Broadcast Protocol) 协议保证数据一致性。客户端(client)可以连接到任意一个服务器,并通过发送请求(request)来读取或修改数据。服务器会根据请求类型进行处理,并返回响应(response)。如果请求涉及到修改数据,则服务器会将请求转发给领导者(leader),领导者会将请求广播给其他跟随者(follower),并等待他们达成一致后再执行请求并返回响应。

Zookeeper 集群是由多个服务器节点组成的,每个节点都可以提供协调服务。为了保证数据的一致性,Zookeeper 集群中的节点分为三种角色:leader、follower 和 observer。

  • Leader 节点是集群中的主节点,负责处理客户端的写请求,以及协调 follower 节点的状态。Leader 节点通过投票选举产生,一个集群中只能有一个 leader 节点。
  • Follower 节点是集群中的从节点,负责处理客户端的读请求,以及同步 leader 节点的数据。Follower 节点可以参与投票选举 leader 节点。
  • Observer 节点是集群中的观察者节点,负责处理客户端的读请求,以及同步 leader 节点的数据。Observer 节点不参与投票选举 leader 节点,也不影响集群的可用性和一致性。

Zookeeper 集群通常需要奇数个节点(至少三个),这样可以保证在出现故障时仍然能够正常工作。

在这里插入图片描述
Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

环境信息

idip
110.10.0.10
210.10.0.22
210.10.0.26

安装zookeeper

# 初始化java环境
vim /etc/profile
## JAVA_HOME
JAVA_HOME=/data/software/jdk/jdk1.8.0_161
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME CLASSPATH PATH
export KAFKA_HOME=/data/software/kafka/kafka_2.11-2.2.1
export ZOOKEEPER_HOME=/data/software/zookeeper/zookeeper
export PATH=$PATH:${KAFKA_HOME}/bin:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf

source /etc/profile
# 下载 ZooKeeper
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.10/apache-zookeeper-3.5.10-bin.tar.gz
# 解压
tar -zxf apache-zookeeper-3.5.10-bin.tar.gz
# 进入 ZooKeeper 目录
cd apache-zookeeper-3.5.10-bin
# 复制示例配置文件
cp conf/zoo_sample.cfg conf/zoo.cfg
vim conf/zoo.cfg
# 服务器之间或客户端与服务器之间维持心跳的时间间隔,tickTime以毫秒为单位。
tickTime=2000
# 集群中的follower服务器(F)与leader服务器(L)之间的初始连接心跳数
initLimit=10
# 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数
syncLimit=5
clientPort=2181
# ZooKeeper 数据存储目录
dataDir=/data/zk/data
# 日志保存目录
dataLogDir=/data/zk/datalog

# ZooKeeper 客户端连接端口
clientPort=2181

# ZooKeeper 集群节点信息
# server.第几号服务器(等于myid)=服务器的地址:服务器 Follower 与集群中的 Leader 服务器交换信息的端口:重新选举Leader时服务器相互通信的端口
server.1=10.10.0.10:2888:3888
server.2=10.10.0.22:2888:3888
server.3=10.10.0.26:2888:3888

# 在每个节点上创建一个 myid 文件,其中包含节点的编号,对应于 server.X 中的 X
# 例如,在第一个节点上:
echo "1" > /path/to/dataDir/myid

# 在第二个节点上:
echo "2" > /path/to/dataDir/myid

# 在第三个节点上:
echo "3" > /path/to/dataDir/myid

# 确保防火墙允许 ZooKeeper 使用的端口(默认是 2181)
# ZooKeeper 3.6.0 之前版本
bin/zkServer.sh start
# ZooKeeper 3.6.0 及更高版本
bin/zookeeper-server-start.sh -daemon conf/zoo.cfg

#  验证 ZooKeeper.
bin/zkServer.sh status
zkCli.sh -server 192.168.3.80:2181
ls -s /

当 quorumListenOnAllIPs=true 时,ZooKeeper 服务器将接受来自任何 IP 地址的连接请求。
当 quorumListenOnAllIPs=false 时,ZooKeeper 服务器将仅接受来自指定 IP 地址的连接请求。

客户端命令

# 创建一个持久无序号节点和下级节点
[zk: localhost:2181(CONNECTED) 6] create /car "car"
Created /car
[zk: localhost:2181(CONNECTED) 7] create /car/tesla "mask"
Created /car/tesla
# 创建一个持久有序号节点
[zk: localhost:2181(CONNECTED) 11] create -s /car/tesla/model_y  "yyyyy"
Created /car/tesla/model_y0000000000
[zk: localhost:2181(CONNECTED) 12] create -s /car/tesla/model_y  "ypppp"
Created /car/tesla/model_y0000000001
[zk: localhost:2181(CONNECTED) 13] ls /car/tesla
[model_y0000000000, model_y0000000001]
# 创建一个临时有序号的节点,客户端与服务器断开连接后,节点就会删除
k: localhost:2181(CONNECTED) 14] create -e -s /car/tesla/model_3 "33333"
Created /car/tesla/model_30000000002
[zk: localhost:2181(CONNECTED) 15] create -e -s /car/tesla/model_3 "3_new"
Created /car/tesla/model_30000000003
[zk: localhost:2181(CONNECTED) 17] ls /car/tesla
[model_30000000002, model_30000000003, model_y0000000000, model_y0000000001]
# 获取节点的值:
[zk: localhost:2181(CONNECTED) 18] get -s /car/tesla
mask
cZxid = 0x340
ctime = Thu Sep 28 17:35:46 CST 2023
mZxid = 0x340
mtime = Thu Sep 28 17:35:46 CST 2023
pZxid = 0x344
cversion = 4
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 4
# 设置节点的值:
[zk: localhost:2181(CONNECTED) 19] set /car/tesla "mask-1111"
[zk: localhost:2181(CONNECTED) 20] get /car/tesla
mask-1111

备份恢复

zookeeper和redis很像,数据都是在内存中的,持久化也是两种方式,一种是记录事务日志,一种是快照方式。

记录事务日志磁盘会进行IO操作,事务日志的不断增多会触发磁盘为文件开辟新的磁盘块,所以为了提升磁盘的效率,可以在创建文件的时候就向操作系统申请一块大一点的磁盘块,通过参数zookeeper.preAllocSize配置。

事务日志的存放地址通过zoo.cfg配置文件中的dataDir来指定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值