天天看点

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

首发CSDN:徐同学呀,原创不易,转载请注明源链接。我是徐同学,用心输出高质量文章,希望对你有所帮助。 快来和我一起学习ZooKeeper吧!

文章目录

    • 一、前言
    • 二、Zookeeper一个动物园管理员的职责
      • 1、工作原理
      • 2、功能特点
      • 3、数据结构
    • 三、Zookeeper的应用场景
      • 1、配置管理
      • 2、命名服务
        • (1)分布式API目录JNDI
        • (2)分布式ID生成器
      • 3、服务注册中心
      • 4、服务上下线感知
      • 5、集群通信与控制子系统
      • 6、分布式锁
    • 四、ZooKeeper下载与安装
      • 1、下载与安装
      • 2、配置说明
    • 五、ZooKeeper集群搭建
      • 1、伪集群
        • (1)准备myid文件
        • (2)配置zoo-.cfg文件
      • 2、集群启动第一次Leader选举
      • 3、模拟服务实例宕机leader重选
      • 4、编写集群批量启动脚本
    • 六、要点回顾
    • 七、参考文献

一、前言

ZooKeeper

是一个可靠的、强一致性的、没有单点故障的分布式数据存储系统。因为其出色的设计(ZAB一致性算法,Watch机制等)和协调能力,使得它成为很多分布式系统的基石,就像其名称动物园管理员一样,做着比较基层的管理协调工作,比如配置管理,命名服务,服务注册发现等。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

二、Zookeeper一个动物园管理员的职责

1、工作原理

Zookeeper

的两个核心设计:

Watch

机制和

ZAB

一致性算法。

  • Watch

    机制,可以理解为事件监听模式,

    Zookeeper

    负责存储数据,并暴露各种事件注册接口,使用者向

    Zookeeper

    注册关心的事件监听器,比如监听节点的创建、修改、删除等,一旦监听的节点数据状态发生变化,

    Zookeeper

    就会通知回调注册在

    Zookeeper

    上的监听器做出相应的反应。
  • Zab

    借鉴

    Paxos

    算法,特意为

    Zookeeper

    设计的支持崩溃恢复的原子广播协议。基于该协议,

    Zookeeper

    设计了

    Leader-Follower

    机制,只有Leader负责写请求,然后由

    Leader

    Follower

    发起写同步。

2、功能特点

Zookeeper

保证的是CP。P(

Partition Tolerance

分区容错性)是必须要有的,所以只能从C(Consistency一致性)和A(Available可用性)中抉择。鱼和熊掌不可兼得,

Zookeeper

选择了C,

Zookeeper

可以保证数据是一致的,无法保证服务一直处于可用状态,可能会因为网络原因导致一些请求丢失,服务宕机超过半数等,同时在Leader选举时对外也是不可用的。

  • 一个领导者(

    Leader

    ),多个跟随者(

    Follower

    ),

    Leader

    负责读写,并向

    Follower

    发起写同步指令,

    Follower

    只负责读,如果

    Follower

    接收到写请求,需要转发给

    Leader

  • 集群中只要有半数以上节点存活,

    Zookeeper

    集群就能正常服务,所以

    Zookeeper

    适合安装奇数台服务器。
  • 数据全局强一致性,每个

    Server

    保存一份相同的数据副本,

    Client

    无论连接到哪个

    Server

    ,数据都是一致的。
  • 更新请求顺序执行,从

    Follower

    转发的写请求或者

    Leader

    自己接收的写请求按先后顺序执行。
  • 数据更新原子性,一次数据更新要么成功,要么失败。
  • 实时性,在一定时间范围内,

    Client

    能读到最新数据。

3、数据结构

ZooKeeper

的数据结构是类UNIX文件系统目录树结构,其中,每个节点称为

ZNode

,每个

ZNode

通过其路径(Path)唯一标识,每个

ZNode

可以存储少量二进制数据,默认最大为1MB,通常不建议在

