跳到主要内容

集群安装

本文介绍如何将 PlantPulse 配置为 主节点 + 工作节点集群,以应对大规模工作负载。您可以从单节点开始,在吞吐量达到极限时逐步扩展。

多节点仅指“水平扩展”​

将基础设施(Aster TSDB·Kafka·Spark)分布到多个节点上的 主节点 / 工作节点集群 是 本文档的主题。在吞吐量达到极限时使用。

分层安装(将数据湖和应用放在不同机器上)已于 2026-09-02 移除。所有机器都是完整安装。

何时扩展到集群?​

环境规模推荐配置备注
标签 ~5,000单主节点无需集群
标签 5,000 ~ 50,000主节点 + 1~2 工作节点分散分析 / 消息处理
标签 50,000+主节点 + 3+ 工作节点全面分布式运行

集群拓扑​

硬件要求​

每个工作节点的推荐配置(主节点遵循系统要求 — 数据湖主节点 96 GB 以上):

项目最低标准大规模
CPU16 vCPU32 vCPU48 vCPU
内存67 GB 以上(60 GB 的工作节点容器必须放入主机 RAM 的 90% 以内 — 64 GB 低于规格)128 GB200+ GB
数据磁盘200 GB NVMe1 TB NVMe4 TB NVMe
网络1 Gbps10 Gbps10 Gbps

节点间网络:集群节点之间建议 10 Gbps 以上。Aster TSDB repair、Kafka 复制、Spark shuffle 流量很大。

前提条件​

在主节点和所有工作节点上,必须完成以下步骤。

  • 满足系统要求
  • 设置主机名 / 固定 IP / DNS
  • 时间同步 (chronyd) — 节点间时间差必须小于 100ms
  • 系统调优 (limits / sysctl / swap off)
  • 节点间私有网络通信可用 (RFC 1918 或 Tailscale)
  • 允许集群内部端口(Aster TSDB 7000/7001/9042、Kafka 9092/9093、Spark 7077/8081 等)

/etc/hosts 设置 (所有节点一致)​

# /etc/hosts — 마스터 / 워커 모든 노드에 동일하게
192.168.0.41 plantpulse-master plantpulse-master.local
192.168.0.101 plantpulse-worker-1 plantpulse-worker-1.local
192.168.0.102 plantpulse-worker-2 plantpulse-worker-2.local
192.168.0.103 plantpulse-worker-3 plantpulse-worker-3.local

Docker 集群(推荐路径)​

在 Docker/一键安装环境中,通过 compose 叠加 来启动工作节点。在主节点上运行基本堆栈的情况下,bin/worker-add.sh 会逐个添加工作节点。密钥和证书按照下面的流程,通过 sidecar 文件在节点间复制,因此无需手动抄写值。

工作节点列表的权威来源 — compose/workers.roster​

存在哪些工作节点的权威来源是 compose/workers.roster 这一个文件。每一行是 <id> <ip> 格式,如果是单节点安装,该文件为空是正常的。

# compose/workers.roster
1 10.99.0.101
项目含义
idPP_WORKER_ID。容器名(plantpulse-worker-<id>)和卷名(pw-<id>-*)的后缀
ippp-net(10.99.0.0/24)上的固定地址。.1 是网关,.100 是数据湖,因此 从 .101 开始使用

compose/docker-compose.worker.yml 在此文件中生成(bin/gen-worker-compose.sh),bin/env.sh 也从同一文件推导出工作节点 IP 和节点列表。这样 compose、运维脚本、密钥轮换守护就不会看到不同的工作节点集合。

不要手动修改生成的文件

docker-compose.worker.yml 是生成物。手动修改会导致 CI 的 gen-worker-compose.sh --check 失败。增减工作节点不是在 roster 中添加或删除行,而是使用下面的 worker-add.sh / worker-decommission.sh + worker-remove.sh — 因为工作节点带有 Aster TSDB 令牌范围和 PostgreSQL 复制槽,仅修改列表无法创建或删除它们。

工作节点相关环境变量 (bin/env.sh)​

变量默认值说明
DOCKER_PW_NAMEplantpulse-worker工作节点容器名前缀 (plantpulse-worker-1 …)
DOCKER_PW_MEMORY60G,若主机较小则为 RAM 的 90%(与主节点的 DOCKER_DATALAKE_MEMORY 分开设定)工作节点容器内存上限
DOCKER_PW_IP_<n> · PP_WORKER_NODES从 roster 推导请勿手动填写
不要随意降低工作节点内存

工作节点使用与数据湖主节点相同的镜像(2026-08-31 整合),因此镜像中烧录的 JVM 大小也相同 — 单个 Aster TSDB 需要 -Xms16G/-Xmx16G。根据主机大小按比例设定的方式是错误的。所需量由服务配置决定,而非主机。

2026-08-31 实测:旧 12g 默认值的工作节点在 Aster TSDB 加入环之前就被 OOMKilled,容器以 OOMKilled=true 状态死亡,同时未发生 join,却一直保持 health: starting。

添加工作节点​

cd /opt/kopens/plantpulse-platform-docker

bin/worker-add.sh # 빈 id·빈 주소 자동 선택
bin/worker-add.sh 3 # id 지정
bin/worker-add.sh 3 10.99.0.103 # id·주소 지정

worker-add.sh 按顺序执行以下操作。

  1. 在 roster 中注册(已存在的 id 不属于“添加”,因此会被拒绝)
  2. 重新生成叠加 compose
  3. 创建卷 → 拉取镜像 → up -d
  4. 确认环加入 — 通过主节点的 nodetool 直接验证
