☰
Docker一键部署Hadoop全家桶:Hive on Tez与Spark实战
2026/10/8 4:10:06 网站建设 项目流程

简介:这是一套面向大数据初学者与进阶学习者的大数据环境搭建基础镜像组件,整合了Hadoop、Spark、Hive、Tez、Hue、Kafka等主流生态组件,适合计算机相关专业学生、教师及企业员工用于课程设计、毕业设计或项目初期立项演示。资源包共22个文件,以10个sh启动脚本、7个xml配置文件为主,辅以properties、ini、Dockerfile及README说明文档,压缩包约34KB,结构精简,便于快速部署与二次修改。内容涵盖hadoop、spark、hive、tez、hue、kafka等模块的初始化与启动脚本,以及mysql初始化、容器入口等配套逻辑,可帮助读者理解各组件间的依赖关系与配置要点。目前已有142人学习下载,代码均经测试运行成功,答辩评审平均分达96分,下载后建议先阅读README.md,适合在此基础上进行功能扩展或作为学习参考。

1. 一套能直接跑起来的 Hadoop 全家桶镜像,省掉三天搭环境的时间

如果你搭过 Hadoop 集群,大概率经历过这种场景:三台虚拟机装完 JDK,改完 hosts,配好 SSH 免密,结果 NameNode 格式化完 DataNode 死活起不来,翻日志发现是 core-site.xml 里 fs.defaultFS 端口写错了一位。更别提后面还要装 Hive、Spark、Tez、Hue,每个组件都有自己的配置文件、环境变量、依赖版本要求,一个不对就连锁报错。这套 bitdata-hadoop 镜像组件就是冲着这个痛点来的——它把 Hadoop、Spark、Hive、Tez、Hue、Kafka、HttpFS 全部打包进一个 Docker 镜像,用一份 Dockerfile 和一组初始化脚本把配置流程固化下来,启动容器就能进 Hive 敲 SQL、提交 Spark 任务。适合正在做大数据课程设计、毕设,或者需要快速拉起一套实验环境验证想法的同学。你不需要从零编译 Hadoop 源码,也不用逐个组件去官网翻安装文档,镜像里已经把这些脏活干完了。

2. 镜像里到底装了什么:组件版本、目录结构与启动链路

2.1 从 Dockerfile 和 run-bdp.sh 看镜像构建逻辑

这套资源的入口是run-bdp.sh,它负责构建镜像并启动容器。先看 Dockerfile 的大致结构,它决定了镜像里有什么、版本怎么选。

# Dockerfile 核心片段(基于项目实际结构还原) FROM centos:7 # 安装 JDK 和基础工具 RUN yum install -y java-1.8.0-openjdk-devel ssh pdsh which # 拷贝各组件安装包到镜像内 COPY hadoop /opt/hadoop COPY spark /opt/spark COPY hive /opt/hive COPY tez /opt/tez COPY hue /opt/hue COPY kafka /opt/kafka # 拷贝配置文件和初始化脚本 COPY conf /opt/conf COPY scripts /opt/scripts # 设置环境变量 ENV HADOOP_HOME=/opt/hadoop ENV SPARK_HOME=/opt/spark ENV HIVE_HOME=/opt/hive ENV TEZ_HOME=/opt/tez ENV PATH=$PATH:$HADOOP_HOME/bin:$SPARK_HOME/bin:$HIVE_HOME/bin # 容器启动入口 ENTRYPOINT ["/opt/scripts/entrypoint.sh"]

这里有几个关键点值得注意。基础镜像是 CentOS 7,JDK 用的是系统自带的 OpenJDK 1.8,这是 Hadoop 2.x/3.x 生态最稳的搭配。各组件不是通过包管理器安装的,而是直接把预编译好的目录 COPY 进去,这意味着版本在打包时就已经锁死了,不会出现“今天 yum 装了个新版本导致不兼容”的问题。entrypoint.sh是容器启动后的第一个脚本,它会依次调用hadoop_init.sh、hive_start.sh、start_kafka.sh等,把整个服务链路拉起来。