ZNode

上存储大量的数据,因为在数据量比较大时,数据在多节点同步的性能较低。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

ZNode

有四种类型,节点类型不同,生命周期也不同:

  • 持久节点(

    PERSISTENT

    ),节点在创建后会一直存在,即使客户端断开连接,zk重启都不会删除该节点,直到有删除操作来主动删除这个节点。持久节点可以持久保存数据,最典型的场景是存储配置信息,集合Watch机制,可以实现配置信息实时生效的特性。
  • 临时节点(

    EPHEMERAL

    ),临时节点的生命周期和创建这个节点的客户端会话绑定,也就是说,如果客户端会话失效(客户端宕机或下线),这个节点就被自动删除。临时节点跟随端客户端启动创建和客户端停止而删除,典型场景是感知服务的上下线,判断服务是否存活。
  • 时序节点(

    SEQUENTIAL

    ),创建节点时,节点的名称会自动加上一个递增数字后缀,这个数字后缀的范围为整型的最大值。该节点也是持久节点。每个节点都有唯一编号,类似于数据库的自增长主键,典型场景是生成全局唯一的分布式Id。
  • 临时时序节点(

    EPHEMERAL_SEQUENTIAL

    ),同时具备临时节点与时序节点的特性,可用于分布式锁的实现。
    分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

三、Zookeeper的应用场景

ZooKeeper

的应用得益于它的节点存储特性和Watch机制。比较典型的几个应用场景,如配置管理,命名服务,服务注册中心,服务上下线感知,集群通信与控制子系统,分布式锁,分布式Id等。

1、配置管理

配置管理利用

ZooKeeper

的持久节点存储配置信息,结合Watch机制,实现配置信息实时生效的特性。配置管理在实际生产中叫配置中心,可以统一管理几乎所有的可配置的,动态的配置信息,配置中心的应用也是

ZooKeeper

最广泛、最基础的使用场景。

推荐一个基于

ZooKeeper

实现的,可直接用于生产的配置中心开源框架Qihoo360/QConf,好用,高性能,支持多种语言SDK。

2、命名服务

命名服务是为系统中的资源提供标识能力。

ZooKeeper

的命名服务主要是利用

ZooKeeper

节点的树状分层结构(路径唯一)和子节点的顺序维护能力,来为分布式系统中的资源命名。

用到命名服务的典型场景有:分布式API目录

JNDI

,分布式ID生成器,分布式节点命名等。

(1)分布式API目录JNDI

著名的

Dubbo

分布式框架就是利用

ZooKeeper

实现分布式的

JNDI

(Java Naming and Directory Interface)功能:

  • 服务提供者(Service Provider)在启动的时候,向

    ZooKeeper

    上的指定节点

    /dubbo/${serviceName}/providers

    写入自己的API地址,这个操作就相当于服务的公开。
  • 服务消费者(

    Consumer

    )启动的时候,订阅节点

    /dubbo/{serviceName}/providers

    下的服务提供者的URL地址,获得所有服务提供者的API。

(2)分布式ID生成器

分布式ID主要用于分布式系统中对数据做全局唯一标识,典型的应用场景是,调用链路追踪。分布式ID的生成方式也很多,

UUID

、数据库自增(

mysql

redis

等)、雪花算法等。

ZooKeeper

是个天生的发号器,其时序节点(无论持久和临时),每个节点都会为它的第一级子节点维护一份递增编号,且是分布式全局唯一的。例如,在创建节点时,传入节点前缀

/myID/id_

ZooKeeper

自动会在

/myID/id_

后面补充数字顺序,例如

/myID/id_00000001

根据这个特性,可以简单实现一个分布式Id生成器。比较著名的雪花算法,可以利用

ZooKeeper

来动态管理机器Id。

3、服务注册中心

服务注册中心,其实也是命名服务的一种应用,即用

ZooKeeper

