Zookeeper

本文详细介绍了Zookeeper的入门知识,包括其工作机制、特点、数据结构和应用场景。重点讲述了Zookeeper集群的安装步骤,包括下载、解压、配置环境变量、设置myid、启动服务等,并解析了配置参数。此外,还介绍了Zookeeper的选举机制、客户端命令行操作、监听器原理以及API操作,展示了如何创建、获取、修改节点等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Zookeeper 入门

1、概述

Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。

2、Zookeeper工作机制

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

3、Zookeeper特点

  1. Zookeeper: 一个领导者(Leader) ,多个跟随者(Follower) 组成的集群。
  2. 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。所以Zookeeper适合安装奇数台服务器。
  3. 全局数据一致:每个Server保存 一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
  4. 更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行。
  5. 数据更新原子性,一次数据更新要么成功,要么失败。
  6. 实时性,在一定时间范围内,Client能读到最新数据。

4、数据结构

ZooKeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。
在这里插入图片描述

5、应用场景

提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。

①统一命名服务

在分布式环境下,经常需要对应用/服务进行统一命名, 便于识别。例如: IP不容易记住,而域名容易记住。
在这里插入图片描述

②统一配置管理

1、分布式环境下,配置文件同步非常常见。
(1)一般要求一个集群中,所有节点的配置信息是一致的,比如Kafka集群。
(2)对配置文件修改后,希望能够快速同步到各个节点上。
2、配置管理可交由ZooKeeper实现。
(1)可将配置信息写入ZooKeeper 上的一个Znode。
(2)各个客户端服务器监听这个Znode。
(3) 一旦Znode中的数据被修改,ZooKeeper将通知各个客户端服务器。
在这里插入图片描述

③统一集群管理

1、分布式环境中,实时掌握每个节点的状态是必要的。
(1)可根据节点实时状态做出一-些调整。

2、ZooK eeper可以实现实时监控节点状态变化
(1) 可将节点信息写入ZooKeeper.上的一 个ZNode。
(2)监听这个ZNode可获取它的实时状态变化。
在这里插入图片描述

④服务器动态上下线

客户端能实时洞察到服务器上下线的变化
在这里插入图片描述

⑤软负载均衡

在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求。
在这里插入图片描述

6、下载地址

①官网首页

https://zookeeper.apache.org/

②下载截图

在这里插入图片描述

7、Zookeeper 安装

①创建工作路径/usr/zookeeper,下载相应软件,解压至工作路径。

mkdir -p /usr/zookeeper
cd /usr/zookeeper

②解压zookeeper到相应路径

tar -zxvf /usr/zookeeper/zookeeper-3.4.10.tar.gz -C /usr/zookeeper

③在zookeeper的目录中,创建配置中所需的zkdata和zkdatalog两个文件夹。(在master执行)

cd /usr/zookeeper/zookeeper-3.4.10
mkdir zkdata
mkdir zkdatalog

④配置文件zoo.cfg

进入zookeeper配置文件夹conf,将zoo_sample.cfg文件拷贝一份命名为zoo.cfg,Zookeeper 在启动时会找这个文件作为默认配置文件。

cd /usr/zookeeper/zookeeper-3.4.10/conf/
mv zoo_sample.cfg zoo.cfg
vim zoo.cfg

#对zoo.cfg文件配置如下:(在master执行)

tickTime=2000    
initLimit=10
syncLimit=5
dataDir=/usr/zookeeper/zookeeper-3.4.10/zkdata
clientPort=2181
dataLogDir=/usr/zookeeper/zookeeper-3.4.10/zkdatalog
server.1=master:2888:3888
server.2=slave1:2888:3888
server.3=slave2:2888:3888

在这里插入图片描述

⑤进入zkdata文件夹,创建文件myid,用于表示是几号服务器。master主机中,设置服务器id为1。(集群中设置master为1号服务器,slave1为2号服务器,slave2为3号服务器)

cd /usr/zookeeper/zookeeper-3.4.10/zkdata
vim myid

在这里插入图片描述

⑥远程复制分发安装文件。

以上已经在主节点master上配置完成ZooKeeper,现在可以将该配置好的安装文件远程拷贝到集群中的各个结点对应的目录下:(在master执行)

scp -r /usr/zookeeper root@slave1:/usr/
scp -r /usr/zookeeper root@slave2:/usr/

⑦设置myid。在我们配置的dataDir指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,conf/zoo.cfg文件中配置的server.X中X为什么数字,则myid文件中就输入这个数字。(在slave1和slave2中执行)

cd /usr/zookeeper/zookeeper-3.4.10/zkdata
vim myid

实验中设置slave1中为2:
在这里插入图片描述
slave2中为3:
在这里插入图片描述

⑧修改/etc/profile文件,配置zookeeper环境变量。(三台机器都执行)

vi /etc/profile

#set zookeeper environment    
export ZOOKEEPER_HOME=/usr/zookeeper/zookeeper-3.4.10 
PATH=$PATH:$ZOOKEEPER_HOME/bin 

