当前位置: 首页 > news >正文

分布式开源协调服务之zookeeper

 Zookeeper简介

Zookeeper是什么?

        Zookeeper官网中对Zookeeper的定义还是比较明确的:

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications. Each time they are implemented there is a lot of work that goes into fixing the bugs and race conditions that are inevitable. Because of the difficulty of implementing these kinds of services, applications initially usually skimp on them ,which make them brittle in the presence of change and difficult to manage. Even when done correctly, different implementations of these services lead to management complexity when the applications are deployed.

        简单地说,Zookeeper作为一个协调管理者被用在分布式系统中。管理什么呢?分布式系统是由多个系统组成的,系统之间涉及的配置信息管理,命名规范,系统之间的信息同步,以及组服务等,这些工作肯定放在统一的管理平台上,来管理会更加顺畅一些。Zookeeper就是负责这些工作的一个管理平台。

        简单来说,ZooKeeper是一个开源的分布式服务框架,为分布式应用提供协调服务,用来解决分布式应用中的数据管理问题,如:配置管理、命名服务分布式同步、集群管理等

一、概念:

分布式

        将一个大型应用的不同业务部署在不同的服务器上,解决高并发的问题

集群

        将同一个业务部署在多台服务器上,提高系统的高可用性

        ZooKeeper 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心(服务注册与发现中心)。

        服务生产者将自己提供的服务注册到 ZooKeeper 中心,服务的消费者在进行服务调用的时候先到 ZooKeeper 中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据。

二、ZooKeeper的由来

ZooKeeper译名为“动物园管理员”。

          Zookeeper 最早起源于雅虎研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型系统基本都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点问题。

        所以,雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在处理业务逻辑上。

        关于“ZooKeeper”这个项目的名字,其实也有一段趣闻。在立项初期,考虑到之前内部很多项目都是使用动物的名字来命名的(例如著名的Pig项目),雅虎的工程师希望给这个项目也取一个动物的名字。

        时任研究院的首席科学家 Raghu Ramakrishnan 开玩笑地说:“再这样下去,我们这儿就变成动物园了!”

        此话一出,大家纷纷表示就叫动物园管理员吧,因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看上去就像一个大型的动物园了。

        而 Zookeeper 正好要用来进行分布式环境的协调,于是,Zookeeper 的名字也就由此诞生了。

        分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

三、基本概念

        本章将介绍 ZooKeeper 的几个核心概念。这些概念贯穿于之后对 ZooKeeper 更深入的讲解,因此有必要预先了解这些概念。

(一)集群角色

1、在 ZooKeeper 中,有三种角色:

        l领导者(leader),负责进行投票的发起和决议,更新系统状态

        l学习者(learner),包括跟随者(follower [ˈfɑːloʊər])和观察者(observer  [əbˈzɜːrvər])。

        ufollower用于接受客户端请求并向客户端返回结果,在选主过程中参与投票

        uObserver可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度

l客户端(client),请求发起方

         一个 ZooKeeper 集群同一时刻只会有一个 Leader,ZooKeeper集群的所有机器通过选举过程来选定一台被称为Leader的机器,Leader服务器为客户端提供读和写服务。其他都是 Follower 或 Observer。

        Follower 和 Observer 都能提供读服务,不能提供写服务。两者唯一的区别在于,Observer 不参与 Leader 选举过程,也不参与写操作的『过半写成功』策略,因此 Observer 可以在不影响写性能的情况下提升集群的读性能。

2、节点状态:

        每个集群中的节点都有一个状态 LOOKING, FOLLOWING, LEADING, OBSERVING。都属于这4种,每个节点启动的时候都是LOOKING状态,如果这个节点参与选举但最后不是leader,则状态是FOLLOWING,如果不参与选举则是OBSERVING,leader的状态是LEADING。