来存储服务的注册信息。服务的注册信息有:服务名称,服务类型,服务的IP、端口,一个服务可以有多个实例,每个实例为一个节点,节点有状态(实例运行状态),权重、类型(实例角色类型)等。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

服务注册中心是服务注册发现架构实现的基础,这个架构中还有两个非常重要的角色:服务提供者和服务消费者。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

服务提供者在启动时,将自身的服务信息注册到服务注册中心,服务消费者启动时,会主动从服务注册中心拉取感兴趣的服务信息。

ZooKeeper

作为服务注册中心还有一个好处是,可以利用

Watch

机制,当服务注册信息更新时,及时通知服务消费者拉取最新数据。

一般服务消费者不会直接连注册中心,而是异步监听注册中心的变化,并将注册信息拉取到本地缓存,这样可以大大降低

ZooKeeper

的压力,推荐使用 Qihoo360/QConf 实现注册中心。

4、服务上下线感知

服务上下线感知,主要利用

ZooKeeper

的临时节点实现。应服务在启动时会将自己的IP地址作为临时节点创建在某个节点(如

/Cluster

)下,当服务因为某些原因如断网或者宕机,使得它与

ZooKeeper

的会话过期时,这个临时节点就会被删除,可以通过这个特性来感知服务的集群有哪些机器可用了。

同时,可以对这些临时节点做监听,感知服务的上下线,并作出相应反应。

5、集群通信与控制子系统

利用

ZooKeeper

的Watch机制,可以很容易实现集群间的高效通信和控制子系统。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)
  • ZooKeeper

    里规划一个用于存放控制命令和应答的·路径(如

    /Commands

    );
  • 集群中的所有节点在启动后都监听此路径(

    /Commands

    );
  • 命令行程序(CLI)发给集群节点的命令及参数被包装成一个

    ZNode

    节点(如上图中的

    command1

    ),写入

    /Commands

    路径下,同时在

    command1

    上监听事件。
  • 集群中的所有节点都通过

    /Commands

    上的Watch事件收到此命令,然后开始执行

    command1

    命令对应的逻辑;
  • 在某个节点执行完成后就在

    command1

    路径下新建一个

    ZNode

    节点(如

    node1result

    )作为应答。
  • 由于CLI之前在

    command1

    上监听,所以很快就被通知此命令已经有节点执行完成,CLI就可以实时输出结果,在所有节点的应答都返回后(或者等待超时),命令行结束。

6、分布式锁

使用

ZooKeeper

实现分布式锁的原理是利用时序节点和Watch机制:

(1)一个

ZNode

节点代表一把锁,如果锁对应的

ZNode

节点不存在,那么先创建

ZNode

节点。需要使用分布式锁功能先申请一个业务路径,如

/lock/app1

(不同服务和不同业务隔离),如果不区分锁的业务路径,也需要区分锁的前缀。

(2)抢占锁的所有客户端,使用锁的

ZNode

节点的子节点列表来表示;如果某个客户端需要占用锁,则在

/lock/app1

下创建一个临时有序的子节点。

(3)如何判断客户端是否占有锁?客户端创建子节点后,需要判断自己创建的子节点是否为当前子节点列表中序号最小的子节点。如果是,则认为加锁成功;如果不是,则监听前一个

ZNode

子节点的变更消息,等待前一个节点释放锁。

(4)一旦队列中后面的节点获得前一个子节点的变更通知,则开始进行判断,判断自己是否为当前子节点列表中序号最小的子节点,如果是,则认为加锁成功;如果不是,则持续监听,一直到获得锁。

(5)获取锁后,开始处理业务流程。在完成业务流程后,删除对应的子节点,完成释放锁的工作,以便后面的节点监听到节点的变更通知,获得分布式锁。

ZooKeeper

实现的分布式锁是公平的,且一般也会是可重入的。流程上非常类似AQS的实现,也是CLH的变体,只不过释放锁后节点通知不是本地,而是利用

ZooKeeper

的Watch机制远程通知。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

四、ZooKeeper下载与安装

为了后续的源码学习,体验到最新的功能,这里下载最新版本的

ZooKeeper

(至今最新3.7.0),实际生产中可以安装历史版本。

(安装ZK前,请先安装JDK)

1、下载与安装

https://zookeeper.apache.org/

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)
分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)
分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

复制下载链接,到

Centos

中下载安装。

cd /usr/local/
mkdir zookeeper
cd zookeeper
# 下载
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
# 解压在当前目录
tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz
           

下载的zk安装,解压之后就可以用了:

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)
# 修改解压之后的目录名称(也可以不修改)
mv apache-zookeeper-3.7.0-bin apache-zookeeper-3.7.0
cd apache-zookeeper-3.7.0
# data/zoo用于存储zk数据
mkdir -p data/zoo
# 修改zoo_sample.cfg 为zoo.cfg,因为bin/zkServer.sh默认用的是zoo.cfg
mv conf/zoo_sample.cfg  conf/zoo.cfg
# 修改zoo.cfg 中的dataDir为/usr/local/zookeeper/apache-zookeeper-3.7.0/data/zoo
# 不能用/tmp 存储zk数据,因为机器会定时清理/tmp目录下的数据
vim conf/zoo.cfg
           
分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)
# 启动,默认使用的conf/zoo.cfg启动,单机版。
bin/zkServer.sh start
           
分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

直接运行

bin/zkServer.sh

,可以看到该命令的使用说明,常用的有

start

status

restart

stop

,还可以在启动时指定配置文件,如:

# 指定配置文件启动,配置文件路径必须放在后面
bin/zkServer.sh start conf/zoo.cfg 
           

2、配置说明

ZooKeeper

的启动配置文件

zoo.cfg

的配置内容说明:

# The number of milliseconds of each tick
# 通信心跳时间,Leader和Follower或者Zookeeper服务器与客户端心跳时间,单位毫秒
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
# Leader和Follower初始连接时能容忍的最多心跳数(tickTime的数量)
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
# Leader和Follower之间通信时间如果超过syncLimit * tickTime,
# Leader认为Follwer死掉,从服务器列表中删除Follwer。
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
# 保存zk数据的目录,默认是/tmp,一般要修改为其他路径,因为Linux系统会定期请求/tmp下的数据
dataDir=/usr/local/zookeeper/apache-zookeeper-3.7.0/data/zoo
# the port at which the clients will connect
# 客户端连接的端口
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
# 最大客户端连接数,默认60
#maxClientCnxns=60
# The number of snapshots to retain in dataDir
# dataDir中保留的快照数量
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
# 自动清除任务运行时间间隔,单位为小时,
# 若设置为 0 则禁用自动清除功能
#autopurge.purgeInterval=1

# zk 指标监控提供者,官方推荐用prometheus普罗米修斯
## Metrics Providers
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
           

zoo.cfg

配置内容最后面是

ZooKeeper

指标数据监控配置,官方推荐用

prometheus

,如果用生产中用

influxdb

存储zk指标数据,本人推荐用Telegraf。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

五、ZooKeeper集群搭建

ZooKeeper

集群中只要有半数以上节点存活,就能正常对外提供服务,所以

Zookeeper

集群一般运行奇数个服务端。由于学习用的Linux只有一台,只能搭建一个伪集群,不过理论上都是一样的。

1、伪集群

搭建

ZooKeeper

集群至少需要同时运行三个zk服务实例,如果其中一个挂了,依然可以正常对外提供服务。

(1)准备myid文件

为三个ZK实例创建数据存储目录。

# 在/usr/local/zookeeper/apache-zookeeper-3.7.0/data目录下
# 创建zoo-1、zoo-2、zoo-3
mkdir data/zoo-1 && mkdir data/zoo-2 && mkdir data/zoo-1
           

为三个目录分别创建

myid

文件,其内容只有一个数字编号,分别为1、2、3。

myid

文件中的编号唯一标识服务节点,用于

Leader

投票选举。

(2)配置zoo-.cfg文件

复制修改三份

zoo.cfg

,分别为

zoo-1.cfg

zoo-2.cfg

zoo-3.cfg

# zoo-1.cfg 
# 没有显示的配置项和zoo.cfg一致
dataDir=/usr/local/zookeeper/apache-zookeeper-3.7.0/data/zoo-1
clientPort=2191

server.1 = 127.0.0.1:2888:3888
server.2 = 127.0.0.1:2889:3889
server.3 = 127.0.0.1:2890:3890
           
# zoo-2.cfg 
# 没有显示的配置项和zoo.cfg一致
dataDir=/usr/local/zookeeper/apache-zookeeper-3.7.0/data/zoo-2
clientPort=2192

server.1 = 127.0.0.1:2888:3888
server.2 = 127.0.0.1:2889:3889
server.3 = 127.0.0.1:2890:3890
           
# zoo-3.cfg 
# 没有显示的配置项和zoo.cfg一致
dataDir=/usr/local/zookeeper/apache-zookeeper-3.7.0/data/zoo-3
clientPort=2193

server.1 = 127.0.0.1:2888:3888
server.2 = 127.0.0.1:2889:3889
server.3 = 127.0.0.1:2890:3890
           

由于三个伪实例在一台机器上运行,所以

clientPort

不一样,实际生产中三个zk实例会运行在不同机器上,

clientPort

建议一致(2181)。

每个配置中都有相同的三行配置,表示这是一个集群关系配置:

server.A=B:C:D
           
  • A是一个数字,就是每个zk实例的myid文件中的编号。
  • B是ip地址,每个zk实例所在的机器ip。
  • C是集群中

    Leader

    Follower

    通信的端口,如

    Leader

    Follower

    发送同步写指令,

    Follower

    将写请求转发给

    Leader

    。(通信端口)
  • D是集群中用于投票选举Leader的端口。(选举端口)

实际生产中,不同的zk实例运行在不同机器上,所以通信端口和选举端口各需要一个即可。

2、集群启动第一次Leader选举

依次执行如下命令,启动集群:

# 在/usr/local/zookeeper/apache-zookeeper-3.7.0目录下
bin/zkServer.sh start conf/zoo-1.cfg
bin/zkServer.sh start conf/zoo-2.cfg
bin/zkServer.sh start conf/zoo-3.cfg
           

为了看清楚三个zk实例启动时的

Leader

选举过程,特意在每次

start

之后穿插

status

  • 启动

    zoo-1

    时,发起一次投票,

    zoo-1

    给自己投一票,此时服务实例不够半数以上,无法对外提供服务。

    status

    显示

    Error contacting service

  • 启动

    zoo-2

    时,再发起一次投票,

    status

    显示

    zoo-2

    leader

    ,zoo-1显示

    follower

    ,说明

    zoo-2

    给自己投了一票,

    zoo-1

    也给

    zoo-2

    投了一票,服务实例数超过半数,

    leader

    选举完成,此时可以对外提供服务。
  • 启动

    zoo-3

    时,

    status

    显示

    zoo-3

    follower

    。说明后来者

    zoo-3

    把选票投给了已经当上了

    leader

    zoo-2

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

调整启动顺序,

zoo-2

zoo-1

zoo-3

leader依然是zoo-2。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

zoo-3

放在前两次启动,

leader

就是

zoo-3

,最后启动实例都是

Follower

(演示省略),可得出结论:

  • myid

    小的投票给

    myid

    大的实例。
  • 已经完成

    leader

    选举后,后来者会直接把选票投给现任

    leader

    ,自己甘为

    Follower

(leader投票选举的更多细节还需要后续看了源码才知道。)

3、模拟服务实例宕机leader重选

Follower

实例宕机,只要集群实例个数在半数以上,依然可以对外提供服务,

leader

的地位也不会动摇,只有当身为

leader

的实例宕机了,此时就需要重新投票选

leader

此时

leader

zoo-2

,将其

stop

,再次查看

zoo-1

zoo-3

的状态,

zoo-3

变成了

leader

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

(更多leader重选细节还需后续看了源码才知道。)

4、编写集群批量启动脚本

集群中每个实例手动一个个执行启动命令,确实比较麻烦,特编写一个批量启动脚本,如果多实例运行在不同机器上,可改成ssh的方式:

#!/bin/bash
case $1 in
"start"){
for i in zoo-1.cfg  zoo-2.cfg zoo-3.cfg
do
 echo ---------- zookeeper $i 启动 ------------
/usr/local/zookeeper/apache-zookeeper-3.7.0/bin/zkServer.sh start /usr/local/zookeeper/apache-zookeeper-3.7.0/conf/$i 
done
};;
"stop"){
for i in zoo-1.cfg  zoo-2.cfg zoo-3.cfg
do
 echo ---------- zookeeper $i 停止 ------------
/usr/local/zookeeper/apache-zookeeper-3.7.0/bin/zkServer.sh stop /usr/local/zookeeper/apache-zookeeper-3.7.0/conf/$i 
done
};;
"restart"){
for i in zoo-1.cfg  zoo-2.cfg zoo-3.cfg
do
 echo ---------- zookeeper $i 重启 ------------
/usr/local/zookeeper/apache-zookeeper-3.7.0/bin/zkServer.sh restart /usr/local/zookeeper/apache-zookeeper-3.7.0/conf/$i 
done
};;
"status"){
for i in zoo-1.cfg  zoo-2.cfg zoo-3.cfg
do
 echo ---------- zookeeper $i 状态 ------------
/usr/local/zookeeper/apache-zookeeper-3.7.0/bin/zkServer.sh status /usr/local/zookeeper/apache-zookeeper-3.7.0/conf/$i 
done
};;
esac
           
分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

六、要点回顾

ZooKeeper

集群搭建好了,就该用客户端连接上集群进行操作了,后续篇章会对客户端操作做详细讲解。

本篇总结如下:

  1. Zookeeper

    有两个核心设计:

    Watch

    机制和

    ZAB

    一致性算法。基于此,

    Zookeeper

    成为很多分布式系统的基石。
  2. Zookeeper

    放弃可用性A,保证CP。数据全局强一致性,并且能在几秒内快速同步,具有不错的实时性体验。
  3. Zookeeper

    数据结构是类UNIX文件系统目录的树状结构,每个

    ZNode

    通过其路径(Path)唯一标识,每个

    ZNode

    可以存储少量二进制数据,默认最大为1MB。
  4. ZNode

    有四种类型:持久节点(配置中心,注册中心)、临时节点(服务上下线感知)、时序节点(分布式ID)、临时时序节点(分布式锁)。
  5. Zookeeper

    的典型的应用场景:配置中心,命名服务,服务注册中心,服务上下线感知,集群通信与控制系统,分布式锁等。
  6. leader

    选举没有完成前,选票会投给

    myid

    较大的实例,选举完成后,后来启动的实例会将选票直接投给现任

    leader

    ,自己为

    Follower

后续会通过看

ZooKeeper

源码,更深层次的剖析其实现原理。

分布式系统的基石之ZooKeeper——基本原理+场景应用+集群搭建(最强万字入门指南)

七、参考文献

书籍:《架构解密:从分布式到微服务(第2版)》吴治辉著 -2.3分布式系统的基石之ZooKeeper。

书籍:《Netty、Redis、ZooKeeper高并发实战》尼恩著 -第10章 ZooKeeper分布式协调。

如若文章有错误理解,欢迎批评指正,同时非常期待你的留言和点赞。如果觉得有用,不妨来个一键三连,让更多人受益。