
简介大数据基础镜像组件配套资源面向计科、人工智能、通信工程等专业学生及大数据入门开发者解决Hadoop、Spark、Hive、Tez、Hue等组件环境搭建繁琐、版本兼容难的问题。压缩包共22个文件以10个shell脚本含hadoop_init.sh、hive_start.sh、start_kafka.sh等环境初始化与启动脚本和7个xml配置文件涵盖Hadoop、Hive、Tez等组件核心配置为主另有Dockerfile、properties配置及README说明文档包体仅34KB轻量精炼。已有141人学习下载。资源源自作者高评分毕业设计代码经完整测试运行成功内含基于Docker的镜像构建方案与一键部署脚本读者可快速搭建大数据基础环境理解组件间配置联动关系并在此基础上开展实验或二次开发同时覆盖Kafka等常用组件适合课程设计、毕业设计及项目初期立项演示等场景。1. 拿镜像搭大数据环境五个组件装一次三分钟起一个集群手动在一台机器上搭 Hadoop、Spark、Hive、Tez、Hue 这一套大数据基础组件顺利的话也要将近两天先改三四个 XML再处理 SSH 和免密然后初始化 Hive 元数据库最后调 Hue 的连接。更麻烦的是这个流程每换一台机器就要重来一遍。大数据基础镜像组件要解决的正是这个问题——把组件装好、配置固定、启动方式固定全部收进一个可重复构建的镜像工程。配合编排文件一条命令就能把整套环境拉起来适合做课程设计、数据开发测试沙箱或者给团队做预研环境。别把“基础”两个字理解成简陋这一层设计得足够干净后面加调度、加监控、加数据研发平台都会顺很多。2. 镜像里的组件选型与目录设计Hadoop、Spark、Hive、Tez、Hue 怎么放才不打架2.1 为什么选镜像而不是 Ansible固化的部分越多环境越稳第一次接触这类镜像项目的人常会问组件用脚本装不就行了为什么非要做成镜像我的经验是脚本方案在机器少、一次性部署时还好但只要需要反复交付环境脚本每跑一次都可能遇到在线源失效、依赖版本漂移、系统自带包不一致的问题。镜像方案把“安装过程”变成一次构建构建完成后所有节点拿到的都是同一个文件系统快照。安装时踩过的坑只踩一次不会在后续每一台机器上重演。常见做法是把整套组件拆成“基础镜像 运行时配置”两层。基础镜像里放 JDK、Hadoop、Spark、Hive、Tez、Hue 以及 jar 包和默认配置运行时通过挂载卷和环境变量把主机名、端口、数据目录传进去。这样同一份镜像既能起伪分布式单节点也能起一主两从的小集群不需要为不同规模维护多套安装包。对比项镜像方案Ansible/Shell 脚本方案首次环境准备构建一次后续直接使用每次跑脚本依赖在线源环境一致性构建产物一致依赖被锁进镜像层受远端源和系统版本影响排错入口docker exec 进入容器定位逐步回放脚本状态难固化升级方式重构建镜像并替换容器改脚本重跑容易引入增量差异一个容易忽略的设计点把容器里的路径分成“状态”和“程序”两部分。程序目录在镜像层保持只读数据、元数据库、日志全部放挂载卷。这样升级组件时只要替换镜像层保留卷里的数据环境不会因为升级丢状态。这层思路是整个镜像项目最值得抄的部分比具体某个组件的安装命令更重要。2.2 版本兼容矩阵JDK、Hadoop、Hive、Tez、Spark 的常见组合版本是这个镜像项目里最容易翻车的地方。Hadoop、Hive、Spark 三方各自带一套依赖树只追求“新”而随意组合等到启动时才发现 ClassNotFoundException 很常见。我一般以 OpenJDK 8 为基线组件使用 Hadoop 3.3.4 Hive 3.1.3 Tez 0.10.2 Spark 3.3.2 Hue 4.10.0 的组合。这个组合的兼容关系比较清晰Hive 3.1.3 对 Tez 打包分发支持成熟Spark 3.3.x 能直接以 Hive 3.1.3 作为外部 metastoreHue 4.10 对 HiveServer2 的 thrift 协议兼容良好。组件常用基线版本选择理由JDKOpenJDK 8Hadoop 3.x 官方兼容列表的主力 JDKHadoop3.3.4比 2.x 更适合容器化YARN 配置更简单Hive3.1.3与 Tez 0.10.x 配套成熟Tez0.10.2能稳定跑在 Hadoop 3.x 上Spark3.3.2提供 Hadoop 3.3 预编译包开箱即用Hue4.10.0兼容 HiveServer2 的常见配置这里有个边界要记住Tez 的分发包需要和 Hive 所依赖的 Hadoop 客户端匹配不能随便从另一个版本目录里下载顶替否则提交任务时会出现 TezChild 类加载失败。还有一点网上不少教程还在用 Hadoop 2.x但新做的镜像项目如果选 2.xYARN 资源模型和 Tez 新版本兼容性会越来越别扭直接上 Hadoop 3.x 是这几年的常态。2.3 镜像内的目录布局与权限设计普通用户跑服务root 只做初始化镜像里的可执行程序、配置和数据目录应该分开常见的目录布局可以整理成下面这种结构/opt/bigdata/ ├── hadoop/ ├── hive/ ├── spark/ ├── tez/ ├── hue/ ├── data/ │ ├── namenode/ │ └── datanode/ ├── logs/ │ ├── hadoop/ │ ├── hive/ │ ├── spark/ │ └── hue/ └── init/ ├── start-hadoop.sh ├── start-hive.sh └── init-hive-schema.sh程序目录只读data 目录挂宿主机 volume容器重建后数据还在logs 用于排错init 目录放启动和初始化脚本。权限上我习惯创建 uid1000 的 bigdata 用户所有服务进程用这个用户跑root 只在镜像构建和初始化时使用。否则容器以内置 root 运行HDFS 写入的文件 owner 都是 root以后宿主机上做备份、清理会非常痛苦。另一个容易从裸机教程带过来的习惯是往镜像里塞 sshd 和免密。容器编排环境里NameNode 和 DataNode 的进程启动并不依赖 SSH 登录start-dfs.sh 在容器里反而会因为 ssh localhost 失败更稳的做法是每个容器通过 docker exec 手动启动对应 daemon或者用环境变量控制 init 脚本。镜像里留着 openssh-clients 用来排错就够了没必要把 sshd 守护进程一起跑起来。目录设计确定之后组件之间的连接关系也要先画清楚HDFS 和 YARN 是底座Hive 的元数据和 SQL 引擎对接到 TezSpark 对接到同一个 HDFS 和同一个 Hive metastoreHue 作为 WebHDFS 和 HiveServer2 的入口。这也是多节点 Hadoop 集群搭建和 Spark 集群搭建共享同一份镜像的基础。3. 从 Dockerfile 构建基础镜像Hadoop、Hive、Tez、Spark、Hue 的安装顺序与关键配置3.1 基础镜像与依赖源、用户、目录一次做齐写 Dockerfile 时不要一上来就装 Hadoop。先把基础镜像、用户、数据目录和 JDK 准备好这部分决定了后面所有组件的文件权限。最小可复现的 Dockerfile 长这样FROM centos:7 # 安装 OpenJDK 8 与常用排错工具 RUN yum install -y java-1.8.0-openjdk-devel \ openssh-clients net-tools curl \ yum clean all ENV JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk # 创建统一运行用户uid/gid 固定为 1000 RUN groupadd --gid 1000 bigdata \ useradd --gid 1000 --uid 1000 -m bigdata # 创建程序、数据、日志目录并授权 RUN mkdir -p /opt/bigdata/{hadoop,hive,spark,tez,hue,data/{namenode,datanode},logs,init} \ chown -R bigdata:bigdata /opt/bigdata ENV HADOOP_HOME/opt/bigdata/hadoop \ HIVE_HOME/opt/bigdata/hive \ SPARK_HOME/opt/bigdata/spark \ PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin:$SPARK_HOME/bin USER bigdata WORKDIR /opt/bigdata几个参数值得说明一下。--gid 1000 --uid 1000是为了让容器里的 bigdata 用户和宿主机上常见第一个普通用户 uid 对齐挂载 volume 之后文件权限问题会少很多如果宿主机用户不是 1000后面单独 chown 即可。数据目录在镜像里先建好可以避免容器启动时以 root 自动创建目录导致 owner 变成 root。ENV PATH把 Hadoop、Hive、Spark 的 bin 目录都加进去进容器排查问题时不用每次手敲绝对路径。3.2 Hadoop 配置三项core-site、hdfs-site、yarn-site 的必调参数Hadoop 的配置散落在三个文件里镜像里最常见的问题是配置写得太长很多参数在单机和集群两种模式下互相矛盾。我一般只改三块核心配置其余保持默认。core-site.xml 关键项property namefs.defaultFS/name valuehdfs://namenode:9000/value /property property namehadoop.proxyuser.hue.hosts/name value*/value /property property namehadoop.proxyuser.hue.groups/name value*/value /propertyfs.defaultFS里的 namenode 是 compose 网络里的主机名不是 IP容器重启后 IP 变化不用改配置。proxyuser 两条是给 Hue 用的Hue 会以 hue 身份代理用户访问 HDFS 和 Hive没有这两条Hue 里打开文件浏览器会报 Forbidden 类错误。hdfs-site.xml 关键项property namedfs.replication/name value2/value /property property namedfs.namenode.name.dir/name value/opt/bigdata/data/namenode/value /property property namedfs.datanode.data.dir/name value/opt/bigdata/data/datanode/value /property property namedfs.permissions.enabled/name valuefalse/value /property一主两从的小集群我把副本设为 2预留一个节点做冗余如果只有单节点则设 1。dfs.permissions.enabledfalse适合开发沙箱让 Hive、Spark 写 HDFS 时不再被权限卡住生产环境不要照抄这个参数。yarn-site.xml 关键项property nameyarn.resourcemanager.hostname/name valuenamenode/value /property property nameyarn.scheduler.maximum-allocation-mb/name value4096/value /property property nameyarn.nodemanager.resource.memory-mb/name value4096/value /property property nameyarn.nodemanager.vmem-check-enabled/name valuefalse/value /propertyvmem-check-enabledfalse几乎是大数据容器环境的必改项。容器内物理内存有限虚拟内存的值很容易超过 NodeManager 默认阈值开着它时任务会被反复 kill表面上看起来像代码问题。yarn.scheduler.maximum-allocation-mb要大于后面 Tez 和 Spark 申请的内存否则任务申请 4G 容器直接会被调度器拒绝。3.3 Hive on Tez把执行引擎从 MapReduce 切掉的关键配置Hive 3.x 默认支持 Tez但不少镜像装上后跑 SQL 还是走 MapReduce慢得离谱。原因通常是 hive-site.xml 里没切引擎或者 Tez 包没有分发到 YARN。切引擎只需要一个参数property namehive.execution.engine/name valuetez/value /property property namehive.tez.container.size/name value1024/value /propertyTez 要在 YARN 上运行需要把 tez 压缩包放到 HDFS让 NodeManager 能拉取。常见做法是在初始化阶段执行hdfs dfs -mkdir -p /tez hdfs dfs -put /opt/bigdata/tez/tez.tar.gz /tez/tez.tar.gz然后让 Hive 引用这个路径property nametez.lib.uris/name value${fs.defaultFS}/tez/tez.tar.gz/value /propertyhive.tez.container.size决定每个 Tez task 的容器内存它必须小于 yarn.scheduler.maximum-allocation-mb。如果 Hive 跑 JOIN 经常 OOM优先把这个值调到 2048 或 3072同时调大 YARN 的调度上限而不是只加 mapreduce 相关的 map 内存。镜像跑在 8G 内存笔记本上时可以把hive.tez.container.size压到 512测试 SQL 足够调度也更从容。注意tez.lib.uris里引用${fs.defaultFS}时要确保 HDFS 已经启动否则后续任务会一直报文件系统不存在的错这个错误出现在 YARN 日志里时很容易被误判为网络问题。3.4 Spark on YARN 与 Hue让两个入口连到同一个集群Spark 在镜像里的角色是计算框架需要让它认识同一个 HDFS 和同一个 Hive metastore否则 Spark 里建的表 Hive 看不见Hue 里也看不见。spark-defaults.conf 里至少需要这几项spark.masteryarn spark.sql.catalogImplementationhive spark.sql.hive.metastore.version3.1.3 spark.sql.hive.metastore.jars.path/opt/bigdata/hive/lib/*.jar spark.yarn.jarshdfs://namenode:9000/spark-jars/*.jarspark.yarn.jars指向 HDFS 上的 jar 包目录能避免每次提交任务都把 Spark 依赖包重复上传。初始化阶段执行hdfs dfs -mkdir -p /spark-jars hdfs dfs -put /opt/bigdata/spark/jars/* /spark-jars/即可。Hue 的接入点是 HiveServer2hue.ini 里需要确认两处。第一处是[[hive]]下的连接地址[beeswax] hive_server_urlthrift://hiveserver2:10000这里必须指向 HiveServer2而不是 Hive Metastore 的 9083 端口。很多镜像里两个服务在同一容器中端口容易混淆。第二处是 Hue 自身的 secret key不生成的话浏览器打开页面会一直报 CSRF 错误用openssl rand -hex 24生成后写进 hue.ini 的secret_key即可。Hive 和 Spark 共用一个 metastore 之后还有一个实用习惯建表、改表的 DDL 尽量统一走 Hive CLI 执行Spark 专注做计算和写入避免两边对表名大小写、分隔符的默认处理不一致。这个习惯在我实际用下来比调任何参数都更能减少“表不见了”的幻觉。4. 集群编排与首次启动的常见问题避坑重启翻车、Tez 卡死、Hue 连不上 Hive镜像构建好之后下一步是把容器编排起来。第一次做编排不要贪多用五个角色就能跑通mysql 负责元数据库namenode 容器跑 NameNode 和 ResourceManagerdatanode 容器跑 DataNode 和 NodeManagerhiveserver2 容器跑 Metastore 和 HiveServer2Hue 单独一个容器。等这套跑顺了再逐步拆更细也不迟。compose 文件的最小骨架可以参照下面这样services: mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: bigdata MYSQL_DATABASE: hive namenode: image: bigdata/env:base environment: ROLE: namenode volumes: - namenode-data:/opt/bigdata/data/namenode datanode: image: bigdata/env:base environment: ROLE: datanode volumes: - datanode-data:/opt/bigdata/data/datanode hiveserver2: image: bigdata/env:base environment: ROLE: hiveserver2 hue: image: bigdata/env:base environment: ROLE: hue镜像相同而 role 不同启动脚本根据环境变量决定拉起哪些 daemon这是镜像环境里很常见的做法比给每个角色单独做镜像更省维护成本。首次启动前有两件事必须做HDFS 只格式化一次Hive 元数据库初始化一次否则 HiveServer2 会一直报先执行 schema 初始化的错。docker-compose up -d mysql docker-compose up -d namenode docker exec namenode bash -c hdfs namenode -format -force docker-compose up -d datanode hiveserver2 hue docker exec hiveserver2 bash -c schematool -dbType mysql -initSchema说一个我见过很多次的错误启动顺序先把所有容器 up 起来再进 namenode 格式化 HDFS结果 DataNode 已经带着旧 clusterID 注册上来了。后面不管怎么重启都在安全模式里打转。格式化和初始化要在对应角色首次启动之前完成这是这套流程里最需要记住的一条顺序约束。4.1 现象容器重启后 HDFS 停在安全模式读写超时第一次启动集群正常用 docker-compose restart 之后dfsadmin -report 显示 Safe mode is ON文件上传报 Cannot create fileName node is in safe mode。多数情况是反复执行 namenode -format 导致 clusterID 变了。格式化动作会生成新的 namespace ID 和 clusterIDDataNode 注册时携带的是旧 clusterIDNameNode 不认只能收块报告但拒绝离开安全模式。常见错误习惯是 DataNode 上有数据时再格式化一次 NameNode 来“重启干净”。开发环境里处理起来比较直接停掉所有容器删除挂载卷里的 namenode 和 datanode 目录重新格式化再启动。更稳的做法是把 format 写进 init 脚本检测 current/VERSION 文件存在就跳过避免误格式化docker-compose down docker volume rm bigdata_namenode bigdata_datanode docker-compose up -d mysql namenode docker exec namenode bash -c hdfs namenode -format -force如果 HDFS 里已经有不想丢的数据不要用这个方案。可以通过修改 DataNode 的 VERSION 文件把 clusterID 改成和 NameNode 一致再逐台滚动重启。基础镜像环境里数据丢了不可惜先把流程跑通再考虑数据保留。4.2 现象Hive on Tez 任务卡在 99%随后 Container 被 KILLHive 执行引擎已经切到 Tez跑 select count 或 join 时YARN UI 上任务进行到最后阶段然后某个 container 报 killed by the ResourceManager。最常见原因是虚拟内存检查误杀。容器中物理内存上限与操作系统过度提交的内存口径不一致NodeManager 默认的 vmem-check 会把虚拟内存也算进去Tez 的 AM 和 task 很容易超阈值。另一个原因是 tez.am.resource.memory.mb 大于 yarn.scheduler.maximum-allocation-mb申请直接被调度器驳回。解决方式是关掉虚拟内存检查并统一三段内存参数yarn.scheduler.maximum-allocation-mb、yarn.nodemanager.resource.memory-mb、hive.tez.container.size。常用组合是 4096 / 4096 / 1024如果 DataNode 容器内存只有 4G可以改成 2048 / 2048 / 512。改完重启 YARN 相关进程docker exec namenode bash -c yarn --daemon stop resourcemanager docker exec namenode bash -c yarn --daemon start resourcemanager docker exec datanode bash -c yarn --daemon stop nodemanager docker exec datanode bash -c yarn --daemon start nodemanager这类容器里跑 Tez 的内存问题本质和 Spark executor 内存配置一样不能只调一边。组件之间的内存共识比单点调大更重要先定总内存再往下分配能少踩很多莫名其妙的坑。4.3 现象Hue 登录成功却看不到任何 Hive 表Hue 页面能打开也能登录SQL 编辑器能输入但表列表是空的执行 show tables 要么提示连接失败要么一直空白。Hue 连接的不是 HiveServer2。hue.ini 默认示例常写 localhost:10000编排之后 hiveserver2 是独立服务名host 不匹配必然失败。另一个隐蔽问题是 HiveServer2 启动失败时Hue 自己不报错只会转圈或者返回空列表。先检查端口再验证 HiveServer2 本身docker exec hiveserver2 bash -c netstat -tlnp | grep 10000 docker exec hiveserver2 bash -c beeline -u jdbc:hive2://hiveserver2:10000/ -n bigdata如果 beeline 能进入问题就在 Hue 配置把 hue.ini 里 hive_server_url 改成 thrift://hiveserver2:10000 然后重启 Hue。如果 beeline 也进不去问题在 HiveServer2看它的日志比在 Hue 里瞎试有效得多。这个排查顺序我每次都能省下不少时间。4.4 现象Spark 写 Hive 分区表任务成功目标表却查不到数据Spark 里 df.write.insertInto 或 saveAsTable 执行成功没有任何报错但 Hive 里 select 不到新数据Hue 看到的数据也是旧的。Spark 默认使用内存 catalog写到了内存目录里Hive metastore 没有感知。更常见的是 spark.sql.catalogImplementation 没切到 hiveSpark 任务看到的是自己内置元数据数据落到了内部临时 warehouse和 Hive 的 warehouse 目录不一致。这个坑和 Flink sink Hive 表数据不入表在连接层面是同一类问题根子都在外部引擎没有正确对接到 Hive metastore。解决办法是确认 spark-defaults.conf 中spark.sql.catalogImplementationhive并把 metastore 地址指向同一个服务。如果镜像里已经配好spark.sql.hive.metastore.version3.1.3和spark.sql.hive.metastore.jars.path/opt/bigdata/hive/lib/*.jar那关键一步就是把 hive.metastore.uris 改成 thrift://hiveserver2:9083让 Spark 和 Hive 共享同一套元数据。验证是否连通可以跑一次简单写入spark.sql(create database if not exists test) spark.sql(select 1 as id).write.mode(overwrite).saveAsTable(test.ping) spark.sql(select * from test.ping).show()然后在 Hive 里再 select 一次同一张表。两侧都能查到说明元数据和 warehouse 完全打通。这个验证脚本我留在镜像的 init 目录里每次改完配置先跑一遍再继续。5. 镜像用起来之后的验证与维护技巧一条命令确认五组件状态5.1 用自检脚本替代逐个进程的肉眼检查每次重启环境我不会逐个容器看日志而是用一个脚本同时检查五个组件的端口和服务状态check_port() { docker exec $1 bash -c cat /dev/null /dev/tcp/$2/$3 2/dev/null \ echo $1:$3 OK || echo $1:$3 FAIL } check_port namenode namenode 8020 # HDFS check_port namenode namenode 8088 # YARN check_port hiveserver2 hiveserver2 9083 # Metastore check_port hiveserver2 hiveserver2 10000 # HiveServer2 check_port hue hue 8888 # Hue端口通过并不代表 HDFS 已退出安全模式所以脚本里最好再加一句docker exec namenode bash -c hdfs dfsadmin -safemode get输出 OFF 才算真正就绪。这个自检脚本放在宿主机上配合容器日志里的报错关键字基本能覆盖日常环境检查。5.2 从镜像环境走向 HA 时的一个习惯镜像稳定之后最常见的下一步是把这套结构和 ZooKeeper 整合成 HA 环境NameNode 双活、ResourceManager 双活加上 JournalNode。这时候不需要推翻镜像重写只要把 hdfs-site.xml 改成 nameservices 方式把 zkfc 启动脚本加进 init 目录即可。另一个高性价比的事是给 Hive 处理小文件在 hive-site.xml 里预设hive.merge.tezfilestrue或者定期跑合并任务比在业务侧反复调内存更管用。容器镜像环境给我的最大教训是把可变状态和不可变状态分开数据、元数据库、日志都放 volume系统程序全在镜像层每次改参数后重新构建镜像而不是进容器直接改环境才不会走上“手工作坊”的路。这个习惯坚持半年之后你会发现自己再也不会在凌晨三点为一个“改了配置但是容器重启后丢了”的问题失眠。希望帮到你。本文还有配套的精品资源点击获取