使用Docker快速搭建ZooKeeper集群

使用Docker快速搭建ZooKeeper集群

背景

1. docker-compose.yml 文件

 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
version: '3'
services:
    zoo1:
        image: zookeeper
        restart: always
        container_name: zoo1
        ports:
            - "2181:2181"
        environment:
            ZOO_MY_ID: 1
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2182 server.3=zoo3:2888:3888;2183 server.4=zoo4:2888:3888;2184
 
    zoo2:
        image: zookeeper
        restart: always
        container_name: zoo2
        ports:
            - "2182:2181"
        environment:
            ZOO_MY_ID: 2
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2182 server.3=zoo3:2888:3888;2183 server.4=zoo4:2888:3888;2184
 
    zoo3:
        image: zookeeper
        restart: always
        container_name: zoo3
        ports:
            - "2183:2181"
        environment:
            ZOO_MY_ID: 3
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2182 server.3=zoo3:2888:3888;2183 server.4=zoo4:2888:3888;2184

    zoo4:
        image: zookeeper
        restart: always
        container_name: zoo4
        ports:
            - "2184:2181"
        environment:
            ZOO_MY_ID: 4
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2182 server.3=zoo3:2888:3888;2183 server.4=zoo4:2888:3888;2184

编排配置说明

  • 此变量允许您指定Zookeeper集群的计算机列表;
  • 每个条目都应该这样指定:server.id=::[:role];[:] 条目间空格分隔
  • id 是一个数字,表示集群中的服务器ID;
  • address1表示这个服务器的ip地址;
  • 集群通信端⼝: port1 表示这个服务器与集群中的 Leader 服务器交换信息的端口;
  • 集群选举端⼝: port2 表示万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口;
  • role: 默认是 participant,即参与过半机制的⻆⾊,选举,事务请求过半提交,还有⼀个是observer, 观察者,不参与选举以及过半机制。
  • client port address 是可选的,如果未指定,则默认为 “0.0.0.0” ;
  • client port 位于分号的右侧。从3.5.0开始,zoo.cfg中不再使用clientPort和clientPortAddress配置参数。作为替代,client port 用来表示客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

2. 启动集群

3. 检测集群状态

4. ZooKeeper 集群角色介绍

5. 不宕机动态扩容和缩容

 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
version: '3'
services:
    zoo1:
        image: zookeeper
        restart: always
        container_name: zoo1
        ports:
            - "2181:2181"
        environment:
            ZOO_MY_ID: 1
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181
            ZOO_CFG_EXTRA: "reconfigEnabled=true"
            JVMFLAGS: "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:YjJhp1/a1jnzeGTDN7nAUxFcep8="

    zoo2:
        image: zookeeper
        restart: always
        container_name: zoo2
        ports:
            - "2182:2181"
        environment:
            ZOO_MY_ID: 2
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181
            ZOO_CFG_EXTRA: "reconfigEnabled=true"
            JVMFLAGS: "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:YjJhp1/a1jnzeGTDN7nAUxFcep8="

    zoo3:
        image: zookeeper
        restart: always
        container_name: zoo3
        ports:
            - "2183:2181"
        environment:
            ZOO_MY_ID: 3
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181
            ZOO_CFG_EXTRA: "reconfigEnabled=true"
            JVMFLAGS: "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:YjJhp1/a1jnzeGTDN7nAUxFcep8="

    zoo4:
        image: zookeeper
        restart: always
        container_name: zoo4
        ports:
            - "2184:2181"
        environment:
            ZOO_MY_ID: 4
            ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 server.4=zoo4:2888:3888;2181
            ZOO_CFG_EXTRA: "reconfigEnabled=true"
            JVMFLAGS: "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:YjJhp1/a1jnzeGTDN7nAUxFcep8="
  • ZOO_CFG_EXTRA: “reconfigEnabled=true” 开启了默认关闭的客户端 reconfig API
  • JVMFLAGS: “-Dzookeeper.DigestAuthenticationProvider.superDigest=super:YjJhp1/a1jnzeGTDN7nAUxFcep8=” 设置了超级管理员账号为 super,明文密码为 qwer1234
1
docker-compose -f docker-compose.yml up

5.1 查看当前集群信息 get /zookeeper/config 执行结果如下:

1
2
3
4
5
6
[zk: localhost:2181(CONNECTED) 0] get /zookeeper/config
server.1=zoo1:2888:3888:participant;0.0.0.0:2181
server.2=zoo2:2888:3888:participant;0.0.0.0:2181
server.3=zoo3:2888:3888:participant;0.0.0.0:2181
server.4=zoo4:2888:3888:participant;0.0.0.0:2181
version=100000000

5.2 扩缩容前的认证超级管理员身份 ,客户端命令行执行addauth digest super:qwer1234 5.3 移除集群中的一台服务器 reconfig -remove <id>比如说,从集群中移除ID为3的ZooKeeper服务:

1
2
3
4
5
6
[zk: localhost:2181(CONNECTED) 6] reconfig -remove 3
Committed new configuration:
server.1=zoo1:2888:3888:participant;0.0.0.0:2181
server.2=zoo2:2888:3888:participant;0.0.0.0:2181
server.4=zoo4:2888:3888:participant;0.0.0.0:2181
version=300000001

5.4 为集群新增一台服务器

1
reconfig -add server.id=<address1>:<port1>:<port2>[:role];[<client port address>:]<client port>

比如说,把刚才移除的服务器再添加回来:

1
2
3
4
5
6
7
[zk: localhost:2181(CONNECTED) 7] reconfig -add server.3=zoo3:2888:3888;2181
Committed new configuration:
server.1=zoo1:2888:3888:participant;0.0.0.0:2181
server.2=zoo2:2888:3888:participant;0.0.0.0:2181
server.3=zoo3:2888:3888:participant;0.0.0.0:2181
server.4=zoo4:2888:3888:participant;0.0.0.0:2181
version=400000001

6. 过半机制

participant ⻆⾊能够形成集群(过半机制),如果集群内的 participant 有一半及以上都宕机了,此时客户端将不再可用。

6.1 半数服务器宕机 比如说,停掉了 zoo3 和 zoo4:此时,没有停掉的服务,也启动不了客户端:

6.2 半数以上服务器可用,然后重启了 zoo3: 稍等一会之后,集群再次变得可用了。

问题记录

1 : Client port not found in server configs

2 :KeeperErrorCode = Reconfig is disabled

3: Insufficient permission