Skip to content

SomeBottle/haspark

Repository files navigation

Hadoop + Spark 容器化镜像

本镜像基于bitnami/spark:3.5.0镜像,系统为Debian 11,执行用户为root

docker pull somebottle/haspark

面向本地集群环境测试,即伪分布式

设计理念是简单配置,快速上线测试,因此配置项较少。

如果有增加配置项的需要,欢迎发Issue亦或者开Pull request

1. 关于本镜像

  • 支持 Hadoop HA(高可用)集群 的简单伪分布式环境部署。
  • 本镜像配置完成,用 docker compose 部署上线容器后,能自动交换 SSH 公钥实现节点间 SSH 免密登录
  • 依赖于SSH的多节点进程启动同步机制:本镜像在进行多个容器上Hadoop组件部署的时候,可能会等待各节点相应进程全启动完毕再进入下一步。
    在启动高可用集群的时候可能需要等待较长的一段时间。
  • 本镜像在 WSL(Ubuntu22.04LTS) 上测试完成。

2. 软件版本

  • Hadoop 3.3.6
  • Spark 3.5.0
  • Zookeeper 3.9.2

3. 可配置的环境变量

环境变量可以写成一个文件,和 docker-compose.yml 配合使用。

bitnami/spark 镜像的基础上,本镜像新增如下环境变量:

3.1. 首要配置

名称 说明 默认值
SH_HOSTS 集群中所有节点的主机名(必填),空格分隔

3.2. Hadoop通用配置

名称 说明 默认值
HADOOP_LAUNCH_MODE Hadoop部署模式 - general(普通分布式)或ha(高可用分布式) "general"
HADOOP_HDFS_REPLICATION HDFS副本数 2
HADOOP_MAP_MEMORY_MB 为每个Map任务分配的内存量 (以MiB为单位) 1024
HADOOP_REDUCE_MEMORY_MB 为每个Reduce任务分配的内存量 (以MiB为单位) 1024

3.3. Hadoop普通分布式

名称 说明 默认值
GN_NAMENODE_HOST HDFS NameNode所在主节点主机名
GN_HADOOP_WORKER_HOSTS 空格分隔的HDFS从节点主机名列表
GN_DATANODE_ON_MASTER 在HDFS NameNode所在节点上是否启动DataNode "false"
GN_SECONDARY_DATANODE_HOST Secondary Namenode所在结点的主机名,留空则不启动
GN_RESOURCEMANAGER_HOST Yarn ResourceManager所在节点
GN_NODEMANAGER_WITH_RESOURCEMANAGER 在ResourceManager所在节点是否启动NodeManager "false"
GN_NODEMANAGER_WITH_RESOURCEMANAGER 在ResourceManager所在节点是否启动NodeManager "false"
GN_HDFS_SETUP_ON_STARTUP 是否在容器启动时自动启动HDFS各个节点的守护进程 "false"
GN_YARN_SETUP_ON_STARTUP 是否在容器启动时自动启动Yarn各个节点的守护进程 "false"
GN_ZOOKEEPER_START_ON_STARTUP 是否在容器启动时自动启动Zookeeper各个节点的守护进程 "false"

3.4. Hadoop高可用(HA)分布式

名称 说明 默认值
HA_HDFS_NAMESERVICE HDFS高可用集群的服务名(逻辑地址) "hacluster"
HA_HDFS_SETUP_ON_STARTUP 是否部署高可用 HDFS 集群 "false"
HA_NAMENODE_HOSTS 需要启动NameNode的节点的主机名列表(空格分隔)
HA_JOURNALNODE_HOSTS 需要启动JournalNode的节点的主机名列表(空格分隔)
HA_DATANODE_HOSTS 需要启动DataNode的节点的主机名列表(空格分隔)
HA_YARN_SETUP_ON_STARTUP 是否部署高可用 Yarn 集群 "false"
HA_RESOURCEMANAGER_HOSTS 需要启动ResourceManager的节点的主机名列表(空格分隔)
HA_NODEMANAGER_HOSTS 需要启动NodeManager的节点的主机名列表(空格分隔)

3.5. 只读环境变量