在这里插入图片描述

⑨生效环境变量

source /etc/profile

⑩启动ZooKeeper集群。在ZooKeeper集群的每个结点上,执行启动ZooKeeper服务的脚本。注意在zookeeper目录下:(三台机器都执行)

开启服务:bin/zkServer.sh start
查看状态:bin/zkServer.sh status

在这里插入图片描述
通过上面状态查询结果可见,一个节点是Leader,其余的结点是Follower。至此,zookeeper安装成功。

8、配置参数解读

Zookeeper中的配置文件zoo.cfg中参数含义解读如下:

①tickTime = 2000

通信心跳时间,Zookeeper服务 器与客户端心跳时间,单位毫秒
在这里插入图片描述

②initLimit= 10

LF初始通信时限
Leader和Follower初始连接时能容忍的最多心跳数(tickTime的数量)
在这里插入图片描述

③syncLimit=5

LF同步通信时限
Leader和Follower之间通信时间如果超过syncLimit * tick Time,Leader认为Follwer死掉,从服务器列表中删除Follwer。

④dataDir

保存Zookeeper中 的数据
注意:默认的tmp目录,容易被Linux系统定期删除,所以一般不用默认的tmp目录。

⑤clientPort= 2181

客户端连接端口,通常不做修改。

9、Zookeeper选举机制(第一次启动)

在这里插入图片描述

客户端命令行操作

①启动客户端

[root@master bin]# sh zkCli.sh -server master:2181

②命令行语法

命令基本语法功能描述
help显示所有操作命令
ls path使用 ls 命令来查看znode的子节点【可监听】 -w 监听子节点变化 -s 附加次级信息
create普通创建子节点 -s 含有序列 -e 临时(重启或者超时小时)
get path获得节点的值【可监听】-w 监听节点内容变化 -e附加次级信息
set设置节点的具体值
stat查看节点信息
delete删除节点
deleteall递归删除节点

③查看当前znode中所包含的内容

ls /

④查看当前节点详细数据

ls -s /

在这里插入图片描述

(1) czxid: 创建节点的事务zxid

每次修改ZooKeeper状态都会产生一个ZooKeeper事务ID。事务ID是ZooKeeper中所有修改总的次序。每次修改都有唯一的zxid,如果zxid小于zxid2,那么zxid在zxid2之前发生。
(2) ctime
znode 被创建的毫秒数(从1970年开始)
(3) mzxid
znode最后更新的事务zxid
(4) mtime
znode 最后修改的毫秒数(从1970年开始)
(5) pZxid
znode最后更新的子节点zxid
(6)cversion
znode 子节点变化号,znode, 子节点修改次数
(7) dataversion
znode 数据变化号
(8) aclVersion
znode 访问控制列表的变化号
(9) ephemeralOwner
如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。
(10) dataI ength
znode的数据长度
(11)numChildren
znode 子节点数量

⑤节点类型

持久(Persistent):客户端和服务器端断开连接后,创建的节点不删除
短暂(Ephemeral):客户端和服务器端断开连接后,创建的节点自己删除
在这里插入图片描述

1、分别创建2个普通节点(永久节点+不带序号)

[zk: master:2181(CONNECTED) 15] create /sanguo "yu zai"

 create /sanguo/shuguo "dian dian" 

获取节点中内容的值

get /sanguo
get /sanguo/shuguo

2、创建普通节点带序号(关闭客户端,数据不会删除)

create -s /sanguo/weiguo/ "zhang liao"

在这里插入图片描述
退出客户端

quit

连接客户端

 sh zkCli.sh -server master:2181

查看节点数据

ls /sanguo/weiguo 

数据并未删除

3、创建临时节点(关闭客户端,数据删除)

create -e /sanguo/wuguo "zouiyu"

4、创建临时节点带序号

 create -e -s /sanguo/wuguo "zouiyu3"

在这里插入图片描述

退出客户端

quit

连接客户端

 sh zkCli.sh -server master:2181

查看临时节点数据

ls /sanguo

在这里插入图片描述

数据消失。

5、修改节点数据值

set /sanguo/weiguo "simayi"

原节点内容
在这里插入图片描述
修改后
在这里插入图片描述

⑥监听器原理

客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节点增加删除)时,ZooKeeper. 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序。

1、监听原理详解

