ZooKeeper学习

本文均总结自B站,有些图片是在视频上截取的。
B站id:BV1PW411r7iP

ZooKeeper

1.入门

1.1概述

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

1.2特点

ZooKeeper学习_第1张图片

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

1.3数据结构

ZooKeeper的数据模型结构于Unix文件系统很类似,整体上可以看做是一棵树,每个节点称作一个ZNode。每个ZNode默认能够存储1MB的数据,每个ZNde都可以通过其路径唯一标识。
ZooKeeper学习_第2张图片

1.4 应用场景

  1. 在分布式环境下,经常需要对应用/服务进行统一命名,便于识别。
  2. 配置文件同步,将配置文件写入ZooKeeper上的ZNode。各个客户端服务器监听这个ZNode。一旦这个ZNode中的数据被修改,ZooKeeper将通知各个客户端服务器。
  3. ZooKeeper可以实时监听控制节点的变化,将节点信息写入ZNode,监听这个ZNode获取它的实时变化。
  4. 可以实时洞察到服务器上下线的变化。
  5. 负载均衡,ZooKeeper记录着每台服务器的访问数,让访问最少的服务器去处理最新的客户端请求。

1.5下载地址

ZooKeeper下载地址

2.ZooKeeper安装

在安装前需要安装好JDK。

2.1 上传&解压

将下载完成的ZooKeeper上传到Linux并且解压。
在这里插入图片描述

2.2修改配置文件

  1. 将conf文件夹下的zoo_sample.cfg重命名为zoo.cfg
 mv zoo_sample.cfg zoo.cfg
  1. 修改zoo.fig文件中的dataDir路径
vim zoo.fig

改为:

dataDir=自己的路径/zkData
  1. 在zookeeper文件下新建zkData文件
mkdir zkData

2.3启动

  1. 启动服务器(zookeeper文件下)
 bin/zkServer.sh start

ZooKeeper学习_第3张图片
2. 关闭服务器(zookeeper文件下)

bin/zkServer.sh stop
  1. 启动客户端(zookeeper文件下)
 bin/zkServer.sh 

ZooKeeper学习_第4张图片
4. 退出客户端

quit

2.4 zoo.cfg参数解读

ZooKeeper学习_第5张图片

2.5 分布式安装

安装步骤跟上方安装步骤一。

  1. 需要在zkData文件下创建myid文件
touch myid
  1. 编辑myid
vim myid
  1. 在myid中添加服务号(id唯一标识)
2
  1. 在每个服务器中都添加
    ZooKeeper学习_第6张图片
    在这里插入图片描述
  2. 分别启动每台服务器的ZooKeeper
    查看状态以及是leader或者follower
bin/zkServer.sh status

2.6 客户端操作语言

  1. 启动客户端
/bin zkCli.sh
  1. 查看所有操作命令
help
  1. 查看zNode中的详情
ls /
  1. 查看节点详细数据
ls2 /
  1. 创建普通节点
create /demo "value"

create /path1/path2 "value"

查看zNodeZooKeeper学习_第7张图片
6. 获取节点的值

get /path
  1. 创建短暂节点
    当前客户端与服务器Server断开了连接就会删除。
create -e /path "value"
  1. 创建带有序号的节点
create -s /path "value"
  1. 修改节点值
set /path "new Value"
  1. 监听节点数据变化
get /path watch
  1. 监听子节点数量的变化
ls /path watch
  1. 删除节点
delete /path
  1. 递归删除节点
    如果一个zNode下有子节点,就没法需要使用rmr删除这个zNode
rmr /path
  1. 查看节点状态
stat /path

3. 内部原理

3.1选举机制

  1. 半数机制:ZooKeeper集群中,半数以上节点存活,集群可用,所以ZooKeeper适合安装奇数服务器。
  2. ZooKeeper虽然在配置文件中并没有指定Master和Slave。但是,Zookeeper工作时,只有一个节点为Leader,其它的都是Follower,Leader是通过内部的选举机制临时产生的。如果有五台服务器一次叠加,则第三个为Follower(Master),无论后面添加的服务器性能再优。

3.2 节点类型

序号可以被用于为所有的时间进行全部排序,这样客户端可以通过顺序号推断事件的顺序。

3.2.1持久

  1. 持久化目录节点:客户端与服务器断开连接后,创建的节点不删除。
  2. 持久化顺序编号目录节点:客户端与ZooKeeper断开连接后,该节点依旧存在,只是ZooKeeper给该节点名称进行顺序编号。

3.2.2短暂

  1. 客户端与服务器断开连接后,创建的节点自己删除。
  2. 临时顺序编号目录节点:客户端与ZooKeeper断开连接后,该节点被删除,只是ZooKeeper给该节点名称进行顺序编号。

3.3Stat结构体

图片来自B站截图

ZooKeeper学习_第8张图片在这里插入图片描述
ZooKeeper学习_第9张图片

3.4监听器原理

ZooKeeper学习_第10张图片

3.5写数据流程

ZooKeeper学习_第11张图片

4.API

4.1 Maven依赖

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

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

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

4.2 建立连接

 //ZooKeeper连接信息(集群用逗号隔开)
    private String conn="your port:2181";

//    超时时间 单位毫秒
    private int sessionTimeout = 2000;

    private ZooKeeper zkClick;

    @Test
    public void init() throws IOException {
        zkClick = new ZooKeeper(conn,sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
            
        });
        System.out.println("连接状态:"+zkClick.getState());
    }

当连接状态为Connecting时就成功了,不过我看别人博客有写是Connected才行,具体原因没找到,
反正我的Connecting可以使用。

4.3 创建节点

    @Test
    public void testCreateNode() throws KeeperException, InterruptedException {
    //参数分别是:路径,value,权限,短暂/持久(普通)/短暂有序/持久(普通)有序
        String s = zkClick.create("/javaNode", "haoshuaio".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(s);
    }

4.4 监听子节点的变化

public class zookeeper {
    //ZooKeeper连接信息(集群用逗号隔开)
    private String conn="your port:2181";

//    超时时间 单位毫秒
    private int sessionTimeout = 2000;

    private ZooKeeper zkClick;

    @Before
    public void init() throws IOException {
        zkClick = new ZooKeeper(conn,sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {

                List<String> children;
                try {
                        children = zkClick.getChildren("/",true);
                    for (String child : children) {
                            System.out.println(child);

                        }
                    System.out.println("--------------------");
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            }
        });
        System.out.println("连接状态:"+zkClick.getState());
    }
    
/**
     * 获取子节点并监听变化
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void getDataAndWatch() throws KeeperException, InterruptedException {
//        获取目录下的子节点,并选择是否监听
        List<String> children = zkClick.getChildren("/", true);

        for (String child : children) {
            System.out.println(child);
        }

        Thread.sleep(Long.MAX_VALUE);
    }

4.5 判断Znode是否存在

  /**
     * 判断Znode是否存在
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void exist() throws KeeperException, InterruptedException {
        Stat stat= zkClick.exists("/demo0421", false);
        System.out.println(stat==null ? "没有" : "有");
    }

你可能感兴趣的:(zookeeper)