📋 目录


🎯 前言

Apache Storm是一个开源的分布式实时计算系统,用于处理无限数据流。本文将详细介绍如何在Docker环境中从零搭建Storm单节点和集群环境,适合实时计算初学者和进阶开发者。

💡 为什么选择Storm?

  • 高性能:每秒可处理百万级消息
  • 容错性强:自动故障恢复机制
  • 易于扩展:水平扩展能力强
  • 实时保证:毫秒级数据处理延迟

📊 本文亮点

✅ 完整的Docker Compose配置文件
✅ 详细的集群部署步骤
✅ ZooKeeper集成配置
✅ 常见错误排查指南
✅ 生产环境最佳实践


🔧 Storm核心概念

在开始搭建之前,先了解Storm的核心组件:

核心组件对比

组件作用类比
Nimbus主节点,负责任务分配和监控大脑(调度中心)
Supervisor工作节点,执行具体计算任务手脚(执行单元)
UIWeb界面,监控集群状态眼睛(监控面板)
ZooKeeper协调服务,管理集群元数据神经系统(协调器)

Storm工作流程

数据源 → Spout(数据获取) → Bolt(数据处理) → 结果输出
        ↓
    ZooKeeper(协调)
        ↓
    Nimbus(调度) → Supervisor(执行)

🛠️ 环境准备

系统要求

  • 操作系统:Windows 10/11(启用WSL 2)
  • Docker Desktop:最新版本
  • 内存要求:至少8GB RAM
  • 磁盘空间:至少20GB可用空间

前置条件检查

# 1. 检查Docker版本
docker --version
# 预期输出:Docker version 24.x.x 或更高

# 2. 检查Docker运行状态
docker ps
# 确保Docker正常运行

# 3. 检查网络列表
docker network ls
# 确认zk-net网络存在(ZooKeeper网络)

⚠️ 重要提示

在搭建Storm之前,必须先完成ZooKeeper集群的搭建,并确保ZooKeeper运行在名为zk-net的网络中。Storm依赖ZooKeeper进行分布式协调。


🚀 单节点Storm安装

步骤1:拉取Storm镜像

打开Windows PowerShell,执行以下命令:

# 拉取最新版Storm镜像
docker pull storm

# 验证镜像是否下载成功
docker images | grep storm

预期输出:

storm    latest    abc123def456    2 weeks ago    450MB

步骤2:创建Docker Compose配置文件

创建名为storm-compose.yml的文件,内容如下:

version: '3'

services:
  nimbus:
    image: storm
    restart: always
    command: storm nimbus
    container_name: nimbus
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
    ports:
      - "6627:6627"
    networks:
      - storm-network
      - zk-net

  supervisor:
    image: storm
    restart: always
    command: storm supervisor
    container_name: supervisor
    depends_on:
      - nimbus
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus"
    links:
      - nimbus:nimbus
    ports:
      - "6700:6700"
      - "6701:6701"
      - "6702:6702"
      - "6703:6703"
      - "8000:8000"
    networks:
      - storm-network
      - zk-net

  ui:
    image: storm
    restart: always
    command: storm ui
    container_name: ui
    depends_on:
      - nimbus
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus"
    links:
      - nimbus:nimbus
    ports:
      - "8080:8080"
    networks:
      - storm-network
      - zk-net

networks:
  storm-network:
  zk-net:
    external: true

📝 配置说明

配置项说明注意事项
STORM_ZOOKEEPER_SERVERSZooKeeper服务器列表修改为实际的ZK容器名称
STORM_NIMBUS_HOSTNimbus主机地址指向nimbus容器
networks网络配置必须加入zk-net网络
ports端口映射注意避免端口冲突

步骤3:启动Storm容器

# 进入配置文件所在目录
cd C:\your\path\to\storm-config

# 启动容器(后台运行)
docker-compose -f .\storm-compose.yml up -d

成功输出示例:

Creating network "storm_storm-network" with the default driver
Creating nimbus ... done
Creating supervisor ... done
Creating ui ... done

步骤4:验证容器运行状态

# 查看运行中的容器
docker ps

# 查看容器日志(可选)
docker logs nimbus
docker logs supervisor
docker logs ui

预期看到3个容器都处于UP状态:

CONTAINER ID   IMAGE   COMMAND              STATUS
abc123def456   storm   "storm nimbus"       Up 2 minutes
def456ghi789   storm   "storm supervisor"   Up 2 minutes
ghi789jkl012   storm   "storm ui"           Up 2 minutes

步骤5:🔥 关键配置修改(必须操作)

这是最容易被忽略但非常重要的一步!

5.1 进入Nimbus容器

通过Docker Desktop图形界面:

  1. 打开Docker Desktop
  2. 点击Containers
  3. 找到nimbus容器
  4. 点击容器名称进入详情页
  5. 点击Files选项卡
