Zookeeper3.5.9的部署和基本使用

一.简介

在这里插入图片描述

二.部署

1.单机部署

  • 下载:3.5.5版本后下载 -bin文件 :apache-zookeeper-3.5.9-bin.tar.gz 2021-01-15 03:46 9.2M
  • 进入配置文件夹 cd conf
  • 复制配置文件cp zoo_sample.cfg zoo.cfg
  • 修改配置文件
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/software/server/apache-zookeeper-3.5.9-bin/data
clientPort=2181
#会话超时时间
#minSessionTimeout=4000
#maxSessionTimeout=40000
  • 启动
    cd bin
    sh zkServer.sh start
    sh zkServer.sh status
  • 停止
    sh zkServer.sh stop
  • 打开客户端
    sh zkCli.sh
  • 查看根节点下的子节点(Znode维系在内存和磁盘中)
    ls /
  • 根节点下创建子节点(必须存储配置信息或节点描述)
    create /log 'log servers'
  • 子节点下创建子节点(必须存储配置信息或节点描述)
    create /log/log01 ''
  • 删除节点(要求没有子节点)
    delete /music
  • 删除节点
    rmr /music
  • 查看节点详情
    get /picture
  • 修改数据
    set /picture 'ps'

2.分布式部署

  • 下载:3.5.5版本后下载 -bin文件 :apache-zookeeper-3.5.9-bin.tar.gz 2021-01-15 03:46 9.2M
  • 进入配置文件夹 cd conf
  • 复制配置文件cp zoo_sample.cfg zoo.cfg
  • 修改配置文件
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/software/server/apache-zookeeper-3.5.9-bin/data
clientPort=2181
#2888选举端口,3888原子广播端口
server.1=172.18.29.152:2888:3888
server.2=172.18.29.150:2888:3888
server.3=172.18.29.153:2888:3888
  • 创建mkdir /usr/local/software/server/apache-zookeeper-3.5.9-bin/data
  • 进入cd /usr/local/software/server/apache-zookeeper-3.5.9-bin/data
  • 分别配置 vim myid
#server.1 其它文件以此类推
1
  • 将内容传到其它节点
    scp -r apache-zookeeper-3.5.9-bin root@172.18.29.150:/usr/local/software/server/
    scp -r apache-zookeeper-3.5.9-bin root@172.18.29.153:/usr/local/software/server/
  • 再修改myid
  • 通过sh zkServer.sh status查看状态

三.基本属性

1.节点详细信息

cZxid: 创建节点的事务id(全局递增,增删改公用一个id)
ctime: 创建节点的时间
mZxid: 修改节点的事务id(全局递增,增删改公用一个id)
mtime: 修改节点的时间
pZxid: 子节点的增删事务id(全局递增,增删改公用一个id)
cversion: 子节点的增删次数
dataversion: 当前节点数据的修改次数
aclversion: 当前节点的权限修改次数
ephemeralOwner: 标记当前节点是否是临时节点(默认是0,临时节点为sessionID)
dataLength: 数据的字节个数
numChildren: 子节点个数

2.节点类型

  • 非顺序节点:(默认)
    持久节点(默认) PERSISTENT
    临时节点 create -e /video ''(不能有子节点,客户端退出消失) EPHEMERAL
  • 顺序节点:create -s /log/l ''
    持久节点(默认)PERSISTENT_SEQUENCIAL
    临时节点 create -e /video ''(不能有子节点,客户端退出消失) EPHEMERAL_SEQUENCIAL

四.API基本操作

  • 引入依赖:
