Zookerper

1.简介

  1. zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apcahe项目<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23124036/1647876220439-1d544ba0-6461-452a-8527-316e80ac8b60.png#clientId=u4dd446b7-4032-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=454&id=u8273ab25&margin=%5Bobject%20Object%5D&name=image.png&originHeight=568&originWidth=1060&originalType=binary&ratio=1&rotation=0&showTitle=false&size=541561&status=done&style=none&taskId=u113ab0a6-eba5-4114-9950-cc99919764d&title=&width=848)

2. 工作机制

  1. 从设计模式的角度理解:zookeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据发生变化,zookeeper就负责通知已经注册的观察者,做出相应的反应。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23124036/1647876240312-9aaa0cf3-9d6d-4902-b977-ffb748683851.png#clientId=u4dd446b7-4032-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=483&id=u23026cba&margin=%5Bobject%20Object%5D&name=image.png&originHeight=604&originWidth=1051&originalType=binary&ratio=1&rotation=0&showTitle=false&size=231942&status=done&style=none&taskId=u63ac4caf-751b-4a2d-bbcd-a552ea5520a&title=&width=840.8)

3.特点

image.png

  • zookeeper:一个领导者,多个追随者组成
  • 集群中只要有半数以上节点存活,zookeeper就能正常工作,所以zookeeper推荐安装奇数太服务器
  • 全局数据一致性:每个server保存一份相同的数据副本,client无论连接到哪一台服务器,获取到的数据都是一致的
  • 更新请求顺序执行:来自同一个client的更新请求按其发送的顺序依次执行
  • 数据更新原子性:follower更新数据,要么成功,要么失败
  • 实时性:统一时间范围内,client能读取到最新的数据

    4. 数据结构

    zookeeper数据模型的结构与Linux文件系统类似,整体上可以看做是一棵树,每个节点看做一个ZNode。每个ZNode默认可以存储1MB数据,通过其路径唯一标识
    image.png

    5 应用

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

5.1 统一命名服务

image.png

5.2 统一配置管理

image.png

5.3 统一集群管理

image.png

5.4 服务器动态上下线

image.png

5.5 软负载均衡

image.png

6.本地化安装

6.1 下载地址

  1. https://zookeeper.apache.org/