5.2 修改storm.yaml配置

找到/conf/storm.yaml文件并右键选择Edit,添加以下配置:

# 原有配置保持不变
# ...

# 添加ZooKeeper服务器配置
storm.zookeeper.servers:
  - "zk1"
  - "zk2"
  - "zk3"

# 添加Nimbus主机配置
nimbus.seeds: ["nimbus"]

⚠️ 注意事项:

  • zk1, zk2, zk3替换为实际的ZooKeeper容器名称
  • 配置格式严格,注意缩进和空格
  • 修改后保存文件
5.3 重启容器
# 重启nimbus容器
docker restart nimbus

# 重启supervisor容器
docker restart supervisor

# 重启ui容器
docker restart ui

步骤6:访问Storm UI

打开浏览器,访问:

http://localhost:8080

成功标志:

  • 看到Storm UI界面
  • Cluster Summary显示1个Nimbus和1个Supervisor
  • Topology summary为空(暂无拓扑任务)

🌐 Storm集群部署

单节点环境适合学习和测试,生产环境建议使用集群模式以提高可用性和性能。

集群架构设计

本示例将搭建一个1主2从的Storm集群:

  • 1个主Nimbus(nimbus1)+ 2个从Nimbus(nimbus2, nimbus3)
  • 3个Supervisor(supervisor1, supervisor2, supervisor3)
  • 1个UI(ui1)

集群配置文件

创建新的storm-cluster-compose.yml文件:

version: '3'

services:
  # ========== 主Nimbus节点 ==========
  nimbus1:
    image: storm
    restart: always
    command: storm nimbus
    container_name: nimbus1
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
    ports:
      - "6627:6627"
    networks:
      - storm-network
      - zk-net

  supervisor1:
    image: storm
    restart: always
    command: storm supervisor
    container_name: supervisor1
    depends_on:
      - nimbus1
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus1"
    links:
      - nimbus1:nimbus1
    ports:
      - "6700:6700"
      - "6701:6701"
      - "6702:6702"
      - "6703:6703"
      - "8000:8000"
    networks:
      - storm-network
      - zk-net

  ui1:
    image: storm
    restart: always
    command: storm ui
    container_name: ui1
    depends_on:
      - nimbus1
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus1"
    links:
      - nimbus1:nimbus1
    ports:
      - "8080:8080"
    networks:
      - storm-network
      - zk-net

  # ========== 从Nimbus节点2 ==========
  nimbus2:
    image: storm
    restart: always
    command: storm nimbus
    container_name: nimbus2
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus1"
    ports:
      - "6628:6627"
    networks:
      - storm-network
      - zk-net

  supervisor2:
    image: storm
    restart: always
    command: storm supervisor
    container_name: supervisor2
    depends_on:
      - nimbus2
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus1"
    links:
      - nimbus2:nimbus2
    ports:
      - "6704:6700"
      - "6705:6701"
      - "6706:6702"
      - "6707:6703"
      - "8001:8000"
    networks:
      - storm-network
      - zk-net

  # ========== 从Nimbus节点3 ==========
  nimbus3:
    image: storm
    restart: always
    command: storm nimbus
    container_name: nimbus3
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus1"
    ports:
      - "6629:6627"
    networks:
      - storm-network
      - zk-net

  supervisor3:
    image: storm
    restart: always
    command: storm supervisor
    container_name: supervisor3
    depends_on:
      - nimbus3
    environment:
      STORM_ZOOKEEPER_SERVERS: "zk1:2181,zk2:2181,zk3:2181"
      STORM_NIMBUS_HOST: "nimbus1"
    links:
      - nimbus3:nimbus3
    ports:
      - "6708:6700"
      - "6709:6701"
      - "6710:6702"
      - "6711:6703"
      - "8002:8000"
    networks:
      - storm-network
      - zk-net

networks:
  storm-network:
  zk-net:
    external: true

集群端口分配表

节点Nimbus端口Supervisor端口UI端口
节点166276700-6703, 80008080
节点266286704-6707, 8001-
节点366296708-6711, 8002-

启动集群

1. 清理旧容器(如果存在)
# 停止并删除旧的Storm容器
docker-compose -f .\storm-compose.yml down

# 或者手动删除
docker rm -f nimbus supervisor ui
2. 启动集群
# 启动集群
docker-compose -f .\storm-cluster-compose.yml up -d

预期输出:

Creating nimbus1 ... done
Creating supervisor1 ... done
Creating ui1 ... done
Creating nimbus2 ... done
Creating supervisor2 ... done
Creating nimbus3 ... done
Creating supervisor3 ... done
3. 验证集群状态
# 查看所有Storm容器
docker ps | grep storm

# 预期看到7个容器都在运行

配置集群节点