除了 bitnami/spark 提供的只读环境变量外,本镜像还提供了:

(可以调用 source /etc/profile 来载入这些环境变量到当前 Shell 中)

名称 说明
ZOOKEEPER_VER Zookeeper版本
ZOOKEEPER_HOME Zookeeper安装目录
ZOOKEEPER_CONF_DIR Zookeeper配置目录
ZOOKEEPER_DATA_DIR Zookeeper数据目录(zoo.cfg中的dataDir配置)
HADOOP_VER Hadoop版本
HADOOP_HOME Hadoop安装目录
HADOOP_CONF_DIR Hadoop配置文件目录
HADOOP_LOG_DIR Hadoop日志目录
HDFS_SERVICE_ADDR HDFS 服务地址。示例: 普通分布式-> host:port; HA 分布式-> mycluster
ZOOKEEPER_QUORUM Zookeeper集群各节点地址,逗号分隔。示例: host1:2181,host2:2181,host3:2181
TEMP_PASS_FILE SSH 临时密码文件的路径,在 SSH 公钥自动交换完毕后此文件将被自动删除(可用于判断 SSH 服务是否就绪)
INIT_FLAG_FILE 容器初始化标记文件,在Hadoop初始化完毕后,此文件会被自动删除

4. 提供的脚本

4.1. 查询集群各容器的Java进程

在命令行执行jpsall即可,脚本实际位于/opt/somebottle/haspark/tools/jpsall

4.2. Zookeeper集群管理脚本

命令行: zoo <start|stop|status>

脚本实际位于/opt/somebottle/haspark/tools/zoo

4.3. Hadoop集群启停脚本

命令行:

  1. 启动集群中所有节点的相应守护进程: start-dfs.sh | stop-dfs.sh | start-yarn.sh | stop-yarn.sh | start-all.sh | stop-all.sh
  2. 启动本机的相应守护进程: start-dfs-local.sh | stop-dfs-local.sh | start-yarn-local.sh | stop-yarn-local.sh | start-all-local.sh | stop-all-local.sh

脚本实际位于/opt/somebottle/haspark/tools/中。

4.4. WordCount测试脚本

本脚本用于测试Hadoop集群是否能正常工作。

命令行: test-wordcount.sh

脚本实际位于/opt/somebottle/haspark/tools/test-wordcount.sh

4.5 文件同步脚本

本脚本用于将某个节点上的文件同步到其他所有节点上(根据上面配置的 $SH_HOSTS 环境变量)。

命令行: xsync <文件名列表>

脚本实际位于/opt/somebottle/haspark/tools/xsync

5. 容器部署

5.1. 拉取

docker pull somebottle/haspark[:tag]

[:tag]可选,默认为latest

5.2. 编写Docker Compose配置

要快速部署伪分布式集群,可以使用Docker Compose工具。

示例配置如下,1 master + 2 worker的分配。

==> 展开查看 <==
version: '3'

services:
  haspark-main:
    image: somebottle/haspark:3.2.0
    hostname: shmain
    env_file: ./conf.env
    environment:
      - SPARK_MODE=master
    volumes:
      - haspark-hdfs-shmain-name:/root/hdfs/name # namenode数据
      - haspark-hdfs-shmain-journal:/root/hdfs/journal
      - haspark-hdfs-shmain-data:/root/hdfs/data
      - ~/docker/spark/share:/opt/share # 三个容器映射到相同的共享目录
    ports:
      - '8080:8080'
      - '8088:8088'
      - '4040:4040'
      - '8042:8042'
      - '9870:9870'
      - '19888:19888'
  haspark-worker-1:
    image: somebottle/haspark:3.2.0
    hostname: shworker1
    env_file: ./conf.env
    environment:
      - SPARK_MODE=worker
      - SPARK_MASTER_URL=spark://shmain:7077
      - SPARK_WORKER_MEMORY=1G
      - SPARK_WORKER_CORES=1
    volumes:
      - ~/docker/spark/share:/opt/share
      - haspark-hdfs-worker1-name:/root/hdfs/name # namenode数据
      - haspark-hdfs-worker1-journal:/root/hdfs/journal
      - haspark-hdfs-worker1-data:/root/hdfs/data # datanode数据
    ports:
      - '8081:8081'
  haspark-worker-2:
    image: somebottle/haspark:3.2.0
    hostname: shworker2
    env_file: ./conf.env
    environment:
      - SPARK_MODE=worker
      - SPARK_MASTER_URL=spark://shmain:7077
      - SPARK_WORKER_MEMORY=1G
      - SPARK_WORKER_CORES=1
    volumes:
      - ~/docker/spark/share:/opt/share
      - haspark-hdfs-worker2-name:/root/hdfs/name # namenode数据
      - haspark-hdfs-worker2-journal:/root/hdfs/journal
      - haspark-hdfs-worker2-data:/root/hdfs/data # datanode数据
    ports:
      - '8082:8081'
      - '8089:8088'
      - '9871:9870'

