Zookeeper

news2025/7/18 7:58:25

文章目录

  • Zk介绍
    • 特点
    • 数据结构
    • 应用场景
  • Zk安装、集群
    • 下载、启动
    • 配置参数解读
    • Zookeeper 集群操作
    • 选举机制(面试重点)
  • 客户端命令行操作
    • 客户端界面
    • 节点类型(持久 / 短暂 / 有序号 / 无序号)
    • 监听器
      • 1)节点的值变化监听
      • 2)节点的子节点变化监听(路径变化)
    • 节点删除与查看
  • 客户端 API 操作
    • 创建 ZooKeeper 客户端
  • 案例
    • 服务器动态上下线
    • 动态监听是否有流量

Zk介绍

特点

在这里插入图片描述

数据结构

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

应用场景

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

统一命名服务

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

统一配置管理

在这里插入图片描述

统一集群管理

在这里插入图片描述

服务器动态上下线

在这里插入图片描述

软负载均衡

Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去 处理最新的客户端请求

在这里插入图片描述

Zk安装、集群

下载、启动

https://zookeeper.apache.org/

解压、配置zk

tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz  -C /opt/module/ # 解压
cd /opt/module/  # 进入 该目录

mv apache-zookeeper-3.7.1-bin/  zookeeper-3.7.1 # 改名
cd /opt/module/zookeeper-3.7.1 # 进入 改名后的目录
mkdir /opt/module/zookeeper-3.7.1/zkdata # 创建存放zk数据的目录
cd conf/
cp zoo_sample.cfg  zoo.cfg  # 拷贝 一份配置文件,重命名为 zoo.cfg
vim zoo.cfg	 # 编辑配置文件

修改dataDir的目录

在这里插入图片描述

操作zk

cd /opt/module/zookeeper-3.7.1/bin
./zkServer.sh start # 启动zk
./zkServer.sh status # 查看zk状态

在这里插入图片描述

./zkCli.sh # 连接zk服务端

在这里插入图片描述

配置参数解读

Zookeeper中的配置文件zoo.cfg中参数含义解读如下:
1)tickTime = 2000:通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒
在这里插入图片描述
2)initLimit = 10:LF初始通信时限
在这里插入图片描述

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

Leader和Follower之间通信时间如果超过 syncLimit * tickTimeLeader认为Follwer死掉,从服务器列表中删除Follwer
4)dataDir:保存Zookeeper中的数据
注意:默认的tmp目录,容易被Linux系统定期删除,所以一般不用默认的tmp目录
5)clientPort = 2181:客户端连接端口,通常不做修改

Zookeeper 集群操作

第一台机器

解压、配置zk

tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz  -C /opt/module/ # 解压
cd /opt/module/  # 进入 该目录

mv apache-zookeeper-3.7.1-bin/  zookeeper-3.7.1 # 改名
cd /opt/module/zookeeper-3.7.1 # 进入 改名后的目录
mkdir /opt/module/zookeeper-3.7.1/zkdata # 创建存放zk数据的目录
cd conf/
cp zoo_sample.cfg  zoo.cfg  # 拷贝 一份配置文件,重命名为 zoo.cfg
vim zoo.cfg	 # 编辑配置文件

修改dataDir的目录

在这里插入图片描述

cd /opt/module/zookeeper-3.7.1/zkdata/  # 进入数据目录
vim  myid

在文件中添加与 server 对应的编号注意:上下不要有空行,左右不要有空格
在这里插入图片描述

2

注意:添加 myid 文件,一定要在 Linux 里面创建,在 notepad++里面很可能乱码

其他机器:

其他不变,修改一下 myid 文件中的 值、修改 数据存储路径 配置

在每台机器增加一下配置

#######################cluster##########################
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
server.4=hadoop104:2888:3888

增加的 配置参数解读

server.A=B:C:D
  • A 是一个数字,表示这个是第几号服务器;
    集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据就是 A 的值

Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个 server。

  • B 是这个服务器的地址;
  • C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口
  • D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口

分别启动Zk即可