重要! 需要为每个Nimbus容器修改storm.yaml配置:

修改nimbus1配置
storm.zookeeper.servers:
  - "zk1"
  - "zk2"
  - "zk3"

nimbus.seeds: ["nimbus1", "nimbus2", "nimbus3"]
修改nimbus2和nimbus3配置
storm.zookeeper.servers:
  - "zk1"
  - "zk2"
  - "zk3"

nimbus.seeds: ["nimbus1", "nimbus2", "nimbus3"]

修改完成后,重启所有容器:

docker restart nimbus1 nimbus2 nimbus3 supervisor1 supervisor2 supervisor3 ui1

验证集群部署

访问Storm UI:http://localhost:8080

成功标志:

  • Cluster Summary显示:
    • 3个Nimbus(1个Leader,2个Follower)
    • 3个Supervisor
    • 合适的Slots总数
  • 所有组件状态为绿色

❗ 常见问题及解决方案

问题1:端口被占用

错误信息:

Error response from daemon: driver failed programming external connectivity 
on endpoint nimbus: Bind for 0.0.0.0:6627 failed: port is already allocated

解决方案:

# 方法1:停止占用端口的容器
docker ps -a
docker rm -f <container_id>

# 方法2:修改docker-compose.yml中的端口映射
ports:
  - "6630:6627"  # 改为其他未使用的端口

问题2:容器无法连接ZooKeeper

症状:

  • 容器频繁重启
  • 日志显示ZooKeeper连接失败

解决方案:

  1. 确认ZooKeeper集群正常运行:
docker ps | grep zookeeper
  1. 验证网络连通性:
# 进入Storm容器
docker exec -it nimbus bash

# 测试ZooKeeper连接
ping zk1
telnet zk1 2181
  1. 检查storm.yaml配置是否正确

问题3:UI界面无法访问

可能原因:

  • UI容器未启动
  • 端口映射配置错误
  • 防火墙阻止

排查步骤:

# 1. 检查UI容器状态
docker ps | grep ui

# 2. 查看UI容器日志
docker logs ui1

# 3. 测试端口是否开放
curl http://localhost:8080

问题4:Nimbus无法选举Leader

症状:

  • UI界面显示没有Leader Nimbus
  • 集群功能异常

解决方案:

  1. 确保所有Nimbus的storm.yaml配置一致
  2. 检查ZooKeeper连接:
# 进入任意Nimbus容器
docker exec -it nimbus1 bash

# 查看ZooKeeper中的Storm数据
storm zk-cli
ls /storm
  1. 重启所有Nimbus节点:
docker restart nimbus1 nimbus2 nimbus3

问题5:YAML格式错误

错误信息:

yaml: unmarshal errors

⚠️ YAML格式注意事项:

  • 使用空格缩进,不要使用Tab
  • 冒号后必须有空格
  • 列表项使用-符号
  • 严格遵循缩进层级

正确示例:

storm.zookeeper.servers:
  - "zk1"
  - "zk2"
  - "zk3"

错误示例:

storm.zookeeper.servers:
-"zk1"  # 缺少空格
-"zk2"

📊 集群监控与管理

通过UI监控集群

访问http://localhost:8080,可以查看:

监控项说明
Cluster Summary集群整体状态
Nimbus SummaryNimbus节点状态
Supervisor SummarySupervisor节点状态
Topology Summary运行中的拓扑任务

常用管理命令

# 查看集群状态
docker exec -it nimbus1 storm list

# 提交拓扑任务
docker exec -it nimbus1 storm jar /path/to/topology.jar MainClass

# 停止拓扑任务
docker exec -it nimbus1 storm kill topology-name

# 查看日志
docker logs -f supervisor1

🎯 总结

本文详细介绍了在Docker环境中搭建Storm单节点和集群的完整流程:

✅ 完成的工作

  1. 环境准备:Docker和ZooKeeper集群配置
  2. 单节点部署:快速搭建Storm测试环境
  3. 集群部署:生产级别的高可用集群
  4. 问题排查:常见错误的解决方案

📚 技术要点总结

技术点重要程度说明
Docker Compose⭐⭐⭐⭐⭐容器编排核心
网络配置⭐⭐⭐⭐⭐与ZooKeeper通信必须
storm.yaml配置⭐⭐⭐⭐⭐最容易出错的地方
端口映射⭐⭐⭐⭐避免冲突
高可用架构⭐⭐⭐⭐集群部署关键

🚀 下一步学习

  • Storm Topology开发(Spout和Bolt编程)
  • 与Kafka集成实现流处理
  • Storm性能调优技巧
  • 生产环境运维最佳实践

🔗 参考资源


如果觉得本文有帮助,欢迎点赞👍、收藏⭐、关注🔔!

有任何问题欢迎在评论区讨论交流!💬

更多推荐