“容器已启动”并不是加入的证据

工作节点同时带有 Aster TSDB 令牌范围、Spark Worker 注册、PostgreSQL 复制槽、Redis 复制链接。容器自身的就绪检查只检查“是否能访问主节点”,因此加入失败的工作节点也会像成功的工作节点一样报告为正常。

2026-08-31 实测:一个 Aster TSDB 被 OOMKilled 的工作节点,在环仍为 1 节点的情况下保持 health: starting。因此 worker-add.sh 会直接询问环本身。

工作节点运维​

cd /opt/kopens/plantpulse-platform-docker

# 진입 (워커는 기본 스택의 서비스가 아니라 shell.sh 로는 잡히지 않습니다)
docker exec -ti plantpulse-worker-3 /bin/bash

# 정지 — compose 동사 그대로
docker compose -f compose/docker-compose.yml -f compose/docker-compose.worker.yml \
--profile worker-3 stop plantpulse-worker-3

# 이미지 갱신 (이미 도는 워커. 추가 시점의 pull 은 worker-add.sh 안에 들어 있습니다)
docker compose -f compose/docker-compose.yml -f compose/docker-compose.worker.yml \
--profile worker-3 pull plantpulse-worker-3
docker compose -f compose/docker-compose.yml -f compose/docker-compose.worker.yml \
--profile worker-3 up -d plantpulse-worker-3

移除工作节点 — 必须按此顺序​

bin/worker-decommission.sh 3 # 데이터 이관 + 링 이탈 확인 + 복제 슬롯 정리
bin/worker-remove.sh # 그 다음에 컨테이너 제거
对存活的工作节点执行 docker rm 不是移除,而是“遗弃”

Aster TSDB 会保留该节点的令牌范围和主机 ID,并将其记为 DN。如果 RF=3,QUORUM 仍然成立,因此不会出现任何告警。并且主节点会一直持有该工作节点的 PostgreSQL 物理复制槽,直到磁盘满为止一直固定 WAL。

worker-remove.sh 在容器运行时会被拒绝,并提示先调用 worker-decommission.sh。

已删除的工作节点脚本 (2026-08-31)

worker-run.sh · worker-stop.sh · worker-update.sh · worker-bash.sh 四个脚本已被删除。它们是以手动管理工作节点服务列表为前提创建的,在改为 roster 生成方式时,不仅是改了名字,而是直接删除了。替代方案分别是 worker-add.sh(含 pull)· compose 动词 · compose pull + up -d · docker exec。

密钥 sidecar 复制(禁止手动复制)​

在主节点生成的服务密钥位于 /etc/kopens/plantpulse-platform.env sidecar 文件中。将此文件复制到工作节点,工作节点即可使用相同凭据加入 — 请勿逐个抄写密码(与 2 节点分离文档的加入 bundle 是相同模式)。

# 마스터 노드에서 각 워커로
scp /etc/kopens/plantpulse-platform.env root@<worker-ip>:/etc/kopens/

共享 CA 复制 → 自动 seed​

节点间 TLS 信任通过共享集群 CA 建立。将主节点的 /etc/kopens/ca/ 复制到工作节点,容器启动时会自动 seed 到 pp-security 卷,无需手动放置证书。

# 마스터 노드에서 각 워커로 (컨테이너 경로 기준 자동 seed)
scp -r /etc/kopens/ca root@<worker-ip>:/etc/kopens/

platform.node.env 是节点身份文件,因此请勿复制。复制对象仅以上两项(plantpulse-platform.env、ca/)。

集群验证(Docker 环境)​

# Cassandra 링 — 모든 노드가 UN (Up Normal) 이어야 합니다
docker exec plantpulse-datalake \
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status

# Spark — 워커가 ALIVE 인지
# 브라우저에서 http://<마스터IP>:4440/ 의 Workers 탭

常见问题​

现象原因排查
工作节点无法加入环PP_MASTER_IP 在此机器上无法访问的地址修正 /etc/kopens/platform.node.env 并 bin/restart-datalake.sh
工作节点上的 Kafka 客户端仅连接主节点广播地址为回环地址将 PP_KAFKA_ADVERTISED_HOST 设置为该机器实际地址
工作节点上缺少 sidecar 值手动复制了秘密文件请使用上方“密钥 sidecar 复制”流程 — 手动复制会导致权限和换行符不一致
nodetool status 中工作节点为 DN防火墙阻止了 7000 系列端口端口配置

移除集群​

# 각 워커에서 — 컨테이너를 제거하고 데이터 볼륨은 남긴다
ssh root@<WORKER_IP> 'cd /opt/kopens/plantpulse-platform-docker && bin/remove.sh'

# 마스터에서
cd /opt/kopens/plantpulse-platform-docker && bin/remove.sh
remove.sh 与 down.sh 不同
动词容器卷
bin/down.sh仅停止 — 通过 up.sh 可直接恢复保留
bin/remove.sh删除保留(默认)

若要删除卷,需另外使用 bin/tools/remove-all-volumes.sh。 若要同时删除镜像和网络,需附加 RM_IMAGE=1 · RM_NETWORK=1。

不存在名为 bin/stop.sh 的命令 — 在切换为 compose 时,统一动词已整理为 up · down · remove · restart · status · logs · update (入门指南)。

数据磁盘按独立策略管理(如有需要,请先备份再删除)。

相关文档​