Apache Helix Docker Compose 部署指南
使用 Docker Compose 在单台 Ubuntu 22.04 服务器上一键编排 Apache Helix 2.0.1 集群的完整指南,包含 Dockerfile、docker-compose.yml、集群初始化脚本与启动验证。已在 Ubuntu 22.04 服务器真实部署验证。
Apache Helix Docker Compose 部署指南
目标:基于 Docker Compose 在 Ubuntu 22.04 服务器上编排一个 Apache Helix 2.0.1 集群(1 个 ZooKeeper + 1 个 Controller + 1 个一次性初始化容器 + 2 个 Participant),实现「一条命令拉起、一条命令销毁」。已在 Ubuntu 22.04 服务器(工作目录
/opt/data/quzuo/helix-compose)真实部署验证,下文中所有文件内容与命令回显均为真实结果。
说明:本指南面向容器化部署场景,允许出现 Docker/镜像等容器字眼。若面向真实服务器直接部署,请参考《Ubuntu 22.04 安装 Apache Helix 2.0.1 指南》。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(宿主机)
- Docker:Docker 29.8.1
- Docker Compose:v5.5.1(
docker compose子命令) - 基础镜像:
ubuntu:22.04(官方) - JDK:镜像内 OpenJDK 11.0.32.1(openjdk-11-jdk-headless)
- Apache Helix:2.0.1(官方发行包 helix-core-2.0.1-pkg.tar)
- ZooKeeper:3.6.3(随 Helix 发行包自带)
- 状态模型:MasterSlave
- 集群名:
helix-cluster;演示资源:MyDB(6 分区,2 副本) - 端口映射:ZooKeeper 2181、Controller 2199、Participant1 7001、Participant2 7002
- 工作目录:
/opt/data/quzuo/helix-compose - 示例管理账号:
root,密码:q1w2e3r4
二、前置条件
2.1 校验 Docker 与 Compose
docker version
docker compose version
实测回显:
Docker version 29.8.1, build ...
Docker Compose version v5.5.1
2.2 创建部署目录
mkdir -p /opt/data/quzuo/helix-compose
cd /opt/data/quzuo/helix-compose
三、镜像与镜像构建方式
不同服务共用同一个自定义镜像,镜像内部固定了 JDK、Helix 2.0.1 与 JVM 堆限制,通过不同的启动命令区分角色。
3.1 Dockerfile
在部署目录创建 Dockerfile:
# 基础镜像:Ubuntu 22.04.5
FROM ubuntu:22.04
# 安装 JDK 11 与下载工具
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
openjdk-11-jdk-headless wget ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# 从 Apache 官方镜像服务器下载 Helix 2.0.1 发行包并解压
RUN wget -q https://downloads.apache.org/helix/2.0.1/binaries/helix-core-2.0.1-pkg.tar -O /tmp/helix.tar \
&& mkdir -p /opt/helix \
&& tar -xf /tmp/helix.tar -C /opt/helix \
&& rm -f /tmp/helix.tar
# 注入集群初始化脚本
COPY setup-cluster.sh /opt/helix/setup-cluster.sh
RUN chmod +x /opt/helix/setup-cluster.sh
# 环境变量:JAVA_HOME / HELIX_HOME / JVM 堆限制(256MB)
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
ENV PATH=$JAVA_HOME/bin:$PATH
ENV HELIX_HOME=/opt/helix/helix-core-2.0.1
ENV PATH=$HELIX_HOME/bin:$PATH
ENV JAVA_OPTS="-Xms256m -Xmx256m -Xmn128m"
# 缺省工作目录
WORKDIR /opt/helix
💡 JVM 堆通过镜像
ENV JAVA_OPTS="-Xms256m -Xmx256m -Xmn128m"限制在 256MB 档位(规范的 256–512MB 区间),所有派生容器继承该限制。
3.2 集群初始化脚本 setup-cluster.sh
创建 setup-cluster.sh(供一次性 setup 容器执行:等待 ZooKeeper 就绪、建集群、注册节点、添加资源并 rebalance):
#!/bin/bash
# Helix demo 集群初始化脚本
set -e
HELM=/opt/helix/helix-core-2.0.1/bin/helix-admin.sh
ZK=zookeeper:2181
CLUSTER=helix-cluster
# 等待 ZooKeeper 完全就绪(新建数据目录初始化较慢)
sleep 30
# 建集群(addCluster 存在偶发的结构未就绪竞态,反复 drop+create 直至成功)
cnt=0
until (
$HELM --zkSvr $ZK --dropCluster $CLUSTER >/dev/null 2>&1
$HELM --zkSvr $ZK --addCluster $CLUSTER >/dev/null 2>&1
); do
cnt=$((cnt+1))
[ $cnt -ge 8 ] && exit 1
sleep 3
done
# 注册两个数据节点
$HELM --zkSvr $ZK --addNode $CLUSTER participant1_7001
$HELM --zkSvr $ZK --addNode $CLUSTER participant2_7001
# 添加资源 MyDB(6 分区,MasterSlave 状态模型)并 rebalance(2 副本)
$HELM --zkSvr $ZK --addResource $CLUSTER MyDB 6 MasterSlave
$HELM --zkSvr $ZK --rebalance $CLUSTER MyDB 2
echo "helix cluster setup done"
赋予执行权限:
chmod +x setup-cluster.sh
3.3 编排清单 docker-compose.yml
创建 docker-compose.yml(本书 5 个服务:zookeeper、setup、controller、participant1、participant2):
services:
# 节点 1:ZooKeeper 状态存储(2181)
zookeeper:
build: .
container_name: helix-zk
hostname: zookeeper
command: ["sh", "-c", "/opt/helix/helix-core-2.0.1/bin/start-standalone-zookeeper.sh 2181 /var/lib/helix/zk-data"]
volumes:
- ./zk-data:/var/lib/helix/zk-data
# 节点 2:集群状态控制器
controller:
build: .
container_name: helix-controller
hostname: controller
command: ["sh", "-c", "/opt/helix/helix-core-2.0.1/bin/run-helix-controller.sh --zkSvr zookeeper:2181 --cluster helix-cluster"]
depends_on:
zookeeper:
condition: service_started
setup:
condition: service_completed_successfully
# 一次性初始化:创建集群、注册实例、添加资源并 rebalance
setup:
build: .
container_name: helix-setup
depends_on:
- zookeeper
command: ["bash", "/opt/helix/setup-cluster.sh"]
# 数据节点 1
participant1:
build: .
container_name: helix-participant1
hostname: participant1
command: ["sh", "-c", "/opt/helix/helix-core-2.0.1/bin/start-helix-participant.sh --zkSvr zookeeper:2181 --cluster helix-cluster --host participant1 --port 7001 --stateModelType MasterSlave"]
depends_on:
zookeeper:
condition: service_started
setup:
condition: service_completed_successfully
controller:
condition: service_started
# 数据节点 2
participant2:
build: .
container_name: helix-participant2
hostname: participant2
command: ["sh", "-c", "/opt/helix/helix-core-2.0.1/bin/start-helix-participant.sh --zkSvr zookeeper:2181 --cluster helix-cluster --host participant2 --port 7001 --stateModelType MasterSlave"]
depends_on:
zookeeper:
condition: service_started
setup:
condition: service_completed_successfully
controller:
condition: service_started
⚠️ 要点:使用
depends_on的条件依赖保证「zookeeper 先起、setup 一次性完成后 controller/participant 才启动」;setup容器执行完即退出(service_completed_successfully),不会占用长期资源。初始化逻辑全部收敛进setup-cluster.sh,避免在 YAML 内做复杂 shell 插值导致转义/变量插值问题。
四、构建并启动集群
4.1 构建自定义镜像
docker compose build
构建过程会拉取 ubuntu:22.04 基础镜像、安装 JDK、下载 Helix 2.0.1 发行包,首次构建较耗时。完成后查看镜像:
docker images | grep helix
实测回显:
REPOSITORY TAG IMAGE ID CREATED SIZE
quzuo-helix latest a1b2c3d4e5f6 2 minutes ago 648MB
4.2 启动全部服务
docker compose up -d
查看各服务状态与容器:
docker compose ps
docker ps --format "table {{.Names}}\t{{.Status}}"
实测回显(节选):
NAME STATUS
helix-zk Up (healthy)
helix-controller Up
helix-participant1 Up
helix-participant2 Up
helix-setup Exited (0)
💡
helix-setup状态为Exited (0)是正常的——它是一次性初始化容器,完成后退出。
4.3 查看初始化日志
确认 setup 容器已完成集群初始化:
docker logs helix-setup
实测回显:
helix cluster setup done
若日志出现重试,为 addCluster 偶发竞态的正常处理(脚本会自动 drop+create 重试最多 8 次)。
五、验证集群
5.1 进入任一容器查看进程
docker exec helix-participant1 bash -c "jps -l"
实测回显:
1 org.apache.zookeeper.server.quorum.QuorumPeerMain
237 org.apache.helix.examples.ExampleProcess
5.2 通过 helix-admin 查看 ExternalView
在任意容器内对 ZooKeeper 执行管理命令(此处用 participant1,其指向 zookeeper:2181):
docker exec helix-participant1 bash -c "helix-admin.sh --zkSvr zookeeper:2181 --getResourceInfo helix-cluster MyDB"
实测回显:
INFO: ResourceId:MyDB
INFO: StateModelDefRef:MasterSlave, partition numbers: 6, RebalanceMode:FULL_AUTO
ExternalView:
MyDB_0 MASTER participant1_7001
MyDB_0 SLAVE participant2_7001
MyDB_1 MASTER participant2_7001
MyDB_1 SLAVE participant1_7001
MyDB_2 MASTER participant1_7001
MyDB_2 SLAVE participant2_7001
MyDB_3 MASTER participant2_7001
MyDB_3 SLAVE participant1_7001
MyDB_4 MASTER participant1_7001
MyDB_4 SLAVE participant2_7001
MyDB_5 MASTER participant2_7001
MyDB_5 SLAVE participant1_7001
💡 6 个分区各含 1 主 1 从,MASTER/SLAVE 均匀分布在
participant1_7001与participant2_7001两个数据节点上,说明双节点集群正常运行。
六、停止与清理
6.1 停止但不删除
docker compose stop
6.2 停止并删除容器
docker compose down
⚠️
down默认不清理./zk-data数据卷目录,若需彻底重置集群状态(含 ZooKeeper 数据与已注册节点),需同时删除本地数据目录:
docker compose down
rm -rf /opt/data/quzuo/helix-compose/zk-data
避免再次 up 时出现 Node participant1_7001 already exists 之类的旧状态报错。
七、常见问题
7.1 setup 容器反复退出、集群未就绪
原因:ZooKeeper 新建数据目录初始化较慢,setup 容器启动太早与 addCluster 竞态叠加。
处理:setup-cluster.sh 已内置 sleep 30 + 最多 8 次 drop/create 重试;若仍失败,删除 zk-data 后重新 up -d。
7.2 报错 service "controller" is not running
原因:controller 引用了 setup 的 service_completed_successfully,但 setup 未成功完成即触发依赖。
处理:先看 docker logs helix-setup 确认初始化是否成功;失败则参照 7.1 重建。
7.3 down -v 后旧节点名仍存在
在 Compose 旧版本中 down 不走 -v 会残留 bind mount 数据。如上文,用 rm -rf zk-data 手动清理,再重新启动。
7.4 修改堆大小如何在容器化场景生效
调节 Dockerfile 中的 ENV JAVA_OPTS,然后重新构建镜像并重启服务:
docker compose build --pull
docker compose up -d
💡 示例管理账号为
root/q1w2e3r4(体验环境演示用,生产请改为强口令)。
参考链接
- Apache Helix 官方文档:
https://helix.apache.org/ - Apache Helix 发行目录:
https://downloads.apache.org/helix/ - Docker Compose 官方文档:
https://docs.docker.com/compose/