6.2 安装

  • 解压到指定目录
    1. tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/module/
  • 修改名称
    1. mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7
  • 修改配置
    1. 拷贝 /opt/module/zookeeper-3.5.7/conf 这个路径下的 zoo_sample.cfg 为 zoo.cfg;
      1. cp zoo_sample.cfg zoo.cfg
  1. 在/opt/module/zookeeper-3.5.7/这个目录上创建 zkData 文件夹

    1. mkdir zkData
    2. # 复制文件路径
    3. cd zkData
    4. pwd
  1. 打开 zoo.cfg 文件,修改 dataDir 路径:(指定数据存放目录) ``` zookeeper-3.5.7]$ vim zoo.cfg

修改如下内容:

dataDir=/opt/module/zookeeper-3.5.7/zkData

  1. <a name="a5fe1881"></a>
  2. ### 6.3 启动
  3. - 启动zookbin/zkServer.sh start

bin/zkServer.sh start

  1. - 查看进程是否启动

[zookeeper-3.5.7]$ jps

启动之前

[root@bogon conf]# jps 1503 Jps [root@bogon conf]#

启动之后

[root@bogon conf]# jps 1530 QuorumPeerMain 1562 Jps [root@bogon conf]#

  1. - 查看状态

[root@bogon conf]# ../bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.7.0_rw/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Mode: standalone

  1. <br />至此单机版服务器启动完毕,接下来启动客户端
  2. - 启动客户端

[root@bogon conf]# ../bin/zkCli.sh

  1. - 退出客户端

[zk: localhost:2181(CONNECTED) 1] quit

  1. - 停止 Zookeeper

[root@bogon conf]# ../bin/zkServer.sh stop ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.7.0_rw/bin/../conf/zoo.cfg Stopping zookeeper … STOPPED [root@bogon conf]# ../bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /opt/module/zookeeper-3.7.0_rw/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Error contacting service. It is probably not running. [root@bogon conf]#

  1. <a name="49b9e74c"></a>
  2. ### 6.4 配置文件参数解读

The number of milliseconds of each tick

tickTime=2000 # 通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒

The number of ticks that the initial

synchronization phase can take

initLimit=10 # LF初始通信时限:Leader和Follower初始通信时,能容忍的最多心跳数

The number of ticks that can pass between

sending a request and getting an acknowledgement

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

the directory where the snapshot is stored.

do not use /tmp for storage, /tmp here is just

example sakes.

dataDir=/opt/module/zookeeper-3.7.0_rw/zkData # 保存Zookeeper中的数据 注意:默认的tmp目录,容易被Linux系统定期删除,所以一般不用默认的tmp目录。

the port at which the clients will connect

clientPort=2181 # 客户端连接端口,通常不做修改。

the maximum number of client connections.

increase this if you need to handle more clients

maxClientCnxns=60

#

Be sure to read the maintenance section of the

administrator guide before turning on autopurge.

#

http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

  1. <a name="1fc40b5a"></a>
  2. ## 7 集群化安装
  3. - 集群规划<br />在 hadoop102、hadoop103 和 hadoop104 三个节点上都部署 Zookeeper。
  4. - 解压安装
  5. 1. 解压 Zookeeper 安装包到/opt/module/目录下

[atguigu@hadoop102 software]$ tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/module/

  1. 2. 修改 apache-zookeeper-3.5.7-bin 名称为 zookeeper-3.5.7

[atguigu@hadoop102 module]$ mv apache-zookeeper-3.5.7-bin/ zookeeper-3.5.7

  1. - 配置服务器编号
  2. 1. 在/opt/module/zookeeper-3.5.7/这个目录下创建 zkData

[atguigu@hadoop102 zookeeper-3.5.7]$ mkdir zkData

  1. 2. 在/opt/module/zookeeper-3.5.7/zkData 目录下创建一个 myid 的文件

[atguigu@hadoop102 zkData]$ vi myid

在文件中添加与 server 对应的编号(注意:上下不要有空行,左右不要有空格)

例如:2

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

  1. 3. 拷贝配置好的 zookeeper 到其他机器上

[atguigu@hadoop102 module ]$ xsync zookeeper-3.5.7

并分别在 hadoop103、hadoop104 上修改 myid 文件中内容为 3、4

  1. - 配置zoo.cfg
  2. 1. 重命名/opt/module/zookeeper-3.5.7/conf 这个目录下的 zoo_sample.cfg zoo.cfg

[atguigu@hadoop102 conf]$ mv zoo_sample.cfg zoo.cfg

  1. 2. 打开 zoo.cfg 文件

[atguigu@hadoop102 conf]$ vim zoo.cfg

修改数据存储路径配置

dataDir=/opt/module/zookeeper-3.5.7/zkData

增加如下配置

#################cluster

server.2=hadoop102:2888:3888 # hadoop102 没配置的话 换成主机ip server.3=hadoop103:2888:3888 server.4=hadoop104:2888:3888



   3.  配置参数解读

server.A=B:C:D。 A 是一个数字,表示这个是第几号服务器; 集群模式下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是哪个 server。 B 是这个服务器的地址; C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口; D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。



   4.  同步配置文件 
-  集群操作 
   1.  分别启动 Zookeeper

[atguigu@hadoop102 zookeeper-3.5.7]$ bin/zkServer.sh start [atguigu@hadoop103 zookeeper-3.5.7]$ bin/zkServer.sh start [atguigu@hadoop104 zookeeper-3.5.7]$ bin/zkServer.sh start



   2.  查看状态

[atguigu@hadoop102 zookeeper-3.5.7]# bin/zkServer.sh status JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Mode: follower

[atguigu@hadoop103 zookeeper-3.5.7]# bin/zkServer.sh status JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Mode: leader

[atguigu@hadoop104 zookeeper-3.4.5]# bin/zkServer.sh status JMX enabled by default Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg Mode: follower



-  编写集群启动脚本 
   1.  在 hadoop102 的/home/atguigu/bin 目录下创建脚本

[atguigu@hadoop102 bin]$ vim zk.sh

内容

case $1 in “start”){ for i in hadoop102 hadoop103 hadoop104 do echo ————— zookeeper $i 启动 —————— ssh $i “/opt/module/zookeeper-3.5.7/bin/zkServer.sh start” done };;

“stop”){ for i in hadoop102 hadoop103 hadoop104 do echo ————— zookeeper $i 停止 —————— ssh $i “/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop” done };;

“status”){ for i in hadoop102 hadoop103 hadoop104 do echo ————— zookeeper $i 状态 —————— ssh $i “/opt/module/zookeeper-3.5.7/bin/zkServer.sh status” done };; esac



   2.  增加脚本执行权限

[atguigu@hadoop102 bin]$ chmod u+x zk.sh



   3.  Zookeeper 集群启动脚本

[atguigu@hadoop102 module]$ zk.sh start



   4.  Zookeeper 集群停止脚本

[atguigu@hadoop102 module]$ zk.sh stop



<a name="80d4c9a8"></a>
## 8 选举机制

- 第一次启动

![image.png](https://cdn.nlark.com/yuque/0/2022/png/23124036/1647876567966-257a1d0e-c7ef-4e0d-a1d9-9bf55e84c193.png#clientId=u4dd446b7-4032-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=415&id=u1c26219b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=519&originWidth=1116&originalType=binary&ratio=1&rotation=0&showTitle=false&size=282850&status=done&style=none&taskId=u6c80a86a-06c0-4ae9-8298-7618acd729f&title=&width=892.8)

- 非第一次启动

![image.png](https://cdn.nlark.com/yuque/0/2022/png/23124036/1647876608019-d8b3afb0-9b73-4e25-ad97-f5bdd7e36298.png#clientId=u4dd446b7-4032-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=406&id=u21975aec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=508&originWidth=1068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=266380&status=done&style=none&taskId=uf500c8a9-27e0-4341-84ab-a4d5d9a5bcc&title=&width=854.4)
<a name="02ab6848"></a>
## 9. 客户端 命令行操作

-  命令行语法  
| 命令 | 功能 |
| --- | --- |
| heip | 显示所有操作命令 |
| ls  路径 | 查看当前节点ZNode 节点信息<br />    -w  监听子节点个数变化<br />    -s 显示详细信息 |
| create   节点名   节点数据 | 创建节点 <br />   -s     有序序列<br />   -e (ephemeral)   临时节点(重启或者超时时消失) <br />   -p (persistent)      长久节点 |
| get path | 获取节点的值 <br />   -w  获取节点数值,同时监听节点数值的变化  <br />   -s  显示详细信息 |
| set node  value | 设置节点数值 |
| stat  node | 查看节点状态 |
| delete node | 删除节点 |
| deleteall   父节点 | 递归删除父节点下所有节点 |

-  具体使用 
   1.  显示所有指令

[zk: localhost:2181(CONNECTED) 0] help



   2.  查看节点信息

[zk: localhost:2181(CONNECTED) 1] ls / [zookeeper] [zk: localhost:2181(CONNECTED) 2] ls /zookeeper [config, quota] [zk: localhost:2181(CONNECTED) 3] ls /zookeeper/config [] [zk: localhost:2181(CONNECTED) 4]



   3.  查看节点的详细数据

[zk: localhost:2181(CONNECTED) 4] ls -s /

节点信息说明

[zookeeper]

创建节点的事务id 每次修改 ZooKeeper状态都会产生一ZooKeeper事务 ID。事务 ID 是 ZooKeeper 中所有修改总的次序。每次修改都有唯一的cxid,如果 cxid1 小于cxid2,那么 zxid1 在 zxid2 之前发生。

cZxid = 0x0

znode 被创建的毫秒数(从 1970 年开始)

ctime = Wed Dec 31 19:00:00 EST 1969

znode 最后更新的事务 zxid

mZxid = 0x0

znode 最后修改的毫秒数(从 1970 年开始)

mtime = Wed Dec 31 19:00:00 EST 1969

znode 最后更新的子节点 zxid

pZxid = 0x0

znode 子节点变化号,znode 子节点修改次数

cversion = -1

znode 数据变化号

dataVersion = 0

:znode 访问控制列表的变化号

aclVersion = 0

如果是临时节点,这个是 znode 拥有者的 session id。如果不是临时节点则是 0

ephemeralOwner = 0x0

znode 的数据长度

dataLength = 0

znode 子节点数量

numChildren = 1

![image.png](https://cdn.nlark.com/yuque/0/2022/png/23124036/1647876692147-d3a0e5c8-a349-4c32-9e75-305fd5b4d65c.png#clientId=u4dd446b7-4032-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=421&id=u5b8301c1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=526&originWidth=1139&originalType=binary&ratio=1&rotation=0&showTitle=false&size=214545&status=done&style=none&taskId=ucd886def-dfff-4bef-b92f-fbdb80ac328&title=&width=911.2)<br /> 

   4.  创建节点
      -  创建普通节点(默认永久节点,不带序号)

[zk: localhost:2181(CONNECTED) 6] create /zookeeper/demo1 “zhangfei” Created /zookeeper/demo1 [zk: localhost:2181(CONNECTED) 7] get /zookeeper/demo1 zhangfei



      -  创建带序号的节点(如果原来没有序号节点,序号从 0 开始依次递增。如果原节点下已有 2 个节点,则再排序时从 2 开始,以此类推)

[zk: localhost:2181(CONNECTED) 14] create -s /zookeeper “xuhao” Created /zookeeper/demo10000000001 [zk: localhost:2181(CONNECTED) 17] ls /zookeeper [config, demo1, demo10000000001, quota]



      -  创建临时节点不带序号(关闭连接后节点消失)

[zk: localhost:2181(CONNECTED) 18] create -e /zookeeper/demo2 “no” Created /zookeeper/demo2 [zk: localhost:2181(CONNECTED) 19] ls /zookeeper [config, demo1, demo10000000001, demo2, quota]



      -  创建临时带序号节点(关闭连接后节点消失)

[zk: localhost:2181(CONNECTED) 2] create -e -s /zookeeper/demo “11” Created /zookeeper/demo0000000003 [zk: localhost:2181(CONNECTED) 4] ls /zookeeper [config, demo0000000003, demo1, demo10000000001, quota]



   5.  修改节点数据

[zk: localhost:2181(CONNECTED) 8] set /zookeeper/demo1 “xishi” [zk: localhost:2181(CONNECTED) 9] get /zookeeper/demo1 xishi



   6.  节点数值变化监听

1. 在主机hadoop104上注册监听/zookeeper/demo1 节点数据变化

[zk: localhost:2181(CONNECTED) 5] get -w /zookeeper/demo1 xishi

2. 在hadoop103上修改/sanguo 节点的数据

[zk: localhost:2181(CONNECTED) 1] set /zookeeper/demo1 “666”

3. 观察 hadoop104 主机收到数据变化的监听

[zk: localhost:2181(CONNECTED) 6] WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/zookeeper/demo1

注意:在hadoop103再多次修改/sanguo的值,hadoop104上不会再收到监听。因为注册

一次,只能监听一次。想再次监听,需要再次注册。



   7.  节点的子节点变化监听

1. 在 hadoop104 主机上注册监听/sanguo 节点的子节点变化

[zk: localhost:2181(CONNECTED) 1] ls -w /sanguo [shuguo, weiguo]

2. 在 hadoop103 主机/sanguo 节点上创建子节点

[zk: localhost:2181(CONNECTED) 2] create /sanguo/jin “simayi” Created /sanguo/jin

3.观察 hadoop104 主机收到子节点变化的监听

WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo

注意:节点的路径变化,也是注册一次,生效一次。想多次生效,就需要多次注册。



   8.  删除节点

[zk: localhost:2181(CONNECTED) 10] delete /zookeeper/demo0000000003 [zk: localhost:2181(CONNECTED) 11] delete /zookeeper/demo1Node not empty: /zookeeper/demo1 [zk: localhost:2181(CONNECTED) 12] deleteall /zookeeper/demo1



<a name="2e0a439f"></a>
## 9 监听器原理

        客户端在注册监听它关心的节点,当目录下节点数据发生改变时(数据改变、节点删除/增加、子目录节点删除/增加),zookeeper会通知客户端。监听机制保证zookeeper保存的任何数据改变都能快速的响应到监听该节点的应用程序<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/23124036/1647876727662-162115d9-f2a6-4bc5-a409-28351caa52a5.png#clientId=u4dd446b7-4032-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=432&id=ue73f4ff8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=540&originWidth=1089&originalType=binary&ratio=1&rotation=0&showTitle=false&size=206477&status=done&style=none&taskId=u65138169-fe07-4177-8053-6da0c9e1dfe&title=&width=871.2)
<a name="cb5ad9b8"></a>
## 10 java客户端 API操作

-  创建pom项目 
-  引入依赖 
```java
        <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.8.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
  • 编写log4j配置文件
    要在项目的 src/main/resources 目录下,新建一个文件,命名为“log4j.properties”,在
    文件中填入。
    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
    
  • 创建主启动类(Mian_demo1)
    1. 连接
      public void init() throws IOException {
       String url= "192.168.1.19:2181";
       int sessionTimeout = 200000;
       zooKeeper = new ZooKeeper(url, sessionTimeout, new Watcher() {
           @Override
           public void process(WatchedEvent watchedEvent) {
               System.out.println("Watcher");
           }
       });
      }
      
  1. 创建节点
    public void  creatNode() throws KeeperException, InterruptedException {
     // 参数 1:要创建的节点的路径; 参数 2:节点数据 ; 参数 3:节点权限 ;参数 4:节点的类型
     final String s = zooKeeper.create("/java1",
             "allen".getBytes(StandardCharsets.UTF_8),
             ZooDefs.Ids.OPEN_ACL_UNSAFE,
             CreateMode.PERSISTENT_SEQUENTIAL);
     System.out.println(s);
    }
    
  1. 获取节点数值并检测节点变化 ``` // 获取节点数据并观测数据(只能监测一次)

    @Test public void getNodeAndWath() throws KeeperException, InterruptedException { final Watcher watcher = new Watcher() {

     @Override
     public void process(WatchedEvent event) {
         System.out.println(event.toString());
     }
    

    }; // 一次性监听 数据改变一次后就不在监听 final byte[] data = zooKeeper.getData(“/java”, watcher, new Stat()); String s = new String(data); System.out.println(s); Thread.sleep(Long.MAX_VALUE); }

// 获取节点数据并观测数据(监测多次)

// 1. 改造连接 zookeeper函数 @Before public void init() throws IOException { String url= “192.168.1.19:2181”; int sessionTimeout = 200000; zooKeeper = new ZooKeeper(url, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { System.out.println(“Watcher”);

            byte[] data =null;
            try {
                data = zooKeeper.getData("/java", true, new Stat());
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String s = new String(data);
            System.out.println(s);
        }
    });
}

// 2. 使用连接函数中的检测 @Test public void getNodeAndWath() throws KeeperException, InterruptedException { final Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.toString()); } }; // 永久性监听 使用init()函数中的监听 ,执行完毕之后再次进行监听 final byte[] data = zooKeeper.getData(“/java”, true, new Stat()); String s = new String(data); System.out.println(s); Thread.sleep(Long.MAX_VALUE); }



   4.  判断节点是否存在
@Test
public void existNode() throws KeeperException, InterruptedException {
    final Stat exists = zooKeeper.exists("/java", false);
    System.out.println(exists);
    final Stat exist2 = zooKeeper.exists("/java/dddd", false);
    System.out.println(exist2);
}


   5.  获取某节点下的子节点,并持续监听
   @Before
   public void init() throws IOException {
    String url= "192.168.1.19:2181";
    int sessionTimeout = 200000;
    zooKeeper = new ZooKeeper(url, sessionTimeout, new Watcher() {
        @Override
        public void process(WatchedEvent watchedEvent) {
            System.out.println("Watcher");
            List<String> childrens = null;
            try {
                childrens = zooKeeper.getChildren("/", true);
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(childrens);
        }
    });
}

@Test public void getPathNode() throws KeeperException, InterruptedException { final List childrens = zooKeeper.getChildren(“/“, true); System.out.println(childrens); Thread.sleep(Long.MAX_VALUE); } ```

11 写请求原理

image.pngimage.png

12 分布式锁

  • 概念
    什么叫做分布式锁呢?保持独占,这样其他进程就无法访问该资源,”进程 1”用完该资源以后就将锁释放掉,让其他进程来获得锁,那么通过这个锁机制,我们就能保证了分布式系统中多个进程能够有序的访问该临界资源。那么我们把这个分布式环境下的这个锁叫作分布式锁。比如说”进程 1”在使用该资源的时候,会先去获得锁,”进程 1”获得锁以后会对该资源

image.png

13 面试真题

  • 选举机制
    半数机制,超过半数的投票通过,即通过。
    1. 第一次启动选举规则:
      投票过半数时,服务器 id 大的胜出
    2. 第二次启动选举规则:
      ①EPOCH 大的直接胜出
      ②EPOCH 相同,事务 id 大的胜出
      ③事务 id 相同,服务器 id 大的胜出
  • 生产集群安装多少 zk 合适?
    安装奇数台 ,生产经验:
    • 10 台服务器:3 台 zk;
    • 20 台服务器:5 台 zk;
    • 100 台服务器:11 台 zk;
    • 200 台服务器:11 台 zk