3、关于ZooKeeper集群服务器数:

        ZooKeeper 官方建议集群服务器的数量为奇数,这是因为一个 ZooKeeper 集群如果要对外提供可用的服务,那么集群中必须要有过半的机器正常工作并且彼此之间能够正常通信。基于这个特性,如果想搭建一个能够允许 N 台机器 down 掉的集群,那么就要部署一个由 2*N+1 台服务器构成的 ZooKeeper 集群。因此,一个由 3 台机器构成的 ZooKeeper 集群,能够在挂掉 1 台机器后依然正常工作,而对于一个由 5 台服务器构成的 ZooKeeper 集群,能够对 2 台机器挂掉的情况进行容灾。注意,如果是一个由6台服务器构成的 ZooKeeper 集群,同样只能够挂掉 2 台机器,因为如果挂掉 3 台,剩下的机器就无法实现过半了。

zookeeper有这样一个特性:

集群中只要有超过过半的机器是正常工作的,那么整个集群对外就是可用的。

4、ZooKeeper可伸缩性:

        那么,ZooKeeper为什么要引入Observer这个角色呢?其实在ZooKeeper中引入Observer,主要是为了使ZooKeeper具有更好的可伸缩性。那么,何为可伸缩性?如果我们的工作负载可以通过给系统分配更多的资源来分担,那么这个系统就是可伸缩的;一个不可伸缩的系统却无法通过增加资源来提升性能,甚至会在工作负载增加时,性能会急剧下降。

        在Observer出现以前,ZooKeeper的伸缩性由Follower来实现,我们可以通过添加Follower节点的数量来保证ZooKeeper服务的读性能。但是随着Follower节点数量的增加,ZooKeeper服务的写性能受到了影响。

        简单来说,Zab协议规定:来自Client的所有写请求,都要转发给ZooKeeper服务中唯一的Server:Leader,由Leader根据该请求发起一个Proposal([prəˈpoʊzl]请求)。然后,其他的Server对该Proposal(请求)进行Vote([voʊt] 投票)。之后,Leader对Vote(投票)进行收集,当Vote数量过半时Leader会向所有的Server发送一个通知消息。最后,当Client所连接的Server收到该消息时,会把该操作更新到内存中并对Client的写请求做出回应。

ZooKeeper写请求工作流程图:

          从图中我们可以看出, ZooKeeper 服务器在上述协议中实际扮演了两个职能。它们一方面从客户端接受连接与操作请求,另一方面对操作结果进行投票。这两个职能在 ZooKeeper集群扩展的时候彼此制约。例如,当我们希望增加 ZK服务中Client数量的时候,那么我们就需要增加Server的数量,来支持这么多的客户端。然而,从Zab协议对写请求的处理过程中我们可以发现,增加服务器的数量,则增加了对协议中投票过程的压力。因为Leader节点必须等待集群中过半Server响应投票,于是节点的增加使得部分计算机运行较慢,从而拖慢整个投票过程的可能性也随之提高,写操作也会随之下降。这正是我们在实际操作中看到的问题——随着 ZooKeeper 集群变大,写操作的吞吐量会下降。

所以,我们不得不在增加Client数量的期望和我们希望保持较好吞吐性能的期望间进行权衡。要打破这一耦合关系,我们引入了不参与投票的服务器,称为Observer。 Observer可以接受客户端的连接,并将写请求转发给Leader节点。但是,Leader节点不会要求 Observer参加投票。相反,Observer不参与投票过程,仅仅在上述第3步那样,和其他服务节点一起得到投票结果。

(二) Znode

ZooKeeper维护一个类似Linux文件系统的数据结构,用于存储数据

        数据模型结构是一种树形结构,由许多节点构成,每个节点叫做ZNode(ZooKeeperNode),每个节点对应一个唯一路径,通过该路径来标识节点,如/app1/p_1,其中 app1和p_1都是 ZNode。每个 ZNode 上都会保存自己的数据内容。

          由于Zookeeper是用来保管“协同数据”(coordination data)的,比如状态信息(status information),配置信息(configuration),位置信息(location information),所以每个znode文件都很小,一般也就是在“kilobyte range”级别的,默认是1M, 可以通过配置修改, 通常不建议在ZNode上存储大量的数据。

在 ZooKeeper 中,ZNode节点类型有四种: 