volumes:
  haspark-hdfs-shmain-name:
  haspark-hdfs-shmain-data:
  haspark-hdfs-shmain-journal:
  haspark-hdfs-worker1-name:
  haspark-hdfs-worker1-data:
  haspark-hdfs-worker1-journal:
  haspark-hdfs-worker2-name:
  haspark-hdfs-worker2-data:
  haspark-hdfs-worker2-journal:

这其实就是本仓库的docker-compose.yml,其搭配着conf.env进行配置

  • 端口映射相关的配置可以参考这里

本仓库的配置使得容器首次上线时,会创建几个Docker卷。

随后这些Docker卷会保持映射到HDFS的NameNodeDataNode目录(在HA集群下还有JournalNode的数据目录),以实现HDFS数据持久化(除非你移除了这些卷)。

Docker Compose Volume配置文档:
https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose

5.3. 上线容器

docker-compose.yml所在目录中执行:

docker compose up -d # 守护模式启动

5.4. 停止和启动容器

⚠️ 建议你在执行这一步前先在容器内调用stop-all.sh脚本停止Hadoop集群。

docker-compose.yml所在目录中执行:

docker compose stop # 停止容器
docker compose start # 启动容器

5.5. 下线容器

docker-compose.yml所在目录中执行。

  1. 下线容器,保留HDFS数据:

    ⚠️ 建议你在执行这一步前先在容器内调用stop-all.sh脚本停止Hadoop集群。

    docker compose down
  2. 如果你想把HDFS的数据连带清空:

    (这个操作会把相关的Docker卷全部移除)

    docker compose down -v # v代表volumes

5.6. 启动与停止Hadoop

你可以在集群任意一个节点上执行以下脚本。

Hadoop集群启动脚本:

start-all.sh  

Hadoop集群停止脚本:

stop-all.sh  

6. 容器内常用端口

以下是本镜像创建的容器内部常用端口,你可以选择性地在docker-compose.yml中将一些端口映射到宿主机。

注:本镜像采用的大多是默认端口。

端口 服务
9870 Namenode WebUI(http)
8088 Yarn ResourceManager WebUI(http)
8042 Yarn NodeManager WebUI(http)
19888 Yarn JobHistory WebUI(http)
8020 fs.defaultFS绑定到的端口;Namenode的RPC端口
8485 JournalNode的RPC端口
2181 Zookeeper对客户端开放的端口

更多默认端口可参考官方文档:

7. 数据存储目录

7.1. HDFS

  • NameNode: /root/hdfs/name
  • DataNode: /root/hdfs/data
  • JournalNode: /root/hdfs/journal

-> 建议挂载卷(Volume)到NameNode和DataNode以及JournalNode的目录上,可以保留HDFS的数据。
-> 尤其在高可用集群中,要注意根据NameNode和DataNode所在容器决定挂载规则。
-----> 比如在只有NameNode的节点上可以仅挂载NameNode的卷,但若同时还有DataNode,则也要挂载DataNode的卷。

7.2. 日志

  • Hadoop的日志位于/opt/hadoop/logs目录。
  • 容器启动时初始化的日志位于/opt/somebottle/haspark/logs目录,用于调试。

感谢

License

Apache License, Version 2.0