前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用docker-compose搭建zookeeper集群

使用docker-compose搭建zookeeper集群

作者头像
喜欢天文的pony站长
发布2021-08-13 14:25:58
1.1K0
发布2021-08-13 14:25:58
举报
文章被收录于专栏:RabbitMQ实战RabbitMQ实战

# 技术

  • docker: https://www.docker.com
  • docker-compose: https://docs.docker.com/compose/
  • zookeeper docker image: https://registry.hub.docker.com/_/zookeeper

# 集群规划

  • 创建包含3个(奇数个)实例的zookeeper集群。
  • 通过docker-compose创建3个docker-zookeeper镜像,映射的宿主机端口分别为: 2081,2182,2183,集群实例myid分别为1,2,3

# 编写docker-compose

  • 可在https://registry.hub.docker.com/_/zookeeper查看demo
  • 环境变量
  • 集群模式下的环境变量
  • 编写docker-compose
代码语言:javascript
复制
# docker compose版本
version: "3.1"

services:
  # 节点1
  zk1:
    # 镜像名称
    image: zookeeper
    # 容器名称
    container_name: zk1.docker
    # docker重启后自动重启容器
    restart: always
    # 当前容器主机名
    hostname: zk1.docker
    # 端口 宿主机:容器
    ports:
      - 2181:2181
    # 环境变量
    environment:
      # myid,一个集群内唯一标识一个节点
      ZOO_MY_ID: 1
      # 集群内节点列表
      ZOO_SERVERS:
        - server.1=zk1.docker:2888:3888;2181
        - server.2=zk2.docker:2888:3888;2181
        - server.3=zk3.docker:2888:3888;2181
  # 节点2
  zk2:
    image: zookeeper
    container_name: zk2.docker
    restart: always
    hostname: zk2.docker
    ports:
      - 2182:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS:
        - server.1=zk1.docker:2888:3888;2181
        - server.2=zk2.docker:2888:3888;2181
        - server.3=zk3.docker:2888:3888;2181
  # 节点3
  zk3:
    image: zookeeper
    container_name: zk3.docker
    restart: always
    hostname: zk3.docker
    ports:
      - 2183:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS:
        - server.1=zk1.docker:2888:3888;2181
        - server.2=zk2.docker:2888:3888;2181
        - server.3=zk3.docker:2888:3888;2181
  • 运行docker-compose脚本 docker-compose -f zk-replicated.yml up

# 检查集群运行状态

  • 镜像列表
  • 查看节点的状态(容器启动顺序为zk1, zk2, zk3) bin/zkServer.sh status
  • zk1:
    • Mode: follower
  • zk2:
    • Mode: leader
  • zk3:
    • Mode: follower
  • 三个节点都启动成功,且因为启动循序是zk1, zk2, zk3,所以根据zk的选举算法,选举zk2为leader,其他的为follower。
  • 选举过程:
    1. 启动zk1(myid=1),投自己一票,此时因为集群大小为3,不够半数票,无法完成选举,所以状态为LOOKING
    2. 启动zk2(myid=2),zk2投自己一票并发起选举,zk1发现zk2的myid比自己的大,所以把选票投给zk2,此时zk2的选票为2,超过了集群大小的一半,选举结束,zk2为leader,zk1为follower
    3. 启动zk3(myid=3), zk3投自己一票,zk1,zk2由于不是LOOKING状态,不会改变选票,所以zk3为follower

# 通过Java程序进行测试

代码语言:javascript
复制
package com.futao.zookeeper.dynamic;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 客户端监听服务实例的变化
 *
 * @author ft
 * @date 2021/8/3
 */
@Slf4j
public class Client {
    private static ZooKeeper Zk = null;
    /**
     * 集群地址
     */
    private static final String CONNECT_STRING = "localhost:2181,localhost:2182,localhost:2183";

    public static void main(String[] args) throws IOException, InterruptedException {
        Zk = new ZooKeeper(CONNECT_STRING, 2000, new Watcher() {
            @SneakyThrows
            @Override
            public void process(WatchedEvent event) {
                Stat stat = Zk.exists("/server-pig", false);
                if (stat == null) {
                    Zk.create("/server-pig", "".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                    log.info("创建/server-pig成功");
                }
                // 可用的实例列表
                List<String> serverList = new ArrayList<>();
                List<String> children = Zk.getChildren("/server-pig", true);
                for (String child : children) {
                    byte[] data = Zk.getData("/server-pig/" + child, false, null);
                    // 拿到的是节点名,而不是data,why?
                    serverList.add(new String(data));
                }
                System.out.println(children);
            }
        });
        // 阻塞主线程
        TimeUnit.HOURS.sleep(1);
    }
}
  • 创建节点之前的集群状态
  • 程序创建节点 /server-pig
  • 创建/server-pig节点之后,且集群各个节点之间的数据是同步

集群搭建完成

# 集群节点下线

  • 对于zookeeper集群,只要超过半数的节点是活的,集群即可正常对外提供服务。
  • 停止zk2
  • 应用仍能正常使用
  • 此时集群节点状态:
    • zk1为follower
    • zk3为leader

# 其他

  • IDEA ZK插件
  • IDEA 查看/操作docker镜像
  • visualStudioCode docker插件
  • docker desktop

# TODO

  • 动态增删ZK集群节点
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 喜欢天文 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 技术
  • # 集群规划
  • # 编写docker-compose
  • # 检查集群运行状态
  • # 通过Java程序进行测试
  • # 集群节点下线
  • # 其他
  • # TODO
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档