l持久化目录节点 persistent

客户端与服务器断开连接,该节点仍然存在 

l持久化顺序编号目录节点 persistent_sequential 

客户端与服务器断开连接,该节点仍然存在,此时节点会被顺序编号,如:000001、000002..... 

l临时目录节点 ephemeral

客户端与服务器断开连接,该节点会被删除 

l临时顺序编号目录节点 ephemeral_sequential 

客户端与服务器断开连接,该节点会被删除,此时节点会被顺序编号,如:000001、000002.....

(三)Watcher

        ZooKeeper是一个基于观察者(watcher)模式设计的分布式服务管理框架 

1.ZooKeeper负责管理和维护项目的公共数据,并授受观察者的注册(订阅) 

2. 一旦这些数据发生变化,ZooKeeper就会通知已注册的观察者 

3.此时观察者就可以做出相应的反应

简单来说,客户端注册监听它关心的目录节点,当目录节点发生变化时,ZooKeeper会通知客户端

        ZooKeeper支持Watch操作,Client可以在某个ZNode上设置一个Watcher,来Watch该ZNode上的变化。如果该ZNode上有相应的变化,就会触发这个Watcher,把相应的事件通知给设置Watcher的Client。需要注意的是,ZooKeeper中的Watcher是一次性的,即触发一次就会被取消,如果想继续Watch的话,需要客户端重新设置Watcher,该机制是 ZooKeeper 实现分布式协调服务的重要特性。

(四)应用场景

1、配置管理

        场景:集群环境、服务器的许多配置都是相同的,如:数据库连接信息,当需要修改这些配置时必须同时修改每台服务器,很麻烦

        解决:把这些配置全部放到ZooKeeper上,保存在ZooKeeper的某个目录节点中,然后所有的应用程序(客户端)对这个目录节点进行监视Watch,一旦配置信息发生变化,ZooKeeper会通知每个客户端,然后从ZooKeeper获取新的配置信息,并应用到系统中。

 2、命名服务(Naming Service),即注册中心——服务注册与发现

        命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。

         注册一个持久节点/service/business/what,他下面的每个子节点都是一个可用服务,保存了服务的地址、端口等信息,服务调用者通过zookeeper获取/service/business/what所有子节点信息来得到可用的服务。下面的节点都是临时节点,服务器启动的时候会过来注册一个临时节点,服务器挂掉之后或主动关闭之后,临时节点会自动移除,这样就可以保证使用者获取的what服务都是可用的,而且可以动态的扩容缩容。

3、软负载均衡

        ZooKeeper本身是不提供负载均衡策略的,需要自己实现,所以准确的说,是在负载均衡中使用ZooKeeper来做集群的协调(也称为软负载均衡)

实现思路: 

        1.将ZooKeeper作为服务的注册中心,所有服务器在启动时向注册中心注册自己能够提供的服务 

        2.服务的调用者到注册中心获取能够提供所需要服务的服务器列表,然后自己根据负载均衡算法,从中选取一台服务器进行连接 

        3.当服务器列表发生变化时,如:某台服务器宕机下线,或新机器加入,ZooKeeper会自动通知调用者重新获取服务列表

实际上利用了ZooKeeper的特性,将ZooKeeper用为服务的注册和变更通知中心

 4、心跳检测

        机器间的心跳检测机制是指在分布式环境中,不同机器(或进程)之间需要检测到彼此是否在正常运行,例如A机器需要知道B机器是否正常运行。在传统的开发中,我们通常是通过主机直接是否可以相互PING通来判断,更复杂一点的话,则会通过在机器之间建立长连接,通过TCP连接固有的心跳检测机制来实现上层机器的心跳检测,这些都是非常常见的心跳检测方法。

        下面来看看如何使用ZooKeeper来实现分布式机器(进程)间的心跳检测。

        基于ZooKeeper的临时节点的特性,可以让不同的进程都在ZooKeeper的一个指定节点下创建临时子节点,不同的进程直接可以根据这个临时子节点来判断对应的进程是否存活。通过这种方式,检测和被检测系统直接并不需要直接相关联,而是通过ZooKeeper上的某个节点进行关联,大大减少了系统耦合。

