一文入门zookeeper(下)

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

一、集群安装

这里,提前准备好了三台机器,名为 hadoop101,Hadoop102、hadoop103.

我们需要在三台机器上都安装上 zookeeper。

1、将安装包上传到 linux 并解压,然后重命名为zookeeper

1
arduino复制代码 tar -zxvf zookeeper-3.5.7.tar.gz -C /opt/module/

2、配置服务器的编号。

三台服务器的编号需要自己新建一个myid 文件,同时在 zoo.cfg 目录中指向这个文件所在的文件夹。

我们在 zookeeper 目录下创建一个 zkData 文件夹,然后里面新增myid 文件,写上编号1

1
2
bash复制代码 mkdir zkData
 touch myid

在文件中添加与 server 对应的编号:

1
复制代码 1

其他两台分别编上 2 和 3 。

3、配置 zoo.cfg 文件 将 conf/zoo_sample.cfg 重命名为 zoo.cfg

1
bash复制代码 vim conf/zoo.cfg

修改dataDir

1
ini复制代码 dataDir=/opt/sofeware/zookeeper/zkData

在文件末尾添加集群配置:

1
2
3
4
ini复制代码 #######################cluster##########################
 server.1=hadoop101:2888:3888
 server.2=hadoop102:2888:3888
 server.3=hadoop103:2888:3888

这里的配置参数需要讲解一下:

1
ini复制代码 server.A=B:C:D。

A 是一个数字,表示这个是第几号服务器;

集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。

B 是这个服务器的地址;

C 是这个服务器Follower与集群中的Leader服务器交换信息的端口;

D 是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

4、集群操作

可以直接启动 bin/zkServer.sh start 。但是需要每台机器上都配置下

集群下面为了方便写了个群起脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bash复制代码 #!/bin/bash
 for i in hadoop101 hadoop102 hadoop103
 do
    echo "===== $i zookeeper======"
    case $1 in
    "start")
        echo "==================== START $i ZOOKEEPER ==================== "
        ssh $i /opt/sofeware/zookeeper/bin/zkServer.sh start
    ;;
    "status")
        echo "==================== STATUS $i ZOOKEEPER ==================== "
        ssh $i /opt/sofeware/zookeeper/bin/zkServer.sh status
    ;;
    "stop")
        echo "==================== STOP $i ZOOKEEPER ==================== "
        ssh $i /opt/sofeware/zookeeper/bin/zkServer.sh stop
    ;;
    *)
    echo "Input error"
    exit
    ;;
    esac
 done

直接群起:

1
2
csharp复制代码 [root@hadoop101 bin]# zkServer.sh start
 ​

查看状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ini复制代码 [root@hadoop101 bin]# zkServer.sh status
 ===== hadoop101 zookeeper======
 ==================== STATUS hadoop101 ZOOKEEPER ====================
 /usr/bin/java
 ZooKeeper JMX enabled by default
 Using config: /opt/sofeware/zookeeper/bin/../conf/zoo.cfg
 Client port found: 2181. Client address: localhost.
 Mode: follower
 ===== hadoop102 zookeeper======
 ==================== STATUS hadoop102 ZOOKEEPER ====================
 /usr/bin/java
 ZooKeeper JMX enabled by default
 Using config: /opt/sofeware/zookeeper/bin/../conf/zoo.cfg
 Client port found: 2181. Client address: localhost.
 Mode: leader
 ===== hadoop103 zookeeper======
 ==================== STATUS hadoop103 ZOOKEEPER ====================
 /usr/bin/java
 ZooKeeper JMX enabled by default
 Using config: /opt/sofeware/zookeeper/bin/../conf/zoo.cfg
 Client port found: 2181. Client address: localhost.
 Mode: follower
 ​

可以看到 那台是主机、哪些是从机信息。

二、客户端基本命令

