Docker一键部署Hadoop全家桶:Hive on Tez与Spark实战 简介这是一套面向大数据初学者与进阶学习者的大数据环境搭建基础镜像组件整合了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 7JDK 用的是系统自带的 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 UI9870 是 HDFS NameNode Web UIHadoop 3.x10000 是 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 支持多 StandbyHDFS 擦除编码也在这个版本引入。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、NodeManagerhive_start.sh负责启动 HiveServer2 和 MetaStorestart_kafka.sh启动 Kafka Brokermysql_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挂载的一些特性。内存至少给 8GBHadoop 全家桶加上 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_HEAPSIZE1024 export YARN_HEAPSIZE512HADOOP_HEAPSIZE控制 NameNode 和 DataNode 的 JVM 堆大小默认可能是 1000MB。如果你宿主机内存只有 8GB建议把 NameNode 堆调到 1024MBDataNode 调到 512MBYARN NodeManager 调到 512MBHiveServer2 调到 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.shbuild.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 done3.3 跑通 Hive on Tez 查询与 Spark 读取 JSON 数据Hive on Tez 是这套镜像的一个亮点。Tez 把多个 MapReduce 任务合并成一个 DAG避免了中间结果落盘跑复杂 SQL 时比原生 MapReduce 快很多。验证 Tez 是否生效-- 进入 Hive 后设置执行引擎 set hive.execution.enginetez; -- 创建测试表 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 UIhttp://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指定为yarndeploy-mode用client方便看日志。如果数据文件在本地而不是 HDFS把路径改成file:///data/data.json即可。注意 Spark 读取 JSON 时如果某行格式不合法默认会报错。可以在spark.read.json里加modePERMISSIVE让非法行变成 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 useResourceManager 进程没起来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.enginetez后执行查询报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 nametez.lib.uris/name valuehdfs://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?createDatabaseIfNotExisttrue用户名和密码跟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 内存参数怎么调才不 OOMSpark 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.memoryOverhead1g \ --conf spark.sql.shuffle.partitions200 \ --conf spark.sql.adaptive.enabledtrue \ spark_job.pyexecutor-memory是堆内内存memoryOverhead是堆外内存JVM 元空间、网络缓冲等。YARN 实际分配的内存是两者之和。如果你设了executor-memory4g但没设 overheadYARN 可能只给 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.enabledtrue。5.2 Hive 小文件合并的两种手段Hive 表如果分区多、每个分区文件又小NameNode 内存会被大量小文件吃掉。合并小文件有两个层面写入时合并和事后合并。写入时合并在 Hive SQL 里加几个参数set hive.merge.mapfilestrue; set hive.merge.mapredfilestrue; set hive.merge.size.per.task256000000; set hive.merge.smallfiles.avgsize16000000;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(dt2024-01-01) SELECT * FROM target_table WHERE dt2024-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确认节点全绿再开始干活。这套镜像省掉的是安装和配置的时间但集群状态还是得自己盯。希望帮到你。本文还有配套的精品资源点击获取