(四)ZooKeeper的官网

http://zookeeper.apache.org/doc/current/zookeeperOver.html

 2、 Zookeeper安装

ZooKeeper的安装包括单机模式安装,以及集群模式安装。

单机模式较简单,是指只部署一个zk进程,客户端直接与该zk进程进行通信。 

        在开发测试环境下,通过来说没有较多的物理资源,因此我们常使用单机模式。当然在单台物理机上也可以部署集群模式,但这会增加单台物理机的资源消耗。故在开发环境中,我们一般使用单机模式。 

        但是要注意,生产环境下不可用单机模式,这是由于无论从系统可靠性还是读写性能,单机模式都不能满足生产的需求。

1、 上传软件包

上传apache-zookeeper-3.8.4-bin.tar.gz  jdk-23-linux-x64.tar.gz 软件包

[root@cong11 ~]# ls

anaconda-ks.cfg  apache-zookeeper-3.8.4-bin.tar.gz  jdk-23_linux-x64_bin.tar.gz

软件下载地址:

https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/apache-zookeeper-3.8.4-bin.tar.gz

2、 配置hosts

[root@cong11 ~]# vim /etc/hosts

192.168.1.11 cong11

3、 部署jdk

由于zookeeper依赖java环境,所以我们需要安装jdk,官网建议最低安装jdk 1.8版本

4、 解压jdk

[root@cong11 ~]# tar -zxvf jdk-23-linux-x64.tar.gz -C /usr/local/

5、 配置JDK环境变量

[root@cong11 ~]# vim /etc/profile  #在文件最后加入以下行

JAVA_HOME=/usr/local/jdk-23 

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar 

export PATH JAVA_HOME CLASSPATH

[root@cong11 ~]# source /etc/profile   #使环境变量生效

6、 查看java环境

[root@cong11 ~]# java -version

 部署zookeeper(独立模式)

1、 解压安装装包

[root@cong11 ~]# tar -zxf apache-zookeeper-3.8.4-bin.tar.gz -C /usr/local/

2、 创建内存数据库快照存放目录:

[root@cong11 ~]# mkdir -p /data/zk/data

3、 创建事务日志存放目录:

[root@cong11 ~]# mkdir -p /data/zk/datalog

注意:如果不配置datalog,那么事务日志也会写在data目录中。这样会严重影响zk的性能。因为在zk吞吐量很高的时候,产生的事务日志和快照日志太多。

4、 生成配置文件

[root@cong11 ~]# cd /usr/local/apache-zookeeper-3.8.4-bin/conf/

[root@cong11 conf]# ls

configuration.xsl  logback.xml  zoo_sample.cfg

[root@cong11 conf]# cp zoo_sample.cfg zoo.cfg #复制一份zoo_sample.cfg文件并命名为zoo.cfg

5、 修改主配置文件zoo.cfg

[root@cong11 conf]# vim zoo.cfg 

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zk/data        #修改这一行为我们创建的目录

dataLogDir=/data/zk/datalog   #添加这一行

clientPort=2181

参数说明:

        tickTime:基本事件单元,以毫秒为单位。它用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime。 

        initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过10个心跳的时间(也就是 tickTime)长度后 Zookeeper服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20 秒 。

        syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 5*2000=10秒。

        dataDir:是存放内存数据库快照的位置(存储数据的位置),默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。

        dataLogDir:是事务日志目录 。用于配置服务器存储事务日志文件的目录,默认值dataDir,但是建议将两个目录分别配置,防止磁盘的并发读写,影响服务器性能。可将其配置在一个单独的磁盘上。

        clientPort:是client连接的端口。不同的服务器可以设置不同的监听端口,默认是2181。

6、 添加path环境变量

这里必须是修改配置文件添加path环境变量,不然启动报错

[root@cong11 ~]# vim /etc/profile

export ZOOKEEPER_HOME=/usr/local/apache-zookeeper-3.8.4-bin