命令基本语法 功能描述
help 显示所有操作命令
ls path 使用 ls 命令来查看当前znode的子节点 [可监听]-w 监听子节点变化-s 附加次级信息
create 普通创建-s 含有序列-e 临时(重启或者超时消失)
get path 获得节点的值 [可监听]-w 监听节点内容变化-s 附加次级信息
set 设置节点的具体值
stat 查看节点状态
delete 删除节点
deleteall 递归删除节点
2.1 启动客户端
1
bash复制代码 bin/zkCli.sh
2.2 显示所有操作命令
1
scss复制代码 [zk: localhost:2181(CONNECTED) 1] help
2.3 查看当前节点包含的内容
1
2
csharp复制代码 [zk: localhost:2181(CONNECTED) 0] ls /
 [zookeeper]
2.4 查看当前节点详细数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ini复制代码 [zk: localhost:2181(CONNECTED) 2] ls2 /
 'ls2' has been deprecated. Please use 'ls [-s] path' instead.
 [zookeeper]
 cZxid = 0x0
 ctime = Thu Jan 01 08:00:00 CST 1970
 mZxid = 0x0
 mtime = Thu Jan 01 08:00:00 CST 1970
 pZxid = 0x0
 cversion = -1
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 0
 numChildren = 1
2.5 创建普通节点
1
2
3
4
5
bash复制代码 [zk: localhost:2181(CONNECTED) 3] create /jiangxi "nanchang"
 Created /jiangxi
 ​
 [zk: localhost:2181(CONNECTED) 4] create /jiangxi/nc "hl"
 Created /jiangxi/nc
2.6 获得节点的值
1
2
3
4
csharp复制代码 [zk: localhost:2181(CONNECTED) 5] get /jiangxi
 nanchang
 [zk: localhost:2181(CONNECTED) 6] get /jiangxi/nc
 hl
2.7 创建临时节点
1
bash复制代码 create -e /jiangxi/yichun "ll"

这个临时节点在重启客户端之后就无法见到了。

2.8 创建带序号的节点
1
2
3
4
bash复制代码 [zk: localhost:2181(CONNECTED) 7] create -s /jiangxi "jinxian"
 Created /jiangxi0000000001
 [zk: localhost:2181(CONNECTED) 8] create -s /jiangxi "yushan"
 Created /jiangxi0000000002
2.9 修改节点的值
1
2
3
csharp复制代码 [zk: localhost:2181(CONNECTED) 9] set /jiangxi "xiazhen"
 [zk: localhost:2181(CONNECTED) 10] get /jiangxi
 xiazhen
2.10 节点的值变化监听

hadoop102 机器开启监听:

1
csharp复制代码 [zk: localhost:2181(CONNECTED) 8] get -w /jiangxi

hadoop101 机器修改值之后,hadoop102 能观测到该值变化

1
2
3
4
bash复制代码 [zk: localhost:2181(CONNECTED) 1] 
 WATCHER::
 ​
 WatchedEvent state:SyncConnected type:NodeDataChanged path:/jiangxi

如果节点的子节点发生变化,则信息如下:

1
2
bash复制代码 WATCHER::
 WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/jiangxi
2.11 删除节点
1
arduino复制代码 delete /jiangxi/yushan
2.12 查看节点状态
1
2
3
4
5
6
7
8
9
10
11
12
ini复制代码 [zk: localhost:2181(CONNECTED) 1] stat /jiangxi
 cZxid = 0x100000002
 ctime = Fri Aug 13 14:34:44 CST 2021
 mZxid = 0x100000008
 mtime = Fri Aug 13 14:39:31 CST 2021
 pZxid = 0x100000003
 cversion = 1
 dataVersion = 2
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 7
 numChildren = 1

三、API应用

1、添加 jar 包

1
2
3
4
5
6
7
8
9
10
11
12
xml复制代码 <dependencies>
  <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>RELEASE</version>
  </dependency>
  <dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.5.7</version>
  </dependency>
 </dependencies>

