跳到主要内容

集群安装

为大规模工作负载配置 PlantPulse 为主节点 + 工作节点集群的方法。您可以从单节点开始,当处理量达到瓶颈时逐步扩展。

多节点配置的两种方式 — 目的不同

配置目的文档
主/工作节点集群水平扩展基础设施(Cassandra·Kafka·Spark) — 将同一层分散到多个节点本文档
数据湖/应用2节点分离垂直分离存储/处理层和控制台/批处理层(分别在不同主机上) — 按节点降低内存·隔离负载2节点分离安装

如果处理量不足需要扩展基础设施,使用 ①;如果单个主机内存不足或需要隔离批处理负载,使用 ②。两者不互斥,PP_MODE(集群化)和 PP_TIER(分层网关)是正交的。

何时扩展为集群?

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

集群拓扑

硬件要求

每个工作节点推荐配置:

项目最低标准大规模
CPU16 vCPU32 vCPU48 vCPU
内存64 GB128 GB200+ GB
数据磁盘200 GB NVMe1 TB NVMe4 TB NVMe
网络1 Gbps10 Gbps10 Gbps

节点间网络:集群节点之间推荐 10 Gbps 或以上。Cassandra repair、Kafka 复制、Spark shuffle 流量很大。

前置条件

主节点和所有工作节点必须完成以下准备:

  • 满足系统要求
  • 配置主机名/固定 IP/DNS
  • 时间同步 (chronyd) — 节点间时间差必须 ≤ 100ms
  • OS 调优 (limits / sysctl / swap off)
  • 节点间专网通信可用 (RFC 1918 或 Tailscale)
  • 允许集群内部端口 (Cassandra 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 逐个添加工作节点。密钥/证书通过以下流程作为边车文件在节点间复制,无需手工移动数值。

工作节点列表的单一真实来源 — 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 — 工作节点拥有 Cassandra 令牌范围和 PostgreSQL 复制槽,仅修改列表既无法创建也无法删除。

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

变量默认值说明
DOCKER_PW_NAMEplantpulse-worker工作节点容器名前缀 (plantpulse-worker-1 …)
DOCKER_PW_MEMORYDOCKER_DATALAKE_MEMORY 相同的值(80G,主机较小时为 RAM 的 90%)工作节点容器内存上限
DOCKER_PW_IP_<n> · PP_WORKER_NODES从 roster 推导不手工填写
不要随意降低工作节点内存

工作节点使用与数据湖主节点相同的镜像(2026-08-31 版本合并),因此该镜像中烧录的 JVM 大小也保持不变 — Cassandra 单独需要 -Xms16G/-Xmx16G。按主机规模成比例分配的方式是错误的。所需容量由服务配置决定,不是主机。

2026-08-31 实测:旧的 12g 默认值工作节点在 Cassandra 加入环前被 OOMKilled,容器以 OOMKilled=true 状态死亡,但加入从未发生,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. 创建卷 → pull 镜像 → up -d
  4. 确认加入 — 通过主节点的 nodetool 直接验证
「容器启动」不是加入的证据

工作节点同时拥有 Cassandra 令牌范围、Spark 工作节点注册、PostgreSQL 复制槽、Redis 复制链接。容器自身的就绪检查只查看「是否可触及主节点」,所以加入失败的工作节点与成功工作节点表现完全相同为正常

2026-08-31 实测:Cassandra 被 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 是遗弃而非移除

Cassandra 通过 DN 持有该节点的令牌范围和 host id。当 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

密钥边车复制 (禁止手工复制)

主节点生成的服务密钥位于 /etc/kopens/plantpulse-platform.env 边车文件中。将此文件复制到工作节点,工作节点即可用相同凭证加入 — 不要逐个手工移动密码(模式与 2 节点分离文档的加入包相同)。

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

复制共享 CA → 自动初始化

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

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

platform.node.env节点身份文件,不要复制。复制目标仅为上述两项(plantpulse-platform.envca/)。

集群验证 (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 탭

原生(二进制)集群流程

当前版本不支持二进制(原生)安装

以下为已采用二进制安装的现有系统保留的流程。现行发行版仅支持上述 Docker Compose 方案,新部署请勿使用。

1. 主节点安装

主节点遵循单节点安装流程。

1.1 主节点安装

# 마스터 노드에서
mkdir -p /opt/kopens
cd /opt/kopens
tar -xzvf plantpulse-platform-2026.05.tgz

cd /opt/kopens/plantpulse-platform/tools
./setup.sh
# 노드 모드 입력: MASTER
# HOST IP: 192.168.0.41
# SERVICE IP: 192.168.0.41 (외부 노출 IP)

1.2 env.local.sh 调整 (集群选项)

env.sh 由部署覆盖,是 SSOT(值的单一真实来源),不要直接修改。机器特定值在同目录的 env.local.sh 中以覆盖形式编写(env.sh 在最开始优先 source,因此总是优先应用)。详见二进制安装第 4 节。

vi /opt/kopens/plantpulse-platform/plantpulse-startup/env.local.sh
# 마스터 노드
export PP_MODE=MASTER
export PP_HOST_IP=192.168.0.41
export PP_SERVICE_IP=192.168.0.41
export PP_MASTER_IP=192.168.0.41
export PP_PUBLIC_IP=192.168.0.41

# 클러스터 자원
export PP_CLUSTER_CORES=64 # 마스터 + 워커 코어 합 (Spark 사용)
export PP_CLUSTER_MEMORY_BY_CORE=2G

# TLS SAN 에 모든 노드 IP / 도메인 포함
export PP_TLS_SAN_IPS="192.168.0.41,192.168.0.101,192.168.0.102,192.168.0.103,127.0.0.1"
export PP_TLS_SAN_DNS="plantpulse-master,plantpulse-worker-1,plantpulse-worker-2,plantpulse-worker-3,localhost"
export PP_TLS_NODE_NAMES="master worker-1 worker-2 worker-3"

1.3 启动主节点

cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./configure.sh
./prepare-ssl.sh
./start-daemon.sh
./status.sh

2. 添加工作节点

2.1 工作节点安装

在各工作节点上执行相同流程。

# 워커 노드 (예: 192.168.0.101) 에서
mkdir -p /opt/kopens
cd /opt/kopens
tar -xzvf plantpulse-platform-2026.05.tgz

cd /opt/kopens/plantpulse-platform/tools
./setup.sh
# 노드 모드 입력: WORKER
# HOST IP: 192.168.0.101
# SERVICE IP: 192.168.0.101
# MASTER IP: 192.168.0.41

2.2 工作节点 env.local.sh 调整 (仅节点特定值)

仅在 env.local.sh 中编写 IP 等机器特定值(env.sh 直接修改 ✗)。

vi /opt/kopens/plantpulse-platform/plantpulse-startup/env.local.sh
# 워커 노드
export PP_MODE=WORKER
export PP_HOST_IP=192.168.0.101 # 이 워커의 IP
export PP_SERVICE_IP=192.168.0.101
export PP_MASTER_IP=192.168.0.41 # 마스터의 IP
export PP_PUBLIC_IP=192.168.0.101

密码/密钥库密码不要手工移到这里 — 通过下面的密钥边车在节点间同步。

2.3 密钥边车复制

服务密钥位于主节点的 /etc/kopens/plantpulse-platform.env 边车文件中。将此文件复制到工作节点,工作节点即可用相同凭证加入(模式与 2 节点分离文档的加入包相同)。不要逐个手工移动密码。

# 마스터에서 워커로 (env.sh 보다 먼저 source 되는 사이드카)
scp /etc/kopens/plantpulse-platform.env root@192.168.0.101:/etc/kopens/

2.4 复制共享 CA → 自动初始化

节点间 TLS 信任通过共享集群 CA 建立。将主节点的 /etc/kopens/ca/ 复制到工作节点,启动时会根据容器路径自动初始化,无需手工部署证书。

# 마스터에서 워커로 (공유 CA — 크로스노드 TLS 신뢰)
scp -r /etc/kopens/ca root@192.168.0.101:/etc/kopens/

platform.node.env 是节点身份文件,不要复制。

2.5 启动工作节点

cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./configure.sh
./start-daemon.sh
./status.sh

查看工作节点的 status.sh 输出,以下内容显示 RUNNING 则正常:

  • Cassandra (:9042)
  • Kafka (:9092)
  • Spark Worker (:8081)

注意:工作节点不运行 server / cep / batch 等应用模块。仅基础设施/分布式处理组件被集群化。

3. 集群验证

3.1 Cassandra 集群

# 마스터에서
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./pd node status

预期输出示例:

Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 192.168.0.41 45.2 GiB 256 ? <uuid> rack1
UN 192.168.0.101 44.8 GiB 256 ? <uuid> rack1
UN 192.168.0.102 45.5 GiB 256 ? <uuid> rack1

所有节点都显示 UN (Up Normal) 则正常。

3.2 Kafka 集群

cd /opt/kopens/plantpulse-platform/plantpulse-messaging/kafka/bin
./kafka-broker-api-versions.sh --bootstrap-server 192.168.0.41:9092 | head

显示 3 个 broker 则正常。

3.3 Spark 集群

在浏览器中访问主节点的 Spark UI:

http://192.168.0.41:4440/

Workers 标签页检查所有工作节点是否为 ALIVE 状态。

4. 集群运维

动态添加工作节点 (扩展)

已运营集群添加工作节点的流程:

移除工作节点

# 1. 워커를 안전하게 비우기 (Cassandra)
ssh root@192.168.0.103 \
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node drain

# 2. 마스터에서 노드 제거
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./pd node remove
# 호스트 ID 입력

# 3. 워커 정지 후 제거
ssh root@192.168.0.103 \
/opt/kopens/plantpulse-platform/plantpulse-startup/stop.sh

节点替换

故障节点更换新节点时,参考管理员:节点替换流程。核心是保持相同 IP/主机名,启动新节点后在 bootstrap 模式下拉取数据。

5. 集群备份

主节点的 plantpulse-backup 负责整个集群。

cd /opt/kopens/plantpulse-platform/plantpulse-backup/bin

# Cassandra: 모든 노드에서 snapshot 수집
./backup.sh --cassandra

# PostgreSQL: 마스터에서만
./backup.sh --postgres

参考备份与恢复

常见问题

症状原因处理
工作节点无法加入seed 节点未设置检查 cassandra.yaml 中的 seeds 是否包含主节点 IP
Cassandra 令牌不均不当加入pd node cleanup + 令牌重分配
Kafka 未充分复制broker 宕机kafka-topics.sh --describe + 检查复制因子
Spark Worker 未注册防火墙阻止 7077专网允许 7077、8081 双向
证书不匹配keystore 同步遗漏从主节点重新运行 prepare-ssl.sh + 工作节点重新部署
时间不同步NTP 未设置检查 chronyc tracking,保持 ≤ 100ms

集群卸载

# 각 워커에서
ssh root@<WORKER_IP> /opt/kopens/plantpulse-platform/plantpulse-startup/stop.sh
ssh root@<WORKER_IP> rm -rf /opt/kopens/plantpulse-platform

# 마스터에서
cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin
./stop.sh
rm -rf /opt/kopens/plantpulse-platform

# 데이터 디스크는 별도 정책으로 관리 (필요 시 백업 후 삭제)

相关文档