run-bdp.sh则是给使用者用的封装脚本,常见写法是:

#!/bin/bash # run-bdp.sh 典型用法 docker build -t bitdata-hadoop:latest . docker run -d --name bdp \ -p 8020:8020 -p 8088:8088 -p 9870:9870 \ -p 10000:10000 -p 8888:8888 -p 9092:9092 \ -v $(pwd)/data:/data \ bitdata-hadoop:latest

端口映射对应关系:8020 是 HDFS NameNode RPC 端口,8088 是 YARN ResourceManager Web UI,9870 是 HDFS NameNode Web UI(Hadoop 3.x),10000 是 HiveServer2 的 Thrift 端口,8888 是 Hue Web 界面,9092 是 Kafka Broker。如果你只想跑单机实验,这些端口全部映射到本机即可;如果要模拟集群,可以把多个容器加入同一个 Docker 网络,用容器名做主机名解析。

2.2 各组件版本选择与目录布局

镜像里各组件的版本虽然没有在项目正文里明确写出,但从目录结构和常见搭配来看,大概率是 Hadoop 3.x + Spark 3.x + Hive 3.x + Tez 0.10.x + Hue 4.x 这一套。为什么这么选?Hadoop 3.x 对 Docker 和容器化支持更好,NameNode 支持多 Standby,HDFS 擦除编码也在这个版本引入。Spark 3.x 对 Spark SQL 的优化更成熟,AQE(自适应查询执行)默认开启,跑 TPC-DS 这类基准测试时比 2.x 快不少。Hive 3.x 的 LLAP 和物化视图功能对交互式查询有帮助,而且 Hive on Tez 的配置在 3.x 里更简洁。

目录布局上,/opt/hadoop下是标准的bin、sbin、etc/hadoop、share结构,etc/hadoop里放的是 core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml 这几个核心配置文件。/opt/spark/conf下是 spark-env.sh 和 spark-defaults.conf。/opt/hive/conf下是 hive-site.xml。/opt/tez/conf下是 tez-site.xml。/opt/hue/desktop/conf下是 hue.ini。这些配置文件在镜像构建时就已经写好了默认值,指向本机服务,所以容器一启动就能用。

scripts目录下的脚本分工明确:hadoop_init.sh负责格式化 HDFS(如果还没格式化过)并启动 NameNode、DataNode、ResourceManager、NodeManager;hive_start.sh负责启动 HiveServer2 和 MetaStore;start_kafka.sh启动 Kafka Broker;mysql_init.sh初始化 Hive 元数据库(Hive 默认用 MySQL 存元数据);wait_to_die.sh是一个保活脚本,防止容器主进程退出。entrypoint.sh按顺序调用这些脚本,中间用sleep和端口检测来保证启动顺序正确。

2.3 启动流程与验证方法

容器启动后,你可以通过以下步骤验证各组件是否正常:

# 进入容器 docker exec -it bdp bash # 检查 HDFS 是否可写 hdfs dfs -mkdir -p /user/test hdfs dfs -ls / # 检查 YARN 节点 yarn node -list # 进入 Hive 命令行 hive -e "show databases;" # 提交一个 Spark 任务 spark-submit --class org.apache.spark.examples.SparkPi \ --master yarn --deploy-mode client \ /opt/spark/examples/jars/spark-examples_2.12-3.2.0.jar 10

如果hdfs dfs -ls /能列出目录,说明 NameNode 和 DataNode 通信正常。yarn node -list显示节点状态为 RUNNING,说明 NodeManager 注册成功。Hive 能执行show databases说明 MetaStore 和 MySQL 连接没问题。SparkPi 跑完输出 Pi 的近似值,说明 Spark on YARN 链路通了。

提示:首次启动时hadoop_init.sh会执行hdfs namenode -format,这个过程只需要一次。如果你重启容器后发现 HDFS 数据丢失,检查一下 data 目录是否挂载到了宿主机,否则容器删除后数据就没了。

3. 从零复现:构建镜像、启动容器、跑通第一个 Hive on Tez 查询