export PATH=$ZOOKEEPER_HOME/bin:$PATH

[root@cong11 ~]# source /etc/profile

7、 启动Zookeeper

[root@cong11 ~]# zkServer.sh start

ZooKeeper JMX enabled by default

Using config: /usr/local/apache-zookeeper-3.8.4-bin/bin/../conf/zoo.cfg

Starting zookeeper ... already running as process 2058.

[root@cong11 ~]# zkServer.sh start /usr/local/apache-zookeeper-3.8.4-bin/conf/zoo.cfg

8、 验证

查看ZooKeeper是否运行

[root@cong11 ~]# ps –ef | grep zookeeper 

# 也可以使用jps ,可以看到java进程中有QuorumPeerMain列出来。

查看ZooKeeper的状态

[root@cong11 ~]# zkServer.sh status

 可以看到端口,我们是单节点部署

启动客户端:

使用zkCli连接ZooKeeper

[root@cong11 ~]# zkCli.sh 或 [root@cong11 ~]# zkCli.sh -server localhost:2181

 连接成功后可以使用如下命令:

常用命令

1、 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容

[zk: localhost:2181(CONNECTED) 0] ls /

[zookeeper]

2、 创建一个新的 znode ,使用 create /zkPro myData

[zk: localhost:2181(CONNECTED) 2] create /zkPro myData

Created /zkPro

[zk: localhost:2181(CONNECTED) 3] ls / #再次查看内容

[zkPro, zookeeper]

3、 使用 get 命令获取的znode中的字符串

下面我们运行 get 命令来确认第二步中所创建的 znode 是否包含我们所创建的字符串:

[zk: localhost:2181(CONNECTED) 4] get /zkPro

myData

4、 使用set命令修改字符串

下面我们通过 set 命令来对 zk 所关联的字符串进行设置:

[zk: localhost:2181(CONNECTED) 5] set /zkPro myData2

[zk: localhost:2181(CONNECTED) 6] get /zkPro

myData2

5、 删除创建的znode

[zk: localhost:2181(CONNECTED) 7] delete /zkPro

[zk: localhost:2181(CONNECTED) 8] ls /

[zookeeper]   #可以看见我们创建的/zkPro被删除

6、 Java代码客户端测试

只需要了解编程人员是怎么使用zookeeper的。

https://blog.csdn.net/dongdong9223/article/details/81349965

Zookeeper集群搭建

Zookeeper节点部署越多,服务的可靠性越高,建议部署奇数个节点,因为zookeeper集群是以宕机个数过半才会让整个集群宕机的。

搭建集群可以选择在一台真实机上搭建多台zookeeper服务这种伪集群模式,我们这里选择在3台虚拟机上搭建zookeeper集群,测试环境可以使用伪集群模式,生产环境不能使用。

1、 集群拓扑

2、 配置hosts

所有节点配置hosts

[root@cong11 ~]# vim /etc/hosts

192.168.1.11 cong11

192.168.1.12 cong12

192.168.1.13 cong13

 cong11配置

安装zookeeper,jdk请参照上面

1、 修改配置文件

[root@cong11 ~]# vim /usr/local/apache-zookeeper-3.8.4-bin/conf/zoo.cfg

#注意修改标红部分

# 服务器之间或客户端与服务器之间维持心跳的时间间隔

# tickTime以毫秒为单位。

 tickTime=2000

 # 集群中的follower服务器(F)与leader服务器(L)之间的初始连接心跳数

 initLimit=10

 # 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数

 syncLimit=5

 # 快照保存目录, 不要设置为/tmp,该目录重新启动后会被自动清除

dataDir=/data/zk/data

# 日志保存目录

dataLogDir=/data/zk/datalog

# 客户端连接端口

 clientPort=2181

 # 客户端最大连接数。

 # 根据自己实际情况设置,默认为60个

 # maxClientCnxns=60

 # 三个节点配置,格式为:

# server.服务编号=服务地址、LF通信端口、选举端口

server.1=cong11:2888:3888

server.2=cong12:2888:3888

