Confluent-Zookeeper在Rainbond的部署

概述

我在向企业客户进行交付的时候,帮助客户在Rainbond上部署了一套基于Confluent实现,可以自由扩展数量的kafka集群,以及kafka-connector。完成这些工作后,我决定将这些经验写作成为若干篇文档,发布到社区供所有开源用户参考。

关于Confluent

Confluent Platform是一个企业级的管理Kafka集群的流处理平台。提供了完整的Kafka部署方案。这一系列的文档将介绍v5.0.0版本的Confluent Platform 部署。

官方网站:https://www.confluent.io
文档地址:https://docs.confluent.io/current/

Kafka集群的元数据存储于Zookeeper中,所以第一篇文档,就会向大家介绍如何在Rainbond平台部署一个可以自由伸缩实例数量(当然要遵从官方推荐的奇数数量3、5、7···)的Zookeeper应用。

关于zookeeper

ZooKeeper是用于分布式应用程序的高性能协调服务。它在一个简单的界面中公开了通用服务,例如命名,配置管理,同步和组服务,因此您不必从头开始编写它们。可以使用它来实现共识,组管理,领导者选举和状态协议。

Kafka使用ZooKeeper来存储持久的群集元数据,并且是Confluent Platform部署的关键组件。例如,如果您在ZooKeeper中丢失了 Kafka数据,则副本到Brokers和主题配置的映射也将丢失,从而使Kafka群集不再起作用,并有可能导致全部数据丢失。

Confluent Platform 附带了稳定版本的Zookeeper,在V5.0.0版本的Confluent Platform中,使用了 3.4.13版本的Zookeeper。

制作流程

项目地址

我从Confluent Platform官方用来制作docker镜像用的仓库中fork了一份代码,并且修改了 /debain/zookeeper这个目录中的内容:

在此基础上修改了 5.0.0-post 这个分支:

做一些改动

重点修改文件如下:

  • 修改 Dockerfile
# 基础镜像选择了Confluent Platform官方5.0.0版本的zookeeper镜像
FROM confluentinc/cp-zookeeper:5.0.0

EXPOSE 2181 2888 3888

ARG COMMIT_ID=unknown
LABEL io.confluent.docker.git.id=$COMMIT_ID
ARG BUILD_NUMBER=-1
LABEL io.confluent.docker.build.number=$BUILD_NUMBER
LABEL io.confluent.docker=true