<properties>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.5.9</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>

    </dependencies>
  • 单元测试
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class ZookeeperDemo1 {

    private ZooKeeper zk;

    /**
     * 创建连接
     * @throws IOException
     * @throws InterruptedException
     */
    @Before
    public void connect() throws IOException, InterruptedException {
        //connectString - 连接地址+端口号
        //sessionTimeout - 会话超时时间(多长时间连不上就断开),默认单位是毫秒4000~40000之间
        //watcher - 监控者,判断到底连上没有
        CountDownLatch cd1 = new CountDownLatch(1);
        zk = new ZooKeeper("39.97.169.72:2181", 5000, watchedEvent -> {
            if(watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected){
                System.out.println("连接成功~");
                cd1.countDown();
            }
        });
        cd1.await();
    }

    /**
     * 创建节点
     */
    @Test
    public void createNode() throws KeeperException, InterruptedException {
        //path:创建的节点路径
        //data:节点数据
        //acl:权限
        //createMode:节点类型
        String nameNode = zk.create(
                "/video","video server".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT_SEQUENTIAL);
        System.out.println("持久节点名称:"+nameNode);
    }

    /**
     * 删除节点
     */
    @Test
    public void deleteNode() throws KeeperException, InterruptedException {
        //version - 数据版本 :dataversion
        zk.delete("/video0000000004",0);
        //version= -1 强制删除
        zk.delete("/video0000000004",-1);
    }

    /**
     * 获得所有子节点
     */
    @Test
    public void getChildrenNode() throws KeeperException, InterruptedException {
        List<String> children = zk.getChildren("/", null);
        for(String c:children){
            System.out.println(c);
        }
    }

    /**
     * 判断节点是否存在
     */
    @Test
    public void exists() throws KeeperException, InterruptedException {
        //返回节点信息 节点不存在返回null 否则返回信息
        Stat s = getNodeMessage();
        if(s==null){
            System.out.println("节点不存在");
        }
        System.out.println("节点存在 "+ s.toString());
    }

    /**
     * 获得节点详细信息
     * @return
     * @throws KeeperException
     * @throws InterruptedException
     */
    public Stat getNodeMessage() throws KeeperException, InterruptedException {
        Stat stat = zk.exists("/log",null);
        return stat;
    }

    /**
     * 获取节点数据
     */
    @Test
    public void getData() throws KeeperException, InterruptedException {
        byte[] data = zk.getData("/log", null, getNodeMessage());
        System.out.println(new String(data));
    }

    /**
     * 修改(更新)节点数据
     */
    public void setData() throws KeeperException, InterruptedException {
        //返回值是节点信息
        Stat stat = zk.setData("/log", "log server".getBytes(), -1);
    }


}

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.notification.RunListener;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class ZookeeperDemo2 {

    private ZooKeeper zk;

    /**
     * 创建连接
     * @throws IOException
     * @throws InterruptedException
     */
    @Before
    public void connect() throws IOException, InterruptedException {
        //connectString - 连接地址+端口号
        //sessionTimeout - 会话超时时间(多长时间连不上就断开),默认单位是毫秒4000~40000之间
        //watcher - 监控者,判断到底连上没有
        CountDownLatch cd1 = new CountDownLatch(1);
        zk = new ZooKeeper("39.97.169.72:2181", 5000, watchedEvent -> {
            if(watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected){
                System.out.println("连接成功~");
                cd1.countDown();
            }
        });
        cd1.await();
    }

    /**
     * 监控当前节点数据是否发生变化
     */
    @Test
    public void nodeDataChanged() throws KeeperException, InterruptedException {
        while (true){
            CountDownLatch cdl1 = new CountDownLatch(1);
            zk.getData("/log", new Watcher() {
                //将数据的变化封装成一个事件进行传递
                @Override
                public void process(WatchedEvent watchedEvent) {
                    if(watchedEvent.getType() == Event.EventType.NodeDataChanged){
                        System.out.println("节点数据更新~");
                        cdl1.countDown();
                    }
                }
            }, null);
            cdl1.await();
        }
    }

    /**
     * 监控子节点的数据是否发生变化
     */
    @Test
    public void childNodeDataChanged() throws KeeperException, InterruptedException {
        while (true) {
            CountDownLatch cdl1 = new CountDownLatch(1);
            zk.getChildren("/log", new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged) {
                        System.out.println("子节点发生变化~~~");
                        cdl1.countDown();
                    }
                }
            });
            cdl1.await();
        }
    }

    /**
     * 监控一个节点的增删变化
     */
    @Test
    public void nodeChanged() throws KeeperException, InterruptedException {
        while (true){
        CountDownLatch cdl1 = new CountDownLatch(1);
        zk.exists("/video", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                if(watchedEvent.getType() == Event.EventType.NodeCreated){
                    System.out.println("新增这个节点");
                }else {
                    System.out.println("删除这个节点");
                }
                cdl1.countDown();
            }
        });
        cdl1.await();
        }
    }
}

五.选举机制

1.过程

  • 每个节点会寻找当前节点的最大事务id
  • 每个节点都会推荐自己为leader,同时将节点信息发给其它节点,进行比较,

2.选举信息

  • 最大事务 - Zxid
  • 选举编号 - myid
  • 逻辑时钟值 - 保证选举在同一轮次上(会将过多轮比较)

3.比较原则

  • 先比较最大事务id,选更大的
  • 其次比较myid,选更大的
  • 当一个节点胜过一半及以上的节点的时候,那么这个节点就会成为leader - 选举过半性(原先总数的过半)
  • 当leader已经存在,后续都是follower
  • 当满足过半存活(原先总数的过半)才会进行选举(防止脑裂)

4.节点状态

looking/voting - 选举状态
follower - 追随者
leader - 领导者
observer - 观察者

六,ZAB协议原子广播

1.过程

  • leader将写操作记录道本地日志log.xxx,记录成功发送道队列
  • follower会执行队列中的操作(写入本地日志)
  • leader如果收到半数及以上的follower的成功信号,那么leader就会命令每个follower执行这个操作
  • leader没有收到半数的follower的成功信号,那么leader就会命令每一个follower删除刚才的操作