server.3=cong13:2888:3888

        注:server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。dataDir、dataLogDir不要相同。

        除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据就是 A 的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个 server。

2、 写入节点标记

myid配置 

        在dataDir所定义的目录下新建myid文件,本例中在/data/zk/data下新建myid文件,填入各主机之ID。如cong11机器的myid文件内容为1,cong12机器的myid文件内容为2,cong13机器的myid文件内容为3。 

在/data/zk/data设置myid, 这个myid的数字跟配置文件里面的server id对应

[root@cong11 ~]# echo 1 > /data/zk/data/myid

3、 拷贝软件和文件到cong12,cong13

1) 拷贝jdk

[root@cong11 ~]# scp -r /usr/local/jdk-23/ 192.168.1.12:/usr/local/

[root@cong11 ~]# scp -r /usr/local/jdk-23/ 192.168.1.13:/usr/local/

2)拷贝zookeeper

[root@cong11 ~]# scp -r /usr/local/apache-zookeeper-3.8.4-bin/ 192.168.100.12:/usr/local/

[root@cong11 ~]# scp -r /usr/local/apache-zookeeper-3.8.4-bin/ 192.168.100.13:/usr/local/

3) 拷贝profile文件,设置环境变量

[root@cong11 ~]# scp /etc/profile 192.168.1.12:/etc/

[root@cong11 ~]# scp /etc/profile 192.168.1.13:/etc/

Cong12上配置

1、 修改hosts

[root@cong12 ~]# vim /etc/hosts

192.168.1.11 cong11

192.168.1.12 cong12

192.168.1.13 cong13

2、 把传过来的profile生效

[root@cong12 ~]# source /etc/profile

[root@cong12 ~]# java -version #查看java环境

java version "1.8.0_171"

