ZooKeeper-二、Zookeeper 集群操作

zookeeper 本地安装

1、集群操作

(1)集群安装

(2)选举机制

  1. 第一次启动:假设有五台服务器
    ①服务器1启动,先投给自己一票,然后发现没有超过半数以上(>=3)的服务器,选举无法完成,进入 LONGING 状态
    ②服务器2启动,先投给自己一票,然后发现没有超过半数以上的服务器,此时服务器1发现服务器2的myid比目前自己投票选举的(服务器1)大,更改投举为服务器2。此时服务器1票数为0,服务器2票数为2,没有超过半数以上,选举无法完成,服务器1、服务器2都进入Looking状态。
    ③服务器3启动,发起一次选举。此时服务器3投给自己,服务器1、2都会改选投为服务器3,超过半数以上,服务器3当选Leader。此时服务器1、2状态为FOLLWERING,服务器3状态为LEADING
    ④服务器4启动,发起一次选举。此时服务器1、2、3已经不是LOOKING状态了,不会随意更改投票,此时服务器4投给自己一票,而服务器3有3票,服务器4服从多数,更改选票为服务器3,并更改状态为FOLLOWING
    ⑤服务器5启动选举过程与服务器4一样

SID:服务器ID,用来唯一标识ZooKeeper集群中的机器,每台机器不能重复,和myid一致。
ZXID:事务ID。ZXID是一个事务ID,用来标识一次服务器状态的更改。
Epoch:每个Leader任期的代号。

  • 非第一次启动:
    当 Zookeeper 集群中的一台服务器出现以下两种情况之一时,就会开始进入 Leader 选举:
    • 服务器初始化启动
    • 服务器运行期间无法和 Leader 保持连接
  • 当一台服务器进入 Leader 选举流程时,当前集群也可能会处于以下两种状态:
    • 集群中存在 Leader
      对于集群中确实存在Leader,机器尝试去选举Leader,会被告知当前服务器的Leader信息,对于该机器来说,仅仅只需要和当前Leader建立连接,并进行状态同步即可。
    • 集群中确实不存在 Leader

(3)ZK 集群启动停止脚本

ZooKeeper 启动

c

ZooKeeper 停止

bin/zkServer.sh stop

查看 ZooKeeper 状态

bin/zkServer.sh status

上面是命令直接启动停止,我们可以写个脚本可以方便一点:

#!/bin/bash

case $1 in
"start"){
    for i in centos102 centos102 centos104
    do
        echo --------- zookeeper $i 启动 ---------
        ssh $i "/opt/module/zookeeper-3.5.7/bin zkServer.sh start"
    done
}
;;
"stop"){
    for i in centos102 centos102 centos104
    do
        echo --------- zookeeper $i 停止 ---------
        ssh $i "/opt/module/zookeeper-3.5.7/bin zkServer.sh stop"
    done
}
;;
"status"){
    for i in centos102 centos102 centos104
    do
        echo --------- zookeeper $i 状态 ---------
        ssh $i "/opt/module/zookeeper-3.5.7/bin zkServer.sh status"
    done
};;
esac

2、客户端命令行操作

客户端启动:

bin/zkCli.sh

但是我们可以看到这里是相当于本地客户端启动,我们需要102、103、104启动

bin/zkCli.sh -server [想启动的服务器]:[该服务器端口号]


对应服务器启动成功

节点信息

ls /

出现一个节点

ls -s /

以下出现的信息都是什么意思呢?

  • czxid:创建节点的事务ID
  • ctime:znode 被创建的毫秒数(从1970年开始)
  • mzxid:

在这里插入图片描述

节点类型

持久:客户端和服务器断开连接后,创建的节点不删除
短暂:客户端和服务器断开连接后,创建的节点自己删除

持久化目录节点:客户端和ZooKeeper断开连接后,该节点依然存在
持久化顺序编号目录节点:客户端和ZooKeeper断开连接后,该节点依然存在,只是ZooKeeper给该节点名称进行顺序编号。
临时目录节点:客户端和ZooKeeper断开连接后,该节点被删除
临时顺序编号目录节点:客户端和ZooKeeper断开连接后,该节点被删除,只是ZooKeeper给该节点名称进行顺序编号。

创建永久节点
create /[节点名称] "添加的信息"

查看节点,多出了一个 snaguo 的节点

多目录的创建节点,在 snaguo 节点下创建 shuguo 节点,添加信息为 liubei

查看节点的信息
get -s /[节点名称]

上面是创建节点不带序号的,接下来我们创建永久九点带序号的:

create -s /[节点名称] "添加的信息"

创建的节点自动带上了序号

有序号的节点有什么好处,如图,再次创建 weiguo 的节点发现不能创建,重复,但是再次创建 zhangliao 带序号的节点便可以创建

创建临时节点
create -e /[节点名称] "添加的信息"

带序号的临时节点

create -e -s  /[节点名称] "添加的信息"

接下来退出客户端,然后再重启,看看还有没有这两个节点

发现只有两个持久性节点,我们创建的两个临时节点不见了

修改节点数据值
set /[节点名称] "修改的信息"

在这里插入图片描述

监听器及节点删除

在这里插入图片描述

监听原理

注册监听器

前提:启动客户端103、104

get -w /[要监听的节点名称]

在centos104上注册监听器,现在就已经监听了 sanguo 这个节点

现在在centos103上修改这个节点的信息

回到centos104下,我们发现出现以下信息,告诉我们节点信息发生修改

注意:此时我们再次修改 sanguo 的值,监听器不会再告诉我们发生信息修改了,这是因为注册一次,只能监听一次;再次监听,需要再次注册。

节点的子节点变化监听(路径变化)

在centos104上设置监听器

创建一个新节点

可以看到提示我们节点修改

再次修改监听器不会再提示修改

节点删除以及查看

删除单个节点

delete /[节点]

不可以直接删除节点 sanguo,因为 sanguo 下有很多个节点,需要使用命令 deleteall /[节点名称],查看已经没有节点 sanguo 了

查看节点状态

stat /[节点名称]

接下来介绍以下命令

3、客户端 API 操作

前提:centos102、centos103、centos104 服务器都已经开启

pom.xml 依赖

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.17.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.5.7</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>RELEASE</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

log4j.properties 配置

# 设置全局的日志记录级别为 INFO
log4j.rootLogger=INFO, stdout

# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

# 文件输出
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

zkClient.java 代码

// 注意:逗号后面不能有空格
    private String connectString = "centos102:2181,centos103:2181,centos104:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zkClient;

    // 创建客户端
    @Before
    public void init() throws IOException {

        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {

            }
        });
    }

    // 创建子节点
    @Test
    public void create() throws InterruptedException, KeeperException {
        String nodeCreated = zkClient.create("/frost", "cat".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        
    }

运行创建子节点,看看是否创建了该节点

上一篇:当遇到 502 错误(Bad Gateway)怎么办


下一篇:TextHarmony:视觉文本理解与生成的新型多模态大模型