3.1 构建前的环境检查与依赖准备

在跑run-bdp.sh之前,先确认宿主机环境。Docker 版本建议 20.10 以上,因为需要用到--network和-v挂载的一些特性。内存至少给 8GB,Hadoop 全家桶加上 Hive 和 Spark 同时跑,4GB 会非常卡。磁盘预留 20GB 以上,镜像本身加上 HDFS 数据目录,空间不够会直接报No space left on device。

# 检查 Docker 版本和资源 docker version docker info | grep -E "Total Memory|CPUs" # 如果内存不够,可以限制各组件堆大小 # 在 hadoop_init.sh 里调整 HADOOP_HEAPSIZE export HADOOP_HEAPSIZE=1024 export YARN_HEAPSIZE=512

HADOOP_HEAPSIZE控制 NameNode 和 DataNode 的 JVM 堆大小,默认可能是 1000MB。如果你宿主机内存只有 8GB,建议把 NameNode 堆调到 1024MB,DataNode 调到 512MB,YARN NodeManager 调到 512MB,HiveServer2 调到 1024MB。这些值可以在hadoop_init.sh和hive_start.sh里通过环境变量覆盖。

还有一个容易忽略的点:宿主机的时间同步。如果宿主机时间不准,容器内的时间也会跟着偏,导致 YARN 的 ResourceManager 和 NodeManager 心跳超时,节点显示为 UNHEALTHY。启动前执行date确认一下,偏差超过 30 秒就先用ntpdate同步一下。

3.2 构建镜像与启动容器

# 解压资源包 unzip bitdata-hadoop-master.zip cd bitdata-hadoop-master # 赋予脚本执行权限 chmod +x run-bdp.sh build.sh scripts/*.sh # 构建镜像(如果 run-bdp.sh 里已经包含 build 步骤,这步可跳过) ./build.sh # 启动容器 ./run-bdp.sh

build.sh里通常就是docker build -t bitdata-hadoop .这一条命令。run-bdp.sh除了docker run之外,可能还会做一些端口检测和目录创建。如果你看到脚本里有docker rm -f bdp这样的命令,说明它会先清理旧容器再启动新的,避免端口冲突。

启动完成后,用docker ps确认容器状态是 Up。如果容器启动后立刻退出,用docker logs bdp看日志。常见原因是entrypoint.sh里某个脚本执行失败导致主进程退出。比如mysql_init.sh在 MySQL 还没完全启动时就尝试建表,会报连接拒绝。解决办法是在entrypoint.sh里加一个等待循环:

# 等待 MySQL 就绪 until mysqladmin ping -h localhost --silent; do echo "Waiting for MySQL..." sleep 2 done

3.3 跑通 Hive on Tez 查询与 Spark 读取 JSON 数据

Hive on Tez 是这套镜像的一个亮点。Tez 把多个 MapReduce 任务合并成一个 DAG,避免了中间结果落盘,跑复杂 SQL 时比原生 MapReduce 快很多。验证 Tez 是否生效:

-- 进入 Hive 后设置执行引擎 set hive.execution.engine=tez; -- 创建测试表 CREATE TABLE IF NOT EXISTS test_tez ( id INT, name STRING ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; -- 插入数据 INSERT INTO test_tez VALUES (1, 'alice'), (2, 'bob'), (3, 'charlie'); -- 执行聚合查询 SELECT count(*) FROM test_tez;

如果查询能正常返回结果,并且 YARN 的 Web UI(http://localhost:8088)里能看到 Tez 的 DAG 执行记录,说明 Tez 集成成功。注意hive.execution.engine这个参数在 Hive 3.x 里默认可能是mr,需要手动改成tez,或者在hive-site.xml里写死。

Spark 读取 JSON 数据也是高频操作。镜像里已经配好了 Spark on YARN,可以直接提交任务:

# spark_read_json.py from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("ReadJSON") \ .master("yarn") \ .getOrCreate() # 读取 HDFS 上的 JSON 文件 df = spark.read.json("hdfs://localhost:8020/user/test/data.json") df.printSchema() df.show() # 按字段聚合 df.groupBy("category").count().show() spark.stop()

提交命令:

spark-submit --master yarn --deploy-mode client spark_read_json.py

这里master指定为yarn,deploy-mode用client方便看日志。如果数据文件在本地而不是 HDFS,把路径改成file:///data/data.json即可。注意 Spark 读取 JSON 时,如果某行格式不合法,默认会报错。可以在spark.read.json里加mode="PERMISSIVE"让非法行变成 null 而不是中断任务。

4. 避坑与排查:HDFS 格式化、端口冲突、Tez 提交失败、Hive 元数据连接

4.1 HDFS 重复格式化导致 DataNode 无法启动

现象:容器重启后,NameNode 能起来,但 DataNode 启动后立刻退出,hdfs dfsadmin -report显示没有可用 DataNode。

原因:hadoop_init.sh里可能每次启动都执行了hdfs namenode -format。格式化会生成新的 clusterID,而 DataNode 的 VERSION 文件里还是旧的 clusterID,两者不匹配,DataNode 拒绝注册。

解决:把格式化操作改成条件执行,只在dfs/name目录不存在时才格式化:

if [ ! -d "/opt/hadoop/data/dfs/name" ]; then hdfs namenode -format -force fi

如果已经格式化了两次,需要把 NameNode 和 DataNode 的 data 目录都清掉,重新格式化一次,然后只启动一次。

4.2 端口冲突导致 YARN ResourceManager 启动失败

现象:docker logs bdp里看到Address already in use,ResourceManager 进程没起来,8088 端口访问不了。

原因:宿主机上已经有其他服务占用了 8088 或 8032 端口,或者之前启动的容器没清理干净,端口还被占用着。

解决:先docker ps -a看有没有残留容器,有就docker rm -f删掉。然后netstat -tlnp | grep 8088确认宿主机端口是否被占。如果被占,改run-bdp.sh里的端口映射,比如把-p 8088:8088改成-p 18088:8088,访问时用 18088。

4.3 Tez 提交任务时报 ClassNotFoundException

现象:Hive 设置hive.execution.engine=tez后执行查询,报java.lang.ClassNotFoundException: org.apache.tez.mapreduce.hadoop.MRInputHelpers。

原因:Tez 的 jar 包没有放到 HDFS 上,或者tez-site.xml里的tez.lib.uris路径写错了。Tez 任务提交到 YARN 后,各个容器需要从 HDFS 拉取 Tez 的依赖包。

解决:把 Tez 的 tar.gz 包上传到 HDFS,并确保tez-site.xml里配置正确:

hdfs dfs -mkdir -p /tez hdfs dfs -put /opt/tez/tez-0.10.1.tar.gz /tez/
<!-- tez-site.xml --> <property> <name>tez.lib.uris</name> <value>hdfs://localhost:8020/tez/tez-0.10.1.tar.gz</value> </property>

改完后重启 HiveServer2 再试。

4.4 Hive 元数据连接 MySQL 超时

现象:启动 Hive 时卡在Initializing HiveMetaStore,日志里报Communications link failure。

原因:MySQL 容器或进程还没完全启动,Hive 就急着连了。或者hive-site.xml里的 JDBC 连接串写的是localhost,但 MySQL 实际监听在另一个地址。

解决:在hive_start.sh里加 MySQL 就绪检测,用mysqladmin ping循环等待。同时确认hive-site.xml里的javax.jdo.option.ConnectionURL是jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true,用户名和密码跟mysql_init.sh里设置的一致。

4.5 Hue 页面打不开或登录后报 500

现象:访问 http://localhost:8888 显示连接拒绝,或者登录后页面报 500 错误。

原因:Hue 依赖的 Python 环境和数据库没初始化好。Hue 默认用 SQLite 存会话,如果hue.ini里配的是 MySQL 但表没建,就会报错。

解决:进入容器执行 Hue 的同步命令:

/opt/hue/build/env/bin/hue syncdb /opt/hue/build/env/bin/hue migrate

然后重启 Hue 进程。如果还是打不开,检查hue.ini里http_port是不是 8888,以及server_user有没有权限访问 HDFS。

5. 进阶技巧:用这套镜像做 Spark 内存调优与 Hive 小文件合并

5.1 Spark 内存参数怎么调才不 OOM

Spark on YARN 跑久了,最容易翻车的就是内存。默认配置下,Executor 内存可能只有 1GB,跑个 groupBy 就 OOM。调优的核心是搞清楚spark.executor.memory、spark.executor.memoryOverhead、spark.yarn.executor.memoryOverhead这几个参数的关系。

spark-submit \ --master yarn \ --deploy-mode cluster \ --executor-memory 4g \ --executor-cores 2 \ --num-executors 4 \ --conf spark.executor.memoryOverhead=1g \ --conf spark.sql.shuffle.partitions=200 \ --conf spark.sql.adaptive.enabled=true \ spark_job.py

executor-memory是堆内内存,memoryOverhead是堆外内存(JVM 元空间、网络缓冲等)。YARN 实际分配的内存是两者之和。如果你设了executor-memory=4g但没设 overhead,YARN 可能只给 4g 多一点点,稍微有点堆外开销就超了,Container 直接被 kill。我一般会把 overhead 设成堆内存的 10% 到 15%,比如 4g 堆配 512m 到 1g overhead。

spark.sql.shuffle.partitions默认是 200,小数据量下会导致大量小任务,每个任务处理几 KB 数据,调度开销比计算还大。如果数据量不大,可以降到 20 到 50。Spark 3.x 的 AQE 开启后,这个参数会自动优化,但前提是spark.sql.adaptive.enabled=true。

5.2 Hive 小文件合并的两种手段

Hive 表如果分区多、每个分区文件又小,NameNode 内存会被大量小文件吃掉。合并小文件有两个层面:写入时合并和事后合并。

写入时合并,在 Hive SQL 里加几个参数:

set hive.merge.mapfiles=true; set hive.merge.mapredfiles=true; set hive.merge.size.per.task=256000000; set hive.merge.smallfiles.avgsize=16000000;

hive.merge.mapfiles控制 Map-only 任务结束后是否合并小文件,hive.merge.mapredfiles控制 MapReduce 任务结束后是否合并。hive.merge.size.per.task是合并后每个文件的目标大小,默认 256MB。hive.merge.smallfiles.avgsize是触发合并的平均文件大小阈值,低于这个值就合并。

事后合并,可以用INSERT OVERWRITE重写分区:

INSERT OVERWRITE TABLE target_table PARTITION(dt='2024-01-01') SELECT * FROM target_table WHERE dt='2024-01-01';

这会启动一个 MapReduce 任务,把分区内的小文件读进来,按hive.merge.size.per.task的大小重新写出。缺点是消耗资源,适合在低峰期做。

5.3 用 Hue 做交互式查询和调度监控

Hue 不只是个 SQL 编辑器,它还能看 YARN 任务执行历史、HDFS 文件浏览器、Hive 元数据管理。登录 Hue 后,在 Query Editor 里选 Hive 或 Spark,可以直接写 SQL 并查看执行计划。如果查询慢,点开 “Jobs” 标签看 Tez 或 Spark 的 DAG 图,能直观看到哪个 Stage 耗时长。

我一般会习惯在 Hue 里建一个 “临时查询” 的 notebook,把常用的show partitions、describe formatted、analyze table ... compute statistics存进去,排查问题时直接点一下就跑,不用每次开终端敲命令。还有一个技巧:Hue 的 “Schedule” 功能可以配 Oozie 或 Celery 定时任务,虽然这套镜像里不一定装了 Oozie,但用 Hue 的 “Export” 功能把查询结果导成 CSV 到 HDFS 上,再配合 Spark 做后续处理,是一条很顺的链路。

从那以后我每次拉起新环境,都会先跑一遍hdfs dfsadmin -report和yarn node -list,确认节点全绿再开始干活。这套镜像省掉的是安装和配置的时间,但集群状态还是得自己盯。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询