Java(TM) SE Runtime Environment (build 1.8.0_171-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

3、 创建zookeeper工作目录

[root@cong12 ~]# mkdir -p /data/zk/{data,datalog}

4、 写入节点标记

[root@cong12 ~]# echo 2 > /data/zk/data/myid

Cong13配置

1、 修改hosts

[root@cong13 ~]# vim /etc/hosts

192.168.1.11 cong11

192.168.1.12 cong12

192.168.1.13 cong13

2、 把传过来的profile生效

[root@cong13 ~]# source /etc/profile

[root@cong13 ~]# java -version #查看java环境

java version "1.8.0_171"

Java(TM) SE Runtime Environment (build 1.8.0_171-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

3、 创建zookeeper工作目录

[root@cong13 ~]# mkdir -p /data/zk/{data,datalog}

4、 写入节点标记

[root@cong13 ~]# echo 3 > /data/zk/data/myid

启动zookeeper集群

在cong11,cong12,cong13上分别启动zookeeper

[root@cong11 ~]# zkServer.sh restart

[root@cong12 ~]# zkServer.sh restart

[root@cong13 ~]# zkServer.sh restart

查看集群服务状态

[root@cong11 ~]# zkServer.sh status

 [root@cong12 ~]# zkServer.sh status

 [root@cong13 ~]# zkServer.sh status

 可以看到3个节点。一个leader,2个follower

zookeeper集群中各个服务的dataDir结构(如下图所示)

 注: 忽略掉除myid文件的其他内容,这些内容是由服务启动后产生的。

服务连接测试

连接ZooKeeper:

[root@cong11 ~]# zkCli.sh

# zkCli.sh -server 192.168.1.11:2181,192.168.1.12:2181,192.168.1.13:2181

 可以看到连接成功,也就是集群配置成功了。

故障切换测试

1、 关掉cong11 ZK

[root@cong11 ~]# zkServer.sh stop

2、 查看cong12,cong13状态

[root@cong12 ~]# zkServer.sh status

 [root@cong13 ~]# zkServer.sh status

 发现leader切换到cong13上了

3、 重新启动cong11 ZK

[root@cong11 ~]# zkServer.sh start

[root@cong11 ~]# zkServer.sh status

 重新加入集群,角色是follower

集群数据同步测试

1、 在cong13上写入数据

[zk: localhost:2181(CONNECTED) 0] create /zkPro myData

Created /zkPro

[zk: localhost:2181(CONNECTED) 1] ls / 

[zkPro, zookeeper]

2、 在cong11,cong12上查看

[zk: localhost:2181(CONNECTED) 0] ls /

[zkPro, zookeeper]   #看到数据一致

配置Observer模式

要使用Observer模式的Server,需要在server的配置文件上添加:

peerType=observer

并且在每个server的配置文件中,配置成Observer模式的server后面追加:observer,如:server.x=host:n:n:observer

将上面的cong11这台服务配置为Observer模式,配置(zoo.cfg)如下:

peerType=observer

server.1=cong11:2888:3888:observer

server.2=cong12:2888:3888

server.3=cong13:2888:3888

同样更新cong12的zoo.cfg, cong13的zoo.cfg中server.1的值和cong11的zoo.cfg一致。并启动这三个server,查看状态,信息如下图:

从上图可以看出修改之后,三个server中存在observer,follower,leader。

注:Zookeeper中follower,leader属于参与者角色(participant),observer属于观察者角色(observer)。

相关文章:

分布式开源协调服务之zookeeper

Zookeeper简介 Zookeeper是什么? Zookeeper官网中对Zookeeper的定义还是比较明确的: ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services…...

ubuntu系统安装playhouse三方库

ubuntu系统python3.10安装playhouse三方库 问题描述 问题描述 虚拟环境中使用pip install playhouse,返回安装成功 用pip list查看,能看到playhouse及版本号 导包时提示没有找到playhouse我那件目录,能发现 检查site-package发现问题&#x…...

【星云 Orbit-F4 开发板】04.一触即发:GPIO 外部中断

【星云 Orbit-F4 开发板】04. 一触即发:外部中断控制 摘要 本文详细介绍了如何使用STM32F407微控制器的HAL库实现外部中断功能。通过配置GPIO引脚作为外部中断源,并在中断回调函数中处理按键事件,实现了按键控制LED状态翻转的功能。本文旨在…...

笔记二:整数和浮点数在内存中存储

目录 一、数据类型介绍 二、类型的基本归类 1.整形家族: 2.浮点数家族: 3.构造类型: 4.指针类型 5.空类型: 三、整形在内存中的存储 3.1 原码,反码、补码 3.2 大小端介绍 四、浮点数在内存中的存储 ​编辑 4.…...

PyQT(PySide)的上下文菜单策略设置setContextMenuPolicy()

在 Qt 中,QWidget 类提供了几种不同的上下文菜单策略,这些策略通过 Qt::ContextMenuPolicy 枚举类型来定义,用于控制控件(如按钮、文本框等)在用户右键点击时如何显示上下文菜单。 以下是 Qt::ContextMenuPolicy 枚举中…...

BladeX框架接口请求跨域

前端使用代理请求接口,接口可以正常访问。如果换全路径请求就跨域。 除了后端要配置跨域 还需要修改配置文件对OPTIONS请求的限制...

如何在Apple不再支持的MacOS上安装Homebrew

手头有一台2012年产的Macbook Pro,系统版本停留在了10.15.7(2020年9月24日发布的)。MacOS 11及后续的版本都无法安装到这台老旧的电脑上。想通过pkg安装Homebrew,发现Homebrew releases里最新的pkg安装包不支持MacOS 10.15.7&…...

本地大模型编程实战(26)用langgraph实现基于SQL数据构建的问答系统(5)

本文将将扩展上一篇文章完成的 langgraph 链,继续使用基于 langgraph 链 ,对结构化数据库 SQlite 进行查询的方法。该系统建立以后,我们不需要掌握专业的 SQL 技能,可以用自然语言询问有关数据库中数据的问题并返回答案。主要完善…...

数据结构与算法:滑动窗口

前言 滑动窗口一般主要用于解决子数组或子串问题,这类的题目更看重对题目的分析和转化。 一、原理 在整个数组上,用l和r分别控制窗口的左右边界,r就扩大,l就减小。 当窗口的范围和题目中某个指标间存在单调关系时,…...

江协科技/江科大-51单片机入门教程——P[2-1] 点亮一个LED

本节将向大家介绍如何用 51 单片机去控制开发板上的 LED。开发板上的 LED 位置标注有 “LED 模块”。 第二章要写 3 个程序代码:第一个代码实现点亮开发板上的第一个 LED;第二个代码让第一个 LED 以 1 秒为周期闪烁;第三个代码使 8 个 LED 以…...

leetcode hot 100 41. 缺失的第一个正数

代码 测试用例 测试用例 测试结果 41. 缺失的第一个正数 已解答 困难 相关标签 相关企业 提示 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1&#xf…...

UniApp 使用 u-loadmore 完整步骤

文章目录 一、前期准备1. 安装 uView - UI 二、使用 u-loadmore组件1. 创建页面2. 编写页面代码模板部分(loadmore-demo.vue)样式部分脚本部分 三、要点补充1. u-loadmore 状态说明2. 数据请求优化3. 性能优化4. 兼容性问题 在 UniApp 开发中&#xff0c…...

设置电脑一接通电源就主动开机

文章目录 1、进入BIOS2、设置4、功能弊端5、电脑自动开机的设置 1、进入BIOS 在电脑重启时,这时屏幕上会显示按XXX键到BIOS界面 没有进入BIOS提示的,按下面方法操作: 方法一 在开机显示logo的时候,立即按下面这几个按键&#xf…...

优艾智合机器人日本子公司成立,加速推进国际化布局

2月27日,工业移动机器人解决方案商优艾智合宣布日本子公司Youibot Robotics Japan株式会社(以下简称“Youibot Japan”)成立,并于东京举行开业典礼。此举标志着优艾智合在日本市场的现地服务能力进一步深化,是其全球化…...

自然语言处理NLP入门 -- 第七节预训练语言模型

1 什么是预训练模型? 在自然语言处理(NLP)里,训练一个好模型通常需要很多数据和计算资源。为了解决这个难题,就出现了“预训练模型”。 预训练模型 是指我们先在海量文本(比如网络上爬到的大量文章、对话…...

Git GitHub基础

git是什么? Git是一个分布式版本控制系统,用于管理源代码的变更。它允许多个开发者在同一个项目上协作,同时跟踪每个修改的历史记录。 关键词: 分布式版本控制软件 软件 安装到我们电脑上的一个工具 版本控制 例如论文&…...

多平台文章同步工具PostSync 安装介绍

PostSync 是一个开源的用于多平台文章同步的工具 环境安装 安装 Python:PostSync 是基于 Python 开发的,你需要确保系统中已经安装了 Python 环境,建议使用 Python 3.7 及以上版本。你可以从 Python 官方网站 下载并安装适合你操作系统的版…...

PXE批量网络装机与Kickstart自动化安装工具

目录 一、系统装机的原理 1.1、系统装机方式 1.2、系统安装过程 二、PXE批量网络装机 2.1、PXE实现原理 2.2、搭建PXE实际案例 2.2.1、安装必要软件 2.2.2、搭建DHCP服务器 2.2.3、搭建TFTP服务器 2.2.4、挂载镜像并拷贝引导文件到tftp服务启动引导文件夹下 2.2.5、编…...

css的复合选择器

1.1什么是复合选择器 在css中,选择器分为基础选择器和复合选择器,复合选择器是建立在基础选择器之上,对基本选择器进行组合形成。 复合选择器可以更准确、更高效的选择目标元素(标签)由两个或多个基础选择器,通过不同的方式组合…...

Wireshark Lua 插件教程

本⽂主要介绍 Lua 脚本在 Wireshark 中的应⽤, Lua 脚本可以在 Wireshark 中完成如下功能: 从⽹络包中提取数据, 或者统计⼀些数据包(Dumper) 需要解析⼀种 Wireshark 不提供原⽣⽀持的协议(Dissector) ⽰例 协议解析 VREP 协议是 NOGD 框架对于 TRIP 协议的⼀种延伸和扩展…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...