(1)首先要有一个main()线程
(2)在main线程中创建Zookeeper客户端 ,这时就会创建两个线程,一个负责网络连接通信(connet) ,-个负责监听(listener) 。
(3)通过connect线程将注册的监听事件发送给Zookeeper。
(4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
(5)Zookeeper监 听到有数据或路径变化,就会将这个消息发送给listener线程。
(6)listener线程内部调用了process()方法。

2、常见的监听

(1)监听节点数据的变化
get path [watch]
(2)监听子节点增减的变化
ls path [watch]

在这里插入图片描述

3、实操

(1)节点数据监听

① 启动三个节点的客户端

 sh zkCli.sh -server master:2181

 sh zkCli.sh -server slave1:2181

 sh zkCli.sh -server slave2:2181

②在slave2节点上监控sanguo的数据值

查看数据值

 get /sanguo

在这里插入图片描述

监控三国

 get /sanguo -w

③在slave1节点上修改sanguo的数据
修改数据

 set /sanguo "xisi"

slave2节点会监测的数据异常
在这里插入图片描述
④再次在slave1节点上修改sanguo的数据
修改数据

set /sanguo "yangfeiyan"

此时数据已经改变,但slave2的不会监测提醒
在这里插入图片描述
注意:在slave1再多次修改/sanguo的值,slave2上不会再收到监听。因为注册一次,只能监听一次。想再次监听,需要再次注册。

(2)节点的子节点数量监听

在slave2注册监听

 ls /sanguo -w

在这里插入图片描述
在slave1上的sanguo创建子节点

create /sanguo/jinguo "simayi"

在这里插入图片描述
slave2监听到异常
在这里插入图片描述
注意:节点的路径变化,也是注册一次,生效一次。想多次生效,就需要多次注册。

⑦节点删除与查看

删除节点

(适用于删除子节点)

delete /sanguo/jinguo

递归删除节点

(其节点与子节点都会删除)

deleteall /sanguo/shuguo

查看节点状态

stat /sanguo

客户端API操作

1、API 环境搭建

前提:保证hadoop102、hadoop103、 hadoop104 服务器上Zookeeper集群服务端启动。

①打开IDEA,创建Maven工程

在这里插入图片描述
在这里插入图片描述

②添加pom文件

<dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>RELEASE</version>
  </dependency>
 <dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.8.2</version>
 </dependency>
 <dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.5.7</version>
 </dependency>
</dependencies>

在这里插入图片描述

③拷贝log4j.properties文件到项目根目录

需要在项目的src/main/resources目录下,新建一个文件,命名为“log4j.properties”,在文件中填入。
在这里插入图片描述

log4j.rootLogger=INFO,stdout
1og4j.appender.stdout=org.apache.log4j.ConsoleAppender
1og4i.appender.stdout.layout=org.apache.1og4j.PatternLayout
loq4j.appender.stdout.layout.ConversionPattern=%d%p[%c]-%m%n
1og4i.appender.logfile=org.apache.1og4j.FileAppender
log4j.appender.logfile.File=target/spring.log
1og4i.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d%p[%c]-%m%n

在这里插入图片描述

④创建包名com.atguigu.zk

在这里插入图片描述

⑤创建类名称zkClient

在这里插入图片描述

2、创建Zookeeper客户端

package yuzai.zk;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;

import javax.imageio.IIOException;
import java.io.IOException;

public class zkClient {
    //:"master:2181,slave1:2181,slave2:2181"的逗号左右不能有空格。
    private String connectString = "master:2181,slave1:2181,slave2:2181";
    private int sessionTimeout = 2000 ;

    @Test
    public void init() throws IOException {

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

            }
        });
    }
}

3、创建子节点

package yuzai.zk;

import org.apache.zookeeper.*;
import org.junit.Before;
import org.junit.Test;

import javax.imageio.IIOException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class zkClient {
    //:"master:2181,slave1:2181,slave2:2181"的逗号左右不能有空格。
    private String connectString = "192.168.187.198:2181,192.168.187.197:2181,192.168.187.196:2181";
    private int sessionTimeout = 2000 ;
    private static ZooKeeper zkClient ;

    @Before
    public void init() throws IOException {

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

            }
        });
    }

    @Test
    public void creata() {
        try {
            String nodeCreated = zkClient.create("/adian", "xiaozahng".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

4、获取子节点并监听节点变化

在这里插入图片描述

5、判断Znode是否存在

在这里插入图片描述

6、客户端向服务端写数据流程

①分析需求

在这里插入图片描述

②具体实现

(1)先在集群上创建/servers节点

[zk: localhost:2181 (CONNECTED) 10]create /servers "servers " 

(2)在Idea中创建包名: com.atguigu.zkcase1

(3)服务器端向Zookeeper注册代码

package yuzai.zk1;

import org.apache.zookeeper.*;

import java.io.IOException;

public class DistributeServer {

    private String connectString = "192.168.187.198:2181,192.168.187.197:2181,192.168.187.196:2181";
    private int sessionTimeout = 2000 ;


    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        DistributeServer server = new DistributeServer();
        //1.获取zk连接
        server.getConnect();
        //2.注册服务器到zk集群
        server.regist(args[0]);

        //3.启动业务逻辑(睡觉觉)
        server.business();
    }

    private void business() throws InterruptedException {
        Thread.sleep(Long.MAX_VALUE);
    }

    private void regist(String hostname) throws InterruptedException, KeeperException {
        String create = zk.create("/servers", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

        System.out.println(hostname+"is online");
    }

    ZooKeeper zk;

    // 获取zk连接.方法
    private void getConnect() throws IOException {

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

            }
        });
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值