2.目的

  • 保证集群中的所有节点的数据一致性(C)

3.崩溃恢复

每个leader被选举出来之后,都会被分配一个全局递增的编号-epochid,分发给每一个follower,若出现脑裂情况,则自动kill掉epochid小的leader并将其转化成follower,保证集群中只有一个leader。

  • epochid存储在version文件夹中
  • cZxid由64位的2禁止数字组成
  • epochid == 高32位
  • 真正的事务id == 低32位

七.查看二进制文件日志

  • 每更换一次leader,就会产生一个新的log以及snapshot文件
cd lib
cp zookeeper-3.5.9.jar /usr/local/software/server/apache-zookeeper-3.5.9-bin/data/version-2/
cp slf4j-api-1.7.25.jar /usr/local/software/server/apache-zookeeper-3.5.9-bin/data/version-2/
cp zookeeper-jute-3.5.9.jar /usr/local/software/server/apache-zookeeper-3.5.9-bin/data/version-2/

cd /usr/local/software/server/apache-zookeeper-3.5.9-bin/data/version-2/
#查看日志:记录操作
java -cp .:zookeeper-3.5.9.jar:slf4j-api-1.7.25.jar:zookeeper-jute-3.5.9.jar org.apache.zookeeper.server.LogFormatter log.200000001
#查看快照:记录节点信息
java -cp .:zookeeper-3.5.9.jar:slf4j-api-1.7.25.jar:zookeeper-jute-3.5.9.jar org.apache.zookeeper.server.SnapshotFormatter snapshot.100000000

在这里插入图片描述

八.观察者Observer

1.特点

  • 不参与投票也不选举,只干活
  • 宕机个数不影响服务

2.配置

  • 修改配置文件vim zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/software/server/apache-zookeeper-3.5.9-bin/data
clientPort=2181
#2888选举端口,3888原子广播端口
peerType=observer
server.1=172.18.29.152:2888:3888:observer
server.2=172.18.29.150:2888:3888
server.3=172.18.29.153:2888:3888

九.远程操作

  • 下载nc
    yum install -y nc
  • 修改启动文件
    vim zkServer.sh
  • 添加内容
ZOOMAIN="-Dzookeeper.4lw.commands.whitelist=* ${ZOOMAIN}"

在这里插入图片描述

  • 查看其它节点的状态
echo stat | nc 172.18.29.150 2181
  • 查看其它节点是否存活
echo ruok | nc 172.18.29.150 2181
#返回imok表存活
imok
  • 查看其它节点配置信息
echo conf | nc 172.18.29.150 2181
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
zookeeper-3.4.5-cdh5.16.2.tar.gz 是一个压缩文件,其中包含的是 ZooKeeper 分布式协调服务的安装包。ZooKeeper 是一个开源的分布式应用程序协调服务,它为分布式系统提供了高度可靠的协调功能。 在这个压缩文件中,"zookeeper-3.4.5" 表示 ZooKeeper 的版本号为 3.4.5,而 "cdh5.16.2" 则表示此版本是基于 Cloudera 发行版 5.16.2。Cloudera 是一个提供基于 Apache Hadoop 的大数据解决方案的公司,他们针对 ZooKeeper 进行了一些修改和适配,以便更好地与其它 Cloudera 软件产品集成。 .tar.gz 是一个常见的压缩格式,通常用于在 Linux 系统中打包和分发文件。使用该格式,文件被打包成一个.tar 文件,然后使用 gzip 压缩算法进行压缩,最终生成一个.tar.gz 文件。 为了使用这个安装包,我们可以按照以下步骤进行操作: 1. 首先,我们需要解压缩.tar.gz 文件。可以使用命令 "tar -zxvf zookeeper-3.4.5-cdh5.16.2.tar.gz" 解压缩该文件。执行完该命令后,会生成一个目录,其中包含了 ZooKeeper 安装包的所有文件。 2. 进入解压后的目录,在其中可以找到 ZooKeeper 的配置文件、示例配置文件和一些其他的脚本文件。 3. 根据自己的需求,修改配置文件。一般需要修改的配置包括 ZooKeeper 服务器集群的地址和端口,以及一些日志和存储文件的路径。 4. 配置完毕后,可以启动 ZooKeeper 服务器。通过运行脚本文件 "bin/zkServer.sh",以指定的模式(例如单机模式、主从模式等)启动服务器。 5. 一旦服务器启动,您就可以使用 ZooKeeper 客户端与其进行交互了。客户端提供了一组命令,可以帮助您管理分布式系统中的节点和数据。 总之,zookeeper-3.4.5-cdh5.16.2.tar.gz 是一个用于安装和部署 ZooKeeper 的文件压缩包,通过解压缩、配置和启动等步骤,您可以在您的分布式系统中使用 ZooKeeper 提供的协调功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值