ENV COMPONENT=zookeeper
# 添加自定义的apt源文件,替换为阿里云源
ADD sources.list /etc/apt/sources.list
# 添加一个步骤,安装 nslookup 工具,该工具的功能会在后文重点介绍
RUN echo "===> installing nslookup..." \
    && apt-get update \
    && apt-get install dnsutils -y \
    && echo "===> clean up ..."  \
    && apt-get clean && rm -rf /tmp/* /var/lib/apt/lists/* 

VOLUME ["/var/lib/zookeeper/data", "/var/lib/zookeeper/log", "/etc/zookeeper/secrets"]

COPY include/etc/confluent/docker /etc/confluent/docker
# 定义启动脚本文件
CMD ["/etc/confluent/docker/run"]
  • 修改启动脚本 /include/etc/confluent/docker/run
set -o nounset \
    -o verbose \
    -o xtrace

# 添加Rainbond相关配置文件,在启动过程中加载
echo "===> Rainbond vars"
. /etc/confluent/docker/rainbondenv

echo "===> ENV Variables ..."
env | sort

echo "===> User"
id

# 下面这个被加载的文件,用于使用环境变量来定义zookeeper参数
echo "===> Configuring ..."
/etc/confluent/docker/configure

echo "===> Running preflight checks ... "
/etc/confluent/docker/ensure

echo "===> Launching ... "
exec /etc/confluent/docker/launch
  • 添加Rainbond相关配置文件 /include/etc/confluent/docker/rainbondenv
#!/usr/bin/env bash
set -o nounset \
    -o verbose \
    -o xtrace
# define ZOOKEEPER_SERVER_ID
# 定义zookeeper实例的myid序号,在使用有状态服务部署时,这个值会根据实例的顺序依次生成为 1、2、3···
export ZOOKEEPER_SERVER_ID=`expr ${HOSTNAME#*-} + 1`

#define KAFKA_ADVERTISED_LISTENERS
export ZOOKEEPER_CLIENT_PORT=${ZOOKEEPER_CLIENT_PORT-2181}

# set default_java_mem_opts
# 根据分配给应用的内存大小,动态生成JAVA HEAP 大小,充分利用内存,防止内存泄漏。
case ${MEMORY_SIZE:-small} in
    "micro")
       export default_java_mem_opts="-Xms90m -Xmx90m -Xss512k  -XX:MaxDirectMemorySize=12M"
       echo "Optimizing java process for 128M Memory...." >&2
       ;;
    "small")
       export default_java_mem_opts="-Xms180m -Xmx180m -Xss512k -XX:MaxDirectMemorySize=24M "
       echo "Optimizing java process for 256M Memory...." >&2
       ;;
    "medium")
       export default_java_mem_opts="-Xms360m -Xmx360m -Xss512k -XX:MaxDirectMemorySize=48M"
       echo "Optimizing java process for 512M Memory...." >&2
       ;;
    "large")
       export default_java_mem_opts="-Xms720m -Xmx720m -Xss512k -XX:MaxDirectMemorySize=96M "
       echo "Optimizing java process for 1G Memory...." >&2
       ;;
    "2xlarge")
       export default_java_mem_opts="-Xms1420m -Xmx1420m -Xss512k -XX:MaxDirectMemorySize=192M"
       echo "Optimizing java process for 2G Memory...." >&2
       ;;
    "4xlarge")
       export default_java_mem_opts="-Xms2840m -Xmx2840m -Xss512k -XX:MaxDirectMemorySize=384M "
       echo "Optimizing java process for 4G Memory...." >&2
       ;;
    "8xlarge")
       export default_java_mem_opts="-Xms5680m -Xmx5680m -Xss512k -XX:MaxDirectMemorySize=768M"
       echo "Optimizing java process for 8G Memory...." >&2
       ;;
    16xlarge|32xlarge|64xlarge)
       export default_java_mem_opts="-Xms8G -Xmx8G -Xss512k -XX:MaxDirectMemorySize=1536M"
       echo "Optimizing java process for biger Memory...." >&2
       ;;
    *)
       export default_java_mem_opts="-Xms128m -Xmx128m -Xss512k -XX:MaxDirectMemorySize=24M"
       echo "Optimizing java process for 256M Memory...." >&2
       ;;
esac



if [[ "${JAVA_OPTS-}" == *-Xmx* ]]; then
  export JAVA_TOOL_OPTIONS=${JAVA_TOOL_OPTIONS:-"-Dfile.encoding=UTF-8"}
else
  default_java_opts="${default_java_mem_opts} -Dfile.encoding=UTF-8"
  export JAVA_OPTS="${default_java_opts} ${JAVA_OPTS-}"
fi
#define KAFKA_HEAP_OPTS
export KAFKA_HEAP_OPTS=${JAVA_OPTS-}


# detect zookeeper cluster node by hostname
[[ ${PAUSE-} ]] && sleep $PAUSE

# 通过平台自动赋予的环境变量 ${SERVICE_POD_NUM} 判定实例数量,并据此生成特定的新变量 ${ZOOKEEPER_SERVERS} 来定义集群配置
if [ ${SERVICE_POD_NUM-} -gt 1 ]; then
   declare -a hosts
    for i in $(seq ${SERVICE_POD_NUM-})
      do
        hosts[$i-1]=${HOSTNAME%-*}-`expr $i - 1`.${HOSTNAME%-*}:2888:3888
      done
    echo "zookeeper cluster nodes are ${hosts[@]}"
    export ZOOKEEPER_SERVERS=$(echo ${hosts[@]} | tr ' ' ';')
fi

部署

  • 直接使用源码构建即可,填写构建源信息如下:

  • 高级设置中的部署属性,一定要选择有状态服务:

  • 点击确认创建即可。

Zookeeper配置

Confluent Platform推出的Zookeeper支持使用环境变量来进行配置,常见配置如下:

环境变量 配置说明 默认值
ZOOKEEPER_TICK_TIME ZooKeeper的时间单位转换为毫秒。这将控制所有ZooKeeper与时间有关的操作。特别是用于心跳和超时。请注意,最小会话超时将是两个刻度。 2000
ZOOKEEPER_GLOBAL_OUTSTANDING_LIMIT 客户端可以比ZooKeeper更快地提交请求,尤其是在有很多客户端的情况下。为了防止ZooKeeper由于队列中的请求而耗尽内存,ZooKeeper将限制客户端,以便系统中的未完成请求不超过这个值。 1000
ZOOKEEPER_PRE_ALLOC_SIZE 为了避免查找,ZooKeeper在事务日志文件中以preAllocSize千字节块的形式分配空间。如果频繁拍摄快照,该值应减小。 64M
ZOOKEEPER_SNAP_COUNT ZooKeeper将事务记录到事务日志中。将snapCount事务写入日志文件后,将启动快照并创建一个新的事务日志文件。 100,000
ZOOKEEPER_MAX_CLIENT_CNXNS 限制单个客户端(由IP地址标识)可以与ZooKeeper集成的单个成员建立的并发连接数(在套接字级别),这是为0取消并发限制。 60
ZOOKEEPER_MIN_SESSION_TIMEOUT 服务器允许客户端进行协商的最小会话超时,以毫秒为单位。 默认为tickTime的 2倍
ZOOKEEPER_MAX_SESSION_TIMEOUT 服务器允许客户端进行协商的最大会话超时,以毫秒为单位。 默认为tickTime的 20倍
ZOOKEEPER_FSYNC_WARNING_THRESHOLDMS 每当事务日志(WAL)中的fsync花费的时间超过此值时,就会向该日志输出警告消息。 1000
ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT 启用后,ZooKeeper自动清除功能会将该值定义数量的最新快照和相应的事务日志分别保留在 dataDir和**dataLogDir中,**并删除其余部分。 默认值为3。最小值为3
ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL 必须触发清除任务的时间间隔,以小时为单位。 设置为正整数(1或更大)以启用自动清除。默认为0
ZOOKEEPER_SYNC_ENABLED 默认情况下,观察者像参与者一样,记录事务并将快照写入磁盘。这减少了重新启动时观察者的恢复时间。 true
ZOOKEEPER_INIT_LIMIT 允许followers连接并与leader同步的时间。如果ZooKeeper管理的数据量很大,请根据需要增加此值。 tickTime为单位
ZOOKEEPER_LEADER_SERVES Leader接受客户端连接。leader服务器用于协调更新。为了获得更高的更新吞吐量,而稍稍牺牲读取吞吐量,可以将leader配置为不接受客户端并专注于协调。 true
ZOOKEEPER_SYNC_LIMIT 允许followers与ZooKeeper同步的时间。 tickTime为单位

如何伸缩

在关闭zookeeper的情况下,将实例数量伸缩为指定的数量后,启动应用即可。

从应用市场安装

我已经将该应用发布到了好雨官方的应用市场,所有安装了Rainbond平台的开源用户都可以一键部署这个应用。

一同发布的ZK-UI组件是一个可视化的Zookeeper管理工具,可以实现基于WEB页面的增删改查操作:

想要使用这个工具,只需要:

  • 在登陆的首页填写连接zookeeper的地址: 127.0.0.1:2181

  • 使用如下凭证登陆:

    admin
    password