2、APi 测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
java复制代码 public class ZookeeperTest {
    public static String connectString = "hadoop101:2181,hadoop102:2181,hadoop103:2181";
    private static int sessionTimeout = 2000;
    private ZooKeeper zkClient = null;
 ​
    /**
      * 创建 zookeeper 客户端
      * @throws IOException
      */
    @Before
    public void init() throws IOException {
        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                // 收到事件通知后的回调函数(用户的业务逻辑)
                System.out.println(watchedEvent.getType()+"--"+watchedEvent.getPath());
                // 再次启动监控
                try {
                    zkClient.getChildren("/",true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
 ​
    /**
      * 创建子节点
      * @throws InterruptedException
      * @throws KeeperException
      */
    @Test
    public void create() throws InterruptedException, KeeperException {
        // 参数1:要创建的节点的路径;
        // 参数2:节点数据 ;
        // 参数3:节点权限 ;
        // 参数4:节点的类型
        String node = zkClient.create("/xiaolei","leilei".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
    }
 ​
    /**
      * 获取子节点并监听节点变化
      */
    @Test
    public void getChildren() throws InterruptedException, KeeperException {
        List<String> children = zkClient.getChildren("/", true);
        for (String child : children) {
            System.out.println(child);
        }
        // 延时阻塞,保持服务器在线
        Thread.sleep(Long.MAX_VALUE);
    }
 ​
    /**
      * 判断zookeeper 是否存在
      * @throws InterruptedException
      * @throws KeeperException
      */
    @Test
    public void exist() throws InterruptedException, KeeperException {
        Stat exists = zkClient.exists("/xiaolei", false);
        if(exists==null){
            System.out.println("not exist");
        }else{
            System.out.println("exist");
        }
    }
 ​
 }

四、zookeeper 总结

4.1 什么是 zookeeper

概述+作用+内部结构+应用场景+优缺点。

zookeeper 它是在大数据或者分布式领域中的一个常用的中间件,它主要用来当作注册中心的存在,用于服务注册和服务发现。它的内部结构和 linux文件系统很相似,整体看作一颗树,每个节点叫做 znode,默认能够存储 1mb的数据,这个节点也分为临时节点和持久两种类型, 总结下来,它就是一个分布式协调服务的框架。

4.2 zookeeper 都有哪些功能

它提供的服务包括:

  • 统一命名管理:客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。
  • 统一配置管理:把公共的配置文件抽取出来,分发给其他系统。
  • 统一集群管理:监控节点存活状态、运行请求等;
  • 软负载均衡:让访问最少的服务器去处理最新的客户端请求。
  • 分布式锁:临时顺序节点实现的。独占锁、共享锁。独占锁即一次只能有一个线程使用资源,共享锁是读锁共享,读写互斥,即可以有多线线程同时读同一个资源,如果要使用写锁也只能有一个线程使用。Zookeeper 可以对分布式锁进行控制。

4.3 ZAB 协议你了解吗

Zookeeper 的核心是原子广播机制,这个机制保证了各个 server 之间的同步。实现这个机制的协议叫做 Zab 协议。Zab 协议有两种模式,它们分别是恢复模式和广播模式。

恢复模式

当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数 server 完成了和 leader 的状态同步以后,恢复模式就结束了。状态同步保证了 leader 和 server 具有相同的系统状态。

广播模式

一旦 leader 已经和多数的 follower 进行了状态同步后,它就可以开始广播消息了,即进入广播状态。这时候当一个 server 加入 ZooKeeper 服务中,它会在恢复模式下启动,发现 leader,并和 leader 进行状态同步。待到同步结束,它也参与消息广播。ZooKeeper 服务一直维持在 Broadcast 状态,直到 leader 崩溃了或者 leader 失去了大部分的 followers 支持。

4.4 znode 节点类型

(1)PERSISTENT-持久节点

除非手动删除,否则节点一直存在于 Zookeeper 上

(2)EPHEMERAL-临时节点

临时节点的生命周期与客户端会话绑定,一旦客户端会话失效(客户端与zookeeper 连接断开不一定会话失效),那么这个客户端创建的所有临时节点都会被移除。

(3)PERSISTENT_SEQUENTIAL-持久顺序节点

基本特性同持久节点,只是增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。

(4)EPHEMERAL_SEQUENTIAL-临时顺序节点

基本特性同临时节点,增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。

4.5 通知机制

客户端会对某个 znode 建立一个 watcher 事件,当该znode 发生变化时,这些 client 会收到 zk 的通知,然后 client 可以根据 znode 变化来做出业务上的改变等。

更多面试题:blog.csdn.net/ThinkWon/ar…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%