选举机制(面试重点)

第一次启动

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

第一次启动

启动选举规则:

  • ①EPOCH 大 的直接胜出
  • ②EPOCH 相同,事务 id 大的胜出
  • ③事务 id 相同,服务器 id 大的胜出

生产集群安装多少 zk 合适?

安装奇数台
生产经验:
⚫ 10 台服务器:3 台 zk;
⚫ 20 台服务器:5 台 zk;
⚫ 100 台服务器:11 台 zk;
⚫ 200 台服务器:11 台 zk

服务器台数多:好处,提高可靠性坏处:提高通信延时

客户端命令行操作

help  # 显示所有操作命令

ls path  #使用 ls 命令来查看当前 znode 的子节点 [可监听]
# -w 监听子节点变化
# -s 附加次级信息

create # 普通创建
#-s 含有序列
#-e 临时(重启或者超时消失)

get path # 获得节点的值 [可监听]
# -w  监听节点内容变化
# -s  附加次级信息

set  # 设置节点的具体值

stat # 查看节点状态

delete # 删除节点

deleteall # 递归删除节点

客户端界面

可以下载 prettyZoo-win.msi 进行操作,更直观

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

节点类型(持久 / 短暂 / 有序号 / 无序号)

在这里插入图片描述
1)分别创建 2个 普通节点(永久节点 + 不带序号)

create /sanguo "liubei"

注意:创建节点时,要赋值

2)获得节点的值

get /sanguo 

在这里插入图片描述

get -s /sanguo 

在这里插入图片描述
3)创建带序号的节点(永久节点 + 带序号)

先创建一个普通的根节点 /sanguo/weiguo,默认是 持久化,不带序号 的节点

create /sanguo/weiguo "caocao" 

创建 带序号的节点

create -s /sanguo/weiguo "caocao"

在这里插入图片描述
如果原来没有序号节点,序号从 0 开始依次递增。如果原节点下已有 2 个节点,则再排序时从 2 开始,以此类推

4)创建短暂节点( 短暂节点 + 不带序号 or 带序号)
创建 短暂的 不带序号的 节点

create -e /sanguo/weiguo "x1"

创建短暂的带序号的节点

create -es /sanguo/weiguo "x2"

5)修改 节点数据值

set /sanguo/weiguo0000000006 xiaowang 

在这里插入图片描述

监听器

1)节点的值变化监听

注册监听 /sanguo 节点数据变化

get -w /sanguo

修改 /sanguo 节点的数据
在这里插入图片描述
type:NodeDataChanged 代表 节点数据变化
在这里插入图片描述

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

监听/sanguo 节点的子节点变化

ls -w /sanguo

在这里插入图片描述

在这里插入图片描述
type:NodeChildrenChanged 子节点变化
在这里插入图片描述

节点删除与查看

# 创建节点
create /sanguo/jin
# 删除节点
delete /sanguo/jin  
# 递归 删除节点
deleteall /sanguo/shuguo

查看 节点状态

stat /sanguo 

在这里插入图片描述

客户端 API 操作

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.7.1</version>
</dependency>

  <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

创建 ZooKeeper 客户端

import lombok.SneakyThrows;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
public class DemoApplicationTests {


    // 注意:多个 zk服务器 用逗号分隔
    //      逗号前后 不能有空格
    private static String connectString =
            "192.168.111.101:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zkClient;

    @Before
    public void init() throws Exception {
        zkClient = new ZooKeeper (connectString, sessionTimeout, new Watcher () {
            @SneakyThrows
            @Override
            public void process(WatchedEvent watchedEvent) {
                //  收到 事件通知后的 回调函数(用户的业务逻辑)
                System.out.println (watchedEvent.getType () + "--"
                        + watchedEvent.getPath ());
                // 再次启动监听
                List<String> children = zkClient.getChildren ("/", true);
                for (String child : children) {
                    System.out.println (child);
                }

            }
        });
    }

    // 创建子节点
    @Test
    public void create() throws Exception {
        /**
         * 参数 1:要创建的节点的路径;
         * 参数 2:节点数据 ;
         * 参数 3:节点权限 ;
         * 参数 4:节点的类型
         *
         */
        String nodeCreated = zkClient.create ("/xiag",
                "shuaige".getBytes (), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT);

        Thread.sleep (Long.MAX_VALUE);
    }

    // 获取子节点并监听节点变化
    @Test
    public void getChildren() throws Exception {
        List<String> children = zkClient.getChildren ("/", true);
        for (String child : children) {
            System.out.println (child);
        }
        // 延时阻塞
        Thread.sleep (Long.MAX_VALUE);
    }

    // 判断 znode 是否存在
    @Test
    public void exist() throws Exception {
        Stat stat = zkClient.exists ("/atguigu", false);
        System.out.println (stat == null ? "not exist" : "exist");
    }
}



案例

服务器动态上下线

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DistributeClient {
    private static String connectString =
            "192.168.111.101:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zk = new ZooKeeper (connectString, sessionTimeout, new Watcher () {
        @Override
        public void process(WatchedEvent event) {

        }
    });
    private String parentNode = "/servers";

    public DistributeClient() throws IOException {
    }


    // 获取服务器列表信息
    // 获取 servers 的子节点信息,从中获取服务器信息列表
    public void getServerList() throws Exception {
        // 1 获取服务器子节点信息
        // 第一次 调用该方法时 注册监听事件、添加 回调函数
        // 然后 获取节点数据 运行下面的逻辑
        List<String> children = zk.getChildren (parentNode, event -> {
            // 监听的事件 发生时, 第一步 注册监听事件、添加 回调函数
            // 然后 再执行下面的业务!!必须 要每次都要注册!形成循环~
            try {
                getServerList ();
            } catch (Exception e) {
                throw new RuntimeException (e);
            }
        });
        // 2 存储服务器信息列表
        ArrayList<String> servers = new ArrayList<> ();
        // 3 遍历 所有节点,获取 节点中的主机名称信息
        for (String child : children) {
            byte[] data = zk.getData (parentNode + "/" + child,
                    false, null);
            if (data == null || data.length == 0) continue;
            servers.add (new String (data));
        }

        // 4 打印服务器列表信息
        System.out.println (servers);

    }

    // 业务功能
    public void business() throws Exception {
        System.out.println ("client is working ...");
        Thread.sleep (Long.MAX_VALUE);
    }

    public static void main(String[] args) throws Exception {
        // 1 获取 zk 连接
        DistributeClient client = new DistributeClient ();
        //注册监听事件
        client.getServerList ();
        // 2 业务进程启动
        client.business ();
    }
}

# 创建节点 /servers
create  /servers

在这里插入图片描述
在这里插入图片描述
删除一个节点
在这里插入图片描述

动态监听是否有流量


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

import java.io.IOException;

public class DistributeClient {
    private static String connectString =
            "192.168.111.101:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zk = new ZooKeeper (connectString, sessionTimeout, new Watcher () {
        @Override
        public void process(WatchedEvent event) {

        }
    });
    ;

    public DistributeClient() throws IOException {
    }


    public void hasFlow() throws Exception {
        // 第一次 调用该方法时 注册监听事件、添加 回调函数
        // 然后 获取节点数据 运行下面的逻辑
        byte[] data = zk.getData ("/hasFlow", event -> {
            // 监听的事件 发生时, 第一步 注册监听事件、添加 回调函数
            // 然后 再执行下面的业务!!必须 要每次都要注册!形成循环~
            try {
                hasFlow ();
            } catch (Exception e) {
                throw new RuntimeException (e);
            }
        }, null);

        String dataStr = new String (data);
        if ("false".equals (dataStr))
            System.out.println ("No Flow!");
        else if ("true".equals (dataStr))
            System.out.println ("Flow  is ok ");

    }

    // 业务功能
    public void business() throws Exception {
        System.out.println ("client is working ...");
        Thread.sleep (Long.MAX_VALUE);
    }

    public static void main(String[] args) throws Exception {
        // 1 获取 zk 连接
        DistributeClient client = new DistributeClient ();
        //注册监听事件
        client.hasFlow ();
        client.business ();
    }
}


# 先创建节点 /hasFlow 
create  /hasFlow  ""

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/36191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【通信】基于matlab模拟室内VLC模型(含BER和SNR)附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

短视频平台如何保证内容安全问题?

本文首发于&#xff1a;行者AI谛听 近些年&#xff0c;短视频的安全意识越来越强&#xff0c;随着各大平台的用户暴增&#xff0c;平台的一些审核及运营都有着巨大的挑战。那么对于平台来说&#xff0c;如何保证内容安全呢&#xff1f; 很多短视频平台的内容有着爆炸式的增长&a…

Vue3动态路由(Vite+Vue3+TS+Mock)

一、动态路由简介 Vue通过路由进行页面管理&#xff0c;不同的路由绑定到不同的页面。一般来说&#xff0c;前端直接写好的路由为静态路由&#xff0c;在不修改代码的情况下&#xff0c;路由表是不会改变的。对于不需要动态改变路由表的网站&#xff0c;静态路由就已经足够了&…

关于数据治理工具的选型,你了解多少?

数据治理的本质是盘点数据资产、治理数据质量&#xff0c;实施数据全生命周期的管理&#xff0c;这里面包括了建组织、立制度或者使用一款数据治理的软件帮助企业开展数据治理的相关工作等等。根据不同的数据治理项目特点&#xff0c;会用到不同的技术或工具。拥有一套趁手好用…

功率放大器的三种类型是什么意思

很多人都知道功率放大器&#xff0c;但是却不知道同样都是功率放大器&#xff0c;但是名字相同&#xff0c;作用却是完全不同的&#xff0c;总是会有工程师发出这样的疑问“功率放大器的三种类型是什么以及功率放大器怎么选择型号”等等&#xff0c;今天就请安泰电子来为我们解…

SpringBoot整合Alibaba-Dubbo和Apache-Dubbo

文章目录1 Alibaba整合Dubbo1.1 服务提供者1.1.1 服务提供者接口1.1.2 服务提供者实现类1.1.2.1 项目结构图1.1.2.2 pom.xml1.1.2.3 服务实现类1.1.2.4 配置文件1.1.2.5 启动类1.2 服务消费者1.2.1 项目结构图示1.2.2 请求入口1.2.3 配置文件1.2.4 启动类2 Apache整合Dubbo2.1 …

Pytorch学习笔记(四)官方60min入门教程之图像分类器

你已经了解了如何定义神经网络&#xff0c;计算损失值和网络里权重的更新。 现在你也许会想应该怎么处理数据&#xff1f; 通常来说&#xff0c;当你处理图像&#xff0c;文本&#xff0c;语音或者视频数据时&#xff0c;你可以使用标准 python 包将数据加载成 numpy 数组格式…

Web3中文|10月份超48%的以太坊NFT交易额是假的

来源 | cryptoslate 编译 | BoweniNFTnews.com 10月份全球NFT销售额超过8.5亿美元&#xff0c;总交易量约为300万笔。 NFT月销售额 数据来源&#xff1a;Footprint Analytics 在市场状况不佳的情况下&#xff0c;仍有大量唯一买家与卖家。10月份有超过100 万的唯一买家和卖家…

第九章 哈希表 AcWing 1532. 找硬币

第九章 哈希表 AcWing 1532. 找硬币 原题链接 AcWing 1532. 找硬币 算法标签 哈希表 双指针 思路 使用哈希表集合 用一个哈希表存储硬币。 对于每一枚硬币 x&#xff0c;判断在集合中是否存在 y&#xff0c;使得 x y m。 如果存在&#xff0c;则是一组解&#xff0c;判…

Linux Command htpasswd 创建密码文件

文章目录Linux Command htpasswd 创建密码文件1. 简介2. 安装3. 语法4. 选项5. 示例6. 其他Linux Command htpasswd 创建密码文件 1. 简介 htpasswd是Apache的Web服务器内置的工具,用于创建和更新储存用户名和用户基本认证的密码文件。 2. 安装 centos 7、 redhat&#xff…

MCE | 靶向 cGAS-STING 通路或可治疗渐冻症

自从 12 年前被发现以来&#xff0c;STING 途径就吸引了众多TOP生物学家的关注&#xff0c;去年 3 月&#xff0c;陈志坚教授带领的研究团队和其合作者在 Nature 上同日发表三篇论文&#xff0c;让 cGAS-STING 通路大火了一把&#xff0c;并被认为是未来十年内肿瘤免疫靶点的“…

指静脉当前遇到的问题

一、《基于改进残差网络的指静脉识别算法》_易芮 2020.5.20 ①采集到的指静脉图像质量不高"边缘曝光"及手指的自由度导致图像存在的偏移问题 &#xff08;传统的指静脉识别技术是基于图像的纹理、特征点等细节进行特征提取&#xff0c;若图像质量较差的话&#xff…

thymeleaf抽取公共页面

thymeleaf抽取公共页面Thymeleaf中th:include、th:replace、th:insert、th:fragment用法及区别th:include、th:replace、th:insert区别在开发Web网站的时候&#xff0c;HTML页面有很多是相同的&#xff0c;如果每一个页面都写一遍&#xff0c;不仅非常麻烦&#xff0c;而且非常…

基于粒子群算法的城轨列车牵引多目标能耗优化问题附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

python基础之元组

文章目录一、元组注意&#xff1a;二、创建元组怎么验证这个变量真的是一个元组类型&#xff1a;三、使用迭代遍历元组四、应用场景五、格式化字符串后面的&#xff08;&#xff09;本质上就是元组六、元组和列表之间的转换一、元组 元组&#xff08;Tuple&#xff09;与列表类…

Python(PyQt5)制作帮助文档查看器(可显示后缀名为md的文件)同时显示文本和图片

先看完整效果图: 帮助文档查看器是很多程序中必备要素,而利用Qt中的QTreeView组件可以很方便的查看文件,而QTextBrowser可以直接显示格式化的MarkDown文本。因此可以利用这两个组件制作一个帮助文件查看器。 未优化 效果图: 问题优化: 你会发现QT treeView列宽设置不成功问题…

Mybatis-Plus 06 条件构造器和常用接口

一、wapper介绍 Wrapper &#xff1a; 条件构造抽象类&#xff0c;最顶端父类 AbstractWrapper &#xff1a; 用于查询条件封装&#xff0c;生成 sql 的 where 条件 ​ QueryWrapper &#xff1a; 查询条件封装 ​ UpdateWrapper &#xff1a; Update 条件封装 AbstractL…

PG::Inclusiveness

nmap -Pn -p- -T4 --min-rate1000 192.168.134.14 nmap -Pn -p 21,22,80 -sCV 192.168.134.14 80端口是默认页面&#xff0c;先查看21端口FTP服务的匿名登录&#xff0c;并未发现可利用信息。 继续查看80端口&#xff0c;在robots.txt中得到提示。 https://www.howtogeek.co…

【Kubernetes | Pod 系列】Pod的 YAML 清单文件详解

目录3. Pod的 YAML 清单文件3.1 获取资源对象 YAML3.2 解析 YAML 清单文件&#xff08;1&#xff09;apiVersion查看 Kubernetes API 中全部的 API 组&#xff08;2&#xff09;kind查看 Kubernetes 中全部的对象资源类型&#xff08;3&#xff09;metadata&#xff08;4&#…

SpringBoot整合Mybatis方式2:使用注解方式整合Mybatis

SpringBoot整合Mybatis简介SpringBoot整合Mybatis方式2&#xff1a;使用注解方式整合Mybatis1.先用idea创建一个添加mybatis需要的相关依赖的工程。2.准备数据库和表3.创建表映射类4.创建mapper代理接口5.创建Service层和Service的实现层6.创建控制层&#xff08;也就是web层&a…