一、zookeeper容错机制?
Zookeeper在集群环境下采用了两种容错机制,分别是主备模式和选举机制。
主备模式通过备节点监控主节点状态,一旦主节点出现故障,备节点能够快速切换成为主节点,保障系统的高可用性。
选举机制则是通过Zab协议实现的,当主节点出现宕机时,剩余节点会通过选举机制重新选择一个节点成为新的主节点。
这种机制能够避免因节点故障导致的数据不一致,保证Zookeeper服务的可靠性。
二、zookeeper启动失败?
查看zookeeper.out,是否有错误信息。错误信息并不一定输出到屏幕上。
今天我师妹也遇到了这个问题,我执行jps,发现zookeeper并没有启动,于是检查了下.out文件发现是配置文件错误。
三、zookeeper是什么?
zookeeper是一款以三国为背景打造的全新游戏软件,zookeeper这款软件游戏爽快刺激的竞技玩法,玩家可以和众多三国英雄们一起享受一场独特的战斗,为了争夺神州大地,玩家需要不断击败强大的对手赢得胜利,丰富精彩的游戏内容等等。
四、zookeeper端口号
随着互联网的快速发展,越来越多的应用程序需要依赖于分布式系统来处理海量的数据和请求。为了确保分布式系统的可靠运行,有必要引入分布式协调服务,比如Apache ZooKeeper这样的工具,它可以帮助我们管理和监控分布式环境中的各种资源。
什么是Apache ZooKeeper?
Apache ZooKeeper是一个开源的分布式协调服务,它可以提供高可用性和一致性的分布式应用程序协调服务。ZooKeeper的最重要特性之一是它的简单性和可靠性。它提供了一个层次化的命名空间,类似于文件系统,用于存储和管理分布式系统中的数据。ZooKeeper还通过内置的原语(例如锁和同步)来实现高效的分布式协作。
ZooKeeper的端口号
ZooKeeper通过特定的端口号与客户端和其他ZooKeeper实例进行通信。这些端口号对于ZooKeeper实例的运行非常重要。默认情况下,ZooKeeper使用的端口号是2181。
端口2181被用于客户端与ZooKeeper服务器之间的通信。通过此端口,客户端可以连接到ZooKeeper服务器,并发送操作指令。此外,ZooKeeper还使用2888和3888端口进行服务器之间的通信,用于选举Leader和集群间的数据复制。
如何配置ZooKeeper的端口号?
要配置ZooKeeper的端口号,您需要编辑ZooKeeper的配置文件(通常为zoo.cfg
)。在配置文件中,您可以找到以下两个重要的参数:
- clientPort:这是用于客户端与ZooKeeper服务器通信的端口号。默认值是
2181
。 - initLimit和syncLimit:这些参数用于配置ZooKeeper服务器之间的通信端口号。
要更改端口号,您只需修改相应参数的值,并重新启动ZooKeeper服务器以使更改生效。
为什么要修改ZooKeeper的端口号?
在某些情况下,您可能需要修改ZooKeeper的端口号。一种常见的情况是由于与其他应用程序的冲突,您需要将ZooKeeper的端口号更改为未被占用的端口。此外,为了增强系统的安全性,您可能还想修改ZooKeeper的端口号,以便更难以被外部攻击者访问。
注意事项
在修改ZooKeeper的端口号之前,有几点需要注意:
- 确保新的端口号不会与其他应用程序使用的端口号发生冲突。
- 所有ZooKeeper实例的端口号必须保持一致,以确保它们能够协作正常。
- 在修改端口号之后,确保更新所有相关的配置文件和客户端代码。
总结
Apache ZooKeeper是一个强大的分布式协调服务,它可以帮助我们管理和监控分布式环境中的各种资源。ZooKeeper使用特定的端口号来与客户端和其他实例进行通信,其中默认端口号是2181。如果需要修改ZooKeeper的端口号,您可以通过编辑配置文件来实现,并确保所有实例的端口号保持一致。在修改端口号之前,请确保遵循相关的注意事项。通过合理配置端口号,可以确保ZooKeeper正常运行并提高系统的可靠性和安全性。
五、zookeeper 端口号
当你安装和配置ZooKeeper时,你可能需要了解ZooKeeper使用的默认端口号以及在需要时如何进行更改。ZooKeeper是一个分布式协调服务,用于管理和协调分布式系统中的各个节点,因此在网络通信中使用了一些端口号来进行通信。
默认端口号
在ZooKeeper中,默认情况下会使用以下端口号:
- 2181: 这是ZooKeeper客户端与ZooKeeper服务器之间的通信端口。几乎所有的ZooKeeper客户端应用程序都使用这个端口来连接和与ZooKeeper交互。
- 2888: 这是ZooKeeper服务器之间进行选举的端口号。当一个ZooKeeper服务器从Leader状态切换到Follower状态时,它将使用该端口号来与其他服务器进行通信。
- 3888: 这是ZooKeeper服务器之间进行Leader选举时使用的端口。一个服务器在刚启动时,它会监听这个端口来接收其他服务器发来的选举通知。
更改端口号
在某些情况下,你可能希望更改ZooKeeper使用的端口号,以满足特定的需求。例如,如果你不希望使用默认的端口号,或者因为端口冲突而需要更换端口。
要更改ZooKeeper的端口号,你需要编辑ZooKeeper的配置文件zoo.cfg
。找到以下配置项并修改为你希望使用的端口号:
clientPort=2181
initLimit=5
syncLimit=2
server.1=zookeeper1.example.com:2888:3888
server.2=zookeeper2.example.com:2888:3888
server.3=zookeeper3.example.com:2888:3888
clientPort 指定了ZooKeeper客户端与服务器之间的通信端口。你可以将其修改为你希望使用的端口号。
server.X 是ZooKeeper服务器配置的一部分。在这个配置项中,X 代表服务器的标识号。你可以根据你的服务器数量和配置来添加或移除这些配置项。X 后面的值是服务器的主机名或IP地址,后面的两个数字分别表示选举通信端口和Leader选举通信端口。
一旦你修改了配置文件并保存,你需要重新启动ZooKeeper服务器以使更改生效。
常见问题
在更改ZooKeeper的端口号时,可能会遇到一些常见的问题:
- 端口冲突: 如果你将端口号更改为已被其他应用程序使用的端口,可能会导致端口冲突。在修改端口号时,请确保没有其他应用程序正在使用该端口。
- 防火墙配置: 如果你正在使用防火墙,需要确保ZooKeeper的新端口号已经在防火墙规则中开放。
- 网络通信异常: 更改端口号可能会导致与其他组件或客户端之间的通信异常。在更改端口号后,请确保与其他组件的通信正常。
总结
ZooKeeper使用一些默认的端口号来进行分布式协调和通信。在特定情况下,你可以更改这些端口号以满足你的需求。通过编辑ZooKeeper的配置文件,你可以修改客户端通信端口、选举通信端口和Leader选举通信端口。在更改端口号时,请注意端口冲突、防火墙配置和网络通信异常等问题。
六、centos安装zookeeper
CentOS安装ZooKeeper
在大型分布式系统中,ZooKeeper是一个关键的应用程序,主要用于协调和管理服务。在本文中,我们将讨论如何在CentOS上安装ZooKeeper。ZooKeeper具有高可用性和可靠性的特点,可以确保系统的稳定性和一致性。
步骤一:准备工作
在开始安装ZooKeeper之前,我们首先需要确保系统已经具备一些必要的条件。请按照以下步骤进行设置:
- 确保系统已经安装了Java环境,可以通过java -version命令来检查Java的版本。
- 安装并配置好相关的网络连接,确保可以访问ZooKeeper的安装包。
步骤二:下载ZooKeeper安装包
在安装ZooKeeper之前,我们需要从官方网站下载最新版本的ZooKeeper安装包。可以通过以下命令来下载:
wget y.com/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz步骤三:解压安装包
下载完成后,使用以下命令解压ZooKeeper安装包:
tar -zxf apache-zookeeper-3.6.3-bin.tar.gz
步骤四:配置ZooKeeper
在解压安装包后,我们需要对ZooKeeper进行一些配置。首先,创建一个ZooKeeper配置文件zoo.cfg:
cp apache-zookeeper-3.6.3-bin/conf/zoo_sample.cfg apache-zookeeper-3.6.3-bin/conf/zoo.cfg
然后,编辑zoo.cfg文件,配置ZooKeeper的相关参数,包括数据目录、日志目录等。
步骤五:启动ZooKeeper
完成配置后,我们可以启动ZooKeeper服务。使用以下命令启动ZooKeeper:
./apache-zookeeper-3.6.3-bin/bin/zkServer.sh start
可以使用zkServer.sh status来检查ZooKeeper的运行状态。
步骤六:连接ZooKeeper
一旦ZooKeeper启动成功,我们就可以通过ZooKeeper客户端连接到ZooKeeper服务器。使用以下命令连接:
./apache-zookeeper-3.6.3-bin/bin/zkCli.sh -server localhost:2181
在连接成功后,您可以执行各种ZooKeeper命令,如创建节点、设置数据等。
结束语
通过以上步骤,您已经成功在CentOS上安装和配置了ZooKeeper。ZooKeeper作为分布式系统中的关键组件,对于系统的稳定性和一致性具有重要意义。希望本文对您有所帮助,谢谢阅读!
七、centos zookeeper 安装
CentOS系统下Zookeeper安装详解
在大型分布式系统中,Zookeeper作为一个关键的组件,扮演着协调、配置管理和分布式锁管理的重要角色。本文将详细介绍在CentOS系统下如何进行Zookeeper的安装配置。
1. 下载Zookeeper
首先,我们需要从Zookeeper官方网站上下载最新的稳定版本。可以通过以下命令获取下载链接:
curl -L -O zookeeper/zookeeper-3.6.3/zookeeper-3.6.3.tar.gz
2. 解压安装包
下载完成后,我们需要将压缩包解压到指定目录。执行如下命令:
tar -zxf zookeeper-3.6.3.tar.gz -C /opt
3. 配置环境变量
为了方便使用Zookeeper,我们需要配置环境变量。在/etc/profile
文件中添加以下内容:
export ZOOKEEPER_HOME=/opt/zookeeper-3.6.3
export PATH=$ZOOKEEPER_HOME/bin:$PATH
保存并执行source /etc/profile
命令使配置生效。
4. 配置Zookeeper
接下来,我们需要对Zookeeper进行基本配置。在Zookeeper安装目录下的conf
文件夹中,复制zoo_sample.cfg
为zoo.cfg
:
cp $ZOOKEEPER_HOME/conf/zoo_sample.cfg $ZOOKEEPER_HOME/conf/zoo.cfg
编辑zoo.cfg
文件,设定Zookeeper相关配置参数,如集群节点信息、数据目录等。
5. 启动Zookeeper
配置完成后,我们即可启动Zookeeper服务。执行以下命令:
zkServer.sh start
可以通过zkServer.sh status
命令检查Zookeeper的运行状态。
6. 验证安装
最后,我们可以通过连接Zookeeper客户端,验证安装是否成功。执行以下命令:
zkCli.sh -server localhost:2181
若成功连接到Zookeeper服务,则说明安装配置已完成。
总结
本文介绍了在CentOS系统下安装Zookeeper的详细步骤,从下载到配置再到验证,希望能够对读者有所帮助。Zookeeper作为分布式系统中的重要组件,合理的安装配置对系统的稳定运行至关重要。
八、centos zookeeper集群
CentOS 搭建 Zookeeper 集群详细步骤
在搭建 Zookeeper 集群之前,首先要确保已经安装了 CentOS 操作系统并配置了相应的网络环境。Zookeeper 是一个分布式的开源协调服务,常用于大型分布式系统中,如 Hadoop、Kafka 等。搭建 Zookeeper 集群可以提高系统的可靠性和稳定性。
步骤一:安装 Java JDK
首先需要在 CentOS 服务器上安装 Java JDK,Zookeeper 是基于 Java 开发的。可以通过以下命令进行安装:
yum install java-11-openjdk-devel
安装完成后,可以通过以下命令验证 Java JDK 是否安装成功:
java -version
步骤二:下载并解压 Zookeeper
在官方网站上下载最新版本的 Zookeeper,并解压到指定目录:
tar -zxf zookeeper-3.7.0.tar.gz -C /opt/
步骤三:配置 Zookeeper 集群
在每台服务器上的 Zookeeper 配置文件中进行如下配置:
- 配置 zoo.cfg 文件:
- 编辑 zoo.cfg 文件,设置集群节点信息:
cp /opt/zookeeper-3.7.0/conf/zoo_sample.cfg /opt/zookeeper-3.7.0/conf/zoo.cfg
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888
步骤四:启动 Zookeeper 集群
在每台服务器上启动 Zookeeper 服务:
/opt/zookeeper-3.7.0/bin/zkServer.sh start
可以使用以下命令检查 Zookeeper 服务的状态:
/opt/zookeeper-3.7.0/bin/zkServer.sh status
步骤五:验证 Zookeeper 集群
通过客户端连接到 Zookeeper 集群,并验证节点信息:
/opt/zookeeper-3.7.0/bin/zkCli.sh -server node1:2181
在 Zookeeper 命令行界面中,可以执行以下命令验证集群状态:
ls /
如果能够成功列出 Zookeeper 根节点信息,则表明搭建的集群运行正常。
总结
通过以上步骤,您已经成功搭建了一个基于 CentOS 的 Zookeeper 集群。在生产环境中,可以根据实际需求搭建更大规模的集群来支持系统的高可用性和扩展性。Zookeeper 的稳定运行对于分布式系统的正常运行至关重要,希望以上内容对您有所帮助。
九、zookeeper 基本特性?
来看看你会做几道
本系列《最少必要面试题》
- 1. 什么是 Zookeeper
- 2. ZK 的节点类型
- 3. Zookeeper 下 Server 工作状态有哪些?
- 4. zookeeper是cp还是ap?
- 5. 说几个 zookeeper 常用的命令。
- 6. 介绍一下ZAB协议?
- 7. ZAB 和 Paxos 算法的联系与区别?
- 8. Zookeeper 的典型应用场景
- 9. Chroot特性
- 拓展
1. 什么是 Zookeeper
ZooKeeper 是一个开源的分布式协调服务。它是一个为分布式应用提供一致性服务的软件,分布式应用程序可以基于 Zookeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
Zookeeper 从设计模式角度来理解, 是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出反应。
观察者模式是什么:设计模式
可以这样理解:
ZooKeeper=文件系统+通知机制
2. ZK 的节点类型
这道题相信大家都有所了解,zookeeper v3.6.2 版本后,支持7种节点类型。持久;持久顺序;临时;临时顺序;容器;持久 TTL;持久顺序 TTL。
说出这几种类型当然已经回答了问题,但是细节的描述更能体现你的知识底蕴。
持久 TTL、持久顺序 TTL
关于持久和顺序这两个关键字,不用我再解释了,这两种类型的节点重点是后面的 TTL,TTL 是 time to live 的缩写,指带有存活时间,简单来说就是当该节点下面没有子节点的话,超过了 TTL 指定时间后就会被自动删除,但是 TTL 启用是需要额外的配置(这个之前也有提过)配置是 zookeeper.extendedTypesEnabled 需要配置成 true,否则的话创建 TTL 时会收到 Unimplemented 的报错。
3. Zookeeper 下 Server 工作状态有哪些?
服务器具有四种状态,分别是 LOOKING、FOLLOWING、LEADING、OBSERVING。
- LOOKING:寻 找 Leader 状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入 Leader 选举状态。
- FOLLOWING:跟随者状态。表明当前服务器角色是 Follower。
- LEADING:领导者状态。表明当前服务器角色是 Leader。
- OBSERVING:观察者状态。表明当前服务器角色是 Observer。(Observer角色除了不能投票(以及和投票相关的能力)和过半写成功策略外,其它和follower功能一样。observer角色减轻了投票的压力,在以前通过增、减follower的数量提高伸缩性。投票来说,follower是有状态的,都直接影响投票结果,特别是follower的数量越多,投票过程的性能就越差。)
4. zookeeper是cp还是ap?
zk遵循的是CP原则,即保证一致性和网络分区容错性,但不保证可用性。
什么是cap?
Consistency(一致性):分布式系统中多个主机之间是否能够保持数据一致性的特性。即当系统数据发生更新操作之后,各个主机中的数据是否仍然处于一致的状态。
Availability(可用性):系统提供的服务必须一直处于可用的状态,即对于的每一个请求,系统总是可以在有限的时间内对用户做出响应。
Partition tolerance(分区容错性):分布式系统在遇到任何网络分区故障时候,仍然保证对外提供满足一致性和可用性的服务。
5. 说几个 zookeeper 常用的命令。
常用命令:ls get set create delete 等。
6. 介绍一下ZAB协议?
ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。
ZAB协议包括两种基本的模式:
- 崩溃恢复
- 消息广播
当整个 zookeeper 集群刚刚启动或者Leader服务器宕机、重启或者网络故障导致不存在过半的服务器与 Leader 服务器保持正常通信时,所有进程(服务器)进入崩溃恢复模式,首先选举产生新的 Leader 服务器,然后集群中 Follower 服务器开始与新的 Leader 服务器进行数据同步,当集群中超过半数机器与该 Leader 服务器完成数据同步之后,退出恢复模式进入消息广播模式,Leader 服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。
7. ZAB 和 Paxos 算法的联系与区别?
相同点:
- 两者都存在一个类似于 Leader 进程的角色,由其负责协调多个 Follower 进程的运行
- Leader 进程都会等待超过半数的 Follower 做出正确的反馈后,才会将一个提案进行提交
- ZAB 协议中,每个 Proposal 中都包含一个 epoch 值来代表当前的 Leader 周期,Paxos 中名字为 Ballot
不同点:
ZAB(ZooKeeper Atomic Broadcast) 用来构建高可用的分布式数据主备系统(Zookeeper),Paxos 是用来构建分布式一致性状态机系统。
而 Paxos 算法与 ZAB 协议不同的是,Paxos 算法的发起者可以是一个或多个。当集群中的 Acceptor 服务器中的大多数可以执行会话请求后,提议者服务器只负责发送提交指令,事务的执行实际发生在 Acceptor 服务器。这与 ZooKeeper 服务器上事务的执行发生在 Leader 服务器上不同。Paxos 算法在数据同步阶段,是多台 Acceptor 服务器作为数据源同步给集群中的多台 Learner 服务器,而 ZooKeeper 则是单台 Leader 服务器作为数据源同步给集群中的其他角色服务器。
注意:
ZAB是在Paxos的基础上改进和演变过来的。
提议者(Proposer)、决策者(Acceptor)、决策学习者(Learner)
8. Zookeeper 的典型应用场景
- 数据发布/订阅
- 负载均衡
- 命名服务
- 分布式协调/通知
- 集群管理
- Master 选举
- 分布式锁
- 分布式队列
数据发布/订阅系统,即所谓的配置中心,目的:动态获取数据(配置信息),实现数据(配置信息)的集中式管理和数据的动态更新
Zookeeper 分布式锁
有了 zookeeper 的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
对于第一类,我们将 zookeeper 上的一个 znode 看作是一把锁,通过 createznode的方式来实现。所有客户端都去创建 /task_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的 task_lock 节点就释放出锁。
对于第二类, /task_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选 master 一样,编号最小的获得锁,用完删除,依次方便。
Zookeeper 队列管理
一般很少用到,可简单了解
两种类型的队列:
- 同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
- 队列按照 FIFO 方式进行入队和出队操作。
第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下创建 PERSISTENT_SEQUENTIAL 节点,创建成功时Watcher 通知等待的队列,队列删除序列号最小的节点用以消费。此场景下Zookeeper 的 znode 用于消息存储,znode 存储的数据就是消息队列中的消息内容,SEQUENTIAL 序列号就是消息的编号,按序取出即可。由于创建的节点是持久化的,所以不必担心队列消息的丢失问题。
9. Chroot特性
zookeeper v3.2.0 版本后,添加了 Chroot 特性,该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot,那么该客户端对服务器的任何操作,都将会被限制在其自己的命名空间下。
通过设置 Chroot,能够将一个客户端应用于 Zookeeper 服务端的一颗子树相对应,在那些多个应用共用一个 Zookeeper 进群的场景下,对实现不同应用间的相互隔离非常有帮助。
拓展
ZooKeeper以Fast Paxos算法为基础,Paxos 算法存在活锁的问题,即当有多个 proposer 交错提交时有可能互相排斥导致没有一个proposer能提交成功,而Fast Paxos做了一些优化,通过选举产生一个领导者,只有leader才能提交proposer具体算法可见Fast Paxos。
低谷蓄力
10道不得不会的Java基础面试题
10道不得不会的Java并发基础面试题
10道不得不会的JavaEE面试题
10道不得不会的JVM面试题
10道不得不会的MySQL基础面试题
10道不得不会的MyBatis面试题
10道不得不会的Spring面试题
10道不得不会的ElasticSearch面试题
10道不得不会的Redis面试题
10道不得不会的Kafka面试题
10道不得不会的Zookeeper面试题
10道不得不会的Docker面试题
看到这里了,不点个关注 @JavaPub
十、关于zookeeper原理是?
ZooKeeper简介
ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。
ZooKeeper设计目的
- 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
- 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。
- 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
- 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
- 原子性:更新只能成功或者失败,没有中间状态。
- 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
ZooKeeper数据模型
Zookeeper会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统,如图所示:
Zookeeper这种数据结构有如下这些特点:
1)每个子目录项如NameService都被称作为znode,这个znode是被它所在的路径唯一标识,如Server1这个znode的标识为/NameService/Server1。
2)znode可以有子节点目录,并且每个znode可以存储数据,注意EPHEMERAL(临时的)类型的目录节点不能有子节点目录。
3)znode是有版本的(version),每个znode中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据,version号自动增加。
4)znode的类型:
- Persistent 节点,一旦被创建,便不会意外丢失,即使服务器全部重启也依然存在。每个 Persist 节点即可包含数据,也可包含子节点。
- Ephemeral 节点,在创建它的客户端与服务器间的 Session 结束时自动被删除。服务器重启会导致 Session 结束,因此 Ephemeral 类型的 znode 此时也会自动删除。
- Non-sequence 节点,多个客户端同时创建同一 Non-sequence 节点时,只有一个可创建成功,其它匀失败。并且创建出的节点名称与创建时指定的节点名完全一样。
- Sequence 节点,创建出的节点名在指定的名称之后带有10位10进制数的序号。多个客户端创建同一名称的节点时,都能创建成功,只是序号不同。
5)znode可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是Zookeeper的核心特性,Zookeeper的很多功能都是基于这个特性实现的。
6)ZXID:每次对Zookeeper的状态的改变都会产生一个zxid(ZooKeeper Transaction Id),zxid是全局有序的,如果zxid1小于zxid2,则zxid1在zxid2之前发生。
ZooKeeper Session
Client和Zookeeper集群建立连接,整个session状态变化如图所示:
如果Client因为Timeout和Zookeeper Server失去连接,client处在CONNECTING状态,会自动尝试再去连接Server,如果在session有效期内再次成功连接到某个Server,则回到CONNECTED状态。
注意:如果因为网络状态不好,client和Server失去联系,client会停留在当前状态,会尝试主动再次连接Zookeeper Server。client不能宣称自己的session expired,session expired是由Zookeeper Server来决定的,client可以选择自己主动关闭session。
ZooKeeper Watch
Zookeeper watch是一种监听通知机制。Zookeeper所有的读操作getData(), getChildren()和 exists()都可以设置监视(watch),监视事件可以理解为一次性的触发器
官方定义如下:
a watch event is one-time trigger, sent to the client that set the watch, whichoccurs when the data for which the watch was set changes。
Watch的三个关键点:
(一次性触发)One-time trigger
当设置监视的数据发生改变时,该监视事件会被发送到客户端,例如,如果客户端调用了getData("/znode1", true) 并且稍后 /znode1 节点上的数据发生了改变或者被删除了,客户端将会获取到 /znode1 发生变化的监视事件,而如果 /znode1 再一次发生了变化,除非客户端再次对/znode1 设置监视,否则客户端不会收到事件通知。
(发送至客户端)Sent to the client
Zookeeper客户端和服务端是通过 socket 进行通信的,由于网络存在故障,所以监视事件很有可能不会成功地到达客户端,监视事件是异步发送至监视者的,Zookeeper 本身提供了顺序保证(ordering guarantee):即客户端只有首先看到了监视事件后,才会感知到它所设置监视的znode发生了变化(a client will never see a change for which it has set a watch until it first sees the watch event)。
网络延迟或者其他因素可能导致不同的客户端在不同的时刻感知某一监视事件,但是不同的客户端所看到的一切具有一致的顺序。
(被设置 watch 的数据)The data for which the watch was set
这意味着znode节点本身具有不同的改变方式。你也可以想象 Zookeeper 维护了两条监视链表:数据监视和子节点监视(data watches and child watches) getData() 和exists()设置数据监视,getChildren()设置子节点监视。或者你也可以想象 Zookeeper 设置的不同监视返回不同的数据,getData() 和 exists() 返回znode节点的相关信息,而getChildren() 返回子节点列表。
因此,setData() 会触发设置在某一节点上所设置的数据监视(假定数据设置成功),而一次成功的create() 操作则会出发当前节点上所设置的数据监视以及父节点的子节点监视。一次成功的 delete操作将会触发当前节点的数据监视和子节点监视事件,同时也会触发该节点父节点的child watch。
Zookeeper 中的监视是轻量级的,因此容易设置、维护和分发。当客户端与 Zookeeper 服务器失去联系时,客户端并不会收到监视事件的通知,只有当客户端重新连接后,若在必要的情况下,以前注册的监视会重新被注册并触发,对于开发人员来说这通常是透明的。
只有一种情况会导致监视事件的丢失,即:通过exists()设置了某个znode节点的监视,但是如果某个客户端在此znode节点被创建和删除的时间间隔内与zookeeper服务器失去了联系,该客户端即使稍后重新连接 zookeeper服务器后也得不到事件通知。
Consistency Guarantees
Zookeeper是一个高效的、可扩展的服务,read和write操作都被设计为快速的,read比write操作更快。
- 顺序一致性(Sequential Consistency):从一个客户端来的更新请求会被顺序执行。
- 原子性(Atomicity):更新要么成功要么失败,没有部分成功的情况。
- 唯一的系统镜像(Single System Image):无论客户端连接到哪个Server,看到系统镜像是一致的。
- 可靠性(Reliability):更新一旦有效,持续有效,直到被覆盖。
- 时间线(Timeliness):保证在一定的时间内各个客户端看到的系统信息是一致的。
ZooKeeper的工作原理
在zookeeper的集群中,各个节点共有下面3种角色和4种状态:
- 角色:leader,follower,observer
- 状态:leading,following,observing,looking
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议(ZooKeeper Atomic Broadcast protocol)。Zab协议有两种模式,它们分别是恢复模式(Recovery选主)和广播模式(Broadcast同步)。
当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。
实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
每个Server在工作过程中有4种状态:
- LOOKING:当前Server不知道leader是谁,正在搜寻。
- LEADING:当前Server即为选举出来的leader。
- FOLLOWING:leader已经选举出来,当前Server与之同步。
- OBSERVING:observer的行为在大多数情况下与follower完全一致,但是他们不参加选举和投票,而仅仅接受(observing)选举和投票的结果。
Leader Election
当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。先介绍basic paxos流程:
- 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
- 选举线程首先向所有Server发起一次询问(包括自己);
- 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
- 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
- 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1.
每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。
fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
Leader工作流程
Leader主要有三个功能:
- 恢复数据;
- 维持与follower的心跳,接收follower请求并判断follower的请求消息类型;
- follower的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。
说明:
PING消息是指follower的心跳信息;REQUEST消息是follower发送的提议信息,包括写请求及同步请求; ACK消息是follower的对提议的回复,超过半数的follower通过,则commit该提议; REVALIDATE消息是用来延长SESSION有效时间。
Follower工作流程
Follower主要有四个功能:
- 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
- 接收Leader消息并进行处理;
- 接收Client的请求,如果为写请求,发送给Leader进行投票;
- 返回Client结果。
Follower的消息循环处理如下几种来自Leader的消息:
- PING消息:心跳消息
- PROPOSAL消息:Leader发起的提案,要求Follower投票
- COMMIT消息:服务器端最新一次提案的信息
- UPTODATE消息:表明同步完成
- REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息
- SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
Zab: Broadcasting State Updates
Zookeeper Server接收到一次request,如果是follower,会转发给leader,Leader执行请求并通过Transaction的形式广播这次执行。Zookeeper集群如何决定一个Transaction是否被commit执行?通过“两段提交协议”(a two-phase commit):
- Leader给所有的follower发送一个PROPOSAL消息。
- 一个follower接收到这次PROPOSAL消息,写到磁盘,发送给leader一个ACK消息,告知已经收到。
- 当Leader收到法定人数(quorum)的follower的ACK时候,发送commit消息执行。
Zab协议保证:
- 如果leader以T1和T2的顺序广播,那么所有的Server必须先执行T1,再执行T2。
- 如果任意一个Server以T1、T2的顺序commit执行,其他所有的Server也必须以T1、T2的顺序执行。
“两段提交协议”最大的问题是如果Leader发送了PROPOSAL消息后crash或暂时失去连接,会导致整个集群处在一种不确定的状态(follower不知道该放弃这次提交还是执行提交)。Zookeeper这时会选出新的leader,请求处理也会移到新的leader上,不同的leader由不同的epoch标识。切换Leader时,需要解决下面两个问题:
1. Never forget delivered messages
Leader在COMMIT投递到任何一台follower之前crash,只有它自己commit了。新Leader必须保证这个事务也必须commit。
2. Let go of messages that are skipped
Leader产生某个proposal,但是在crash之前,没有follower看到这个proposal。该server恢复时,必须丢弃这个proposal。
Zookeeper会尽量保证不会同时有2个活动的Leader,因为2个不同的Leader会导致集群处在一种不一致的状态,所以Zab协议同时保证:
- 在新的leader广播Transaction之前,先前Leader commit的Transaction都会先执行。
- 在任意时刻,都不会有2个Server同时有法定人数(quorum)的支持者。 这里的quorum是一半以上的Server数目,确切的说是有投票权力的Server(不包括Observer)。
总结
简单介绍了Zookeeper的基本原理,数据模型,Session,Watch机制,一致性保证,Leader Election,Leader和Follower的工作流程和Zab协议。
参考
《ZooKeeper—Distributed Process Coordination》 by FlavioJunqueira and Benjamin Reed http://zookeeper.apache.org/doc/trunk/zookeeperOver.html http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html 《ZooKeeper的一致性算法赏析》https://my.oschina.net/pingpangkuangmo/blog/778927
作者:阿凡卢来源:ZooKeeper的原理是什么?
关注我 @Java编程宇宙,学习更多 Java 知识
100 道 Java 面试题汇总 PDF 下载(含答案解析和思维导图)