ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Docker一键搭建Hadoop/Spark/Hive/Tez/Hue大数据环境

Docker一键搭建Hadoop/Spark/Hive/Tez/Hue大数据环境 简介一套面向大数据基础环境搭建的 Docker 镜像组件工程集成 Hadoop、Spark、Hive、Tez、Hue 及 Kafka 等主流组件目标是帮助使用者通过脚本和配置快速完成集群环境的构建与初始化。适合计算机相关专业学生、毕业设计开发者以及需要搭建实验平台进行入门学习或项目演示的技术人员。压缩包内共 22 个文件以 shell 启动与初始化脚本、XML 组件配置为主同时包含 Dockerfile、属性配置、环境说明和 README 文档覆盖镜像构建、集群启动、MySQL 初始化、Kafka 服务拉起等环节整体包体仅 34KB是轻量级配置与脚本集合便于阅读和二次修改。资料目前已获得 141 人浏览学习在大数据入门与课程设计场景中具有参考价值。使用者可以从中获得完整的组件配置思路、可运行的启动脚本和配套说明参照 README 能理清 Hadoop、Hive、Spark 等组件的镜像构建和运行流程也便于在此基础上调整参数、增加组件用于毕业设计、课程作业或初期项目演示。1. 大数据基础镜像组件 pack为什么用 Docker 拉起 Hadoop/Spark/Hive/Tez/Hue做大数据课程设计或者毕设的同学大概率都有过这种体验为了一个 WordCount 去装三台虚拟机每台都要配 Java、调 SSH、改 hosts折腾两天还没把 HDFS 跑起来。这套 bitdata-hadoop-master 镜像组件就是把 Hadoop、Spark、Hive、Tez、Hue 甚至 Kafka 直接打包成 Docker 镜像配合 run-bdp.sh 一键启动本地浏览器里就能看到 YARN 页面、Spark 作业和 Hive 查询结果。它适合三种人准备毕设答辩的在校生、想在公司内网快速拉一套开发环境验证代码的工程师、以及刚入门想看看 Hadoop 生态各个组件到底怎么协作的新手。接下来我从工程结构、参数配置、启动验证和踩坑四个角度把这个镜像组件拆开讲透。2. bitdata-hadoop-master 工程结构build.sh、run-bdp.sh、Dockerfile 与五类启动脚本的分工拿到压缩包以后别急着 docker build先看清目录结构。这套资源的设计思路是“镜像构建 容器启动”两层分离Dockerfile 负责把 Hadoop、Spark、Hive、Tez、Hue 装进镜像而 run-bdp.sh、entrypoint.sh、hadoop_init.sh、hive_start.sh、mysql_init.sh、start_kafka.sh 这些脚本负责在容器启动时把服务按顺序拉起来。这样你在开发机上改配置不需要重新打包镜像改完 conf 目录里对应 XML 重启容器就行。2.1 压缩包里的五个目录conf、hadoop、spark、hive、tez、hue 各管什么解压后能看到几个核心目录hadoop、spark、hive、tez、hue 这五个是运行时组件目录conf 目录下面放的是各组件的配置文件。常见做法是把编译好的二进制包直接放进目录然后在 Dockerfile 里通过 COPY 命令拷进镜像再做环境变量和 PATH 的声明。实际拆这个包的时候我建议你先看 conf 下面有哪些文件。一般至少会有 core-site.xml、hdfs-site.xml、yarn-site.xml、hive-site.xml、spark-defaults.conf、tez-site.xml 这几类。它们之间的关系是这样的Hadoop 的 core-site.xml 决定 HDFS 的 NameNode 地址hdfs-site.xml 决定数据块副本数和 NameNode 的 Web 端口yarn-site.xml 决定 ResourceManager 端口和调度器配置。Hive 的 hive-site.xml 则指向元数据库连接方式和执行引擎Tez 的配置则决定 DAG 任务在 YARN 上怎么跑。这些 XML 是整套环境的坐标系后面所有问题排查基本都落在这几个文件里。还有两个细节值得注意第一hue 目录下的配置文件需要维护一堆服务地址包括 HDFS 的 NameNode、ResourceManager、HiveServer2、ZooKeeper 等端口必须和前面 Hadoop、Hive 实际监听的端口保持一致第二mysql_init.sh 的存在说明元数据大概率依赖 MySQL 而非 Hive 默认的 Derby这点在后面启动顺序里会专门讲。2.2 build.sh Dockerfile构建镜像的常规三步build.sh 不复杂本质上就是对 docker build 的封装。我一般会先打开这个脚本看它指定的镜像名称和 tag因为后面 run-bdp.sh 启动容器时会引用同一个镜像名两处不一致就会导致“docker run 找不到镜像”。#!/bin/bash # 构建 bitdata-hadoop 基础镜像 # -t 指定镜像名和版本号通常与 run-bdp.sh 内的 IMAGE_NAME 保持一致 docker build -t bitdata-hadoop:latest .这段脚本的逻辑很直接进入工程根目录读取 Dockerfile然后把当前目录作为构建上下文打包发送给 Docker daemon。要注意的是Dockerfile 里如果写了COPY hadoop /opt/hadoop这类指令它的来源路径是相对于“构建上下文”的也就是这个 build.sh 所在的目录。所以解压后不要把 build.sh 单独拿出来保持目录结构完整才能构建成功。Dockerfile 的常规写法一般分四段FROM 指定基础镜像和 Java 版本COPY 把 hadoop、spark、hive、tez、hue 目录拷进 /optRUN 设置环境变量并创建启动脚本的执行权限EXPOSE 声明需要映射的端口常见的有 8020、8088、9870、9083、10000 这些。最后一个动作是设置 ENTRYPOINT通常是执行 entrypoint.sh让容器启动时自动拉起服务。如果你只是做开发验证别去动基础镜像的版本因为整套组件的编译版本是互相搭配好的盲目升级 Spark 版本很可能把 Tez 和 Hive 的兼容性打破。2.3 entrypoint.sh 与初始化脚本从 SSH 到 MySQL 到 Hive 的拉起顺序entrypoint.sh 是整个容器的总调度。因为 Docker 容器启动时只会执行一个主进程所以这个脚本要做的事就是把所有后台服务都拉起来最后用tail -f /dev/null让容器保持不退出的状态。实际内容可能不完全一致但逻辑通常是下面这种结构#!/bin/bash # 容器入口脚本按依赖顺序拉起所有大数据组件 echo [entrypoint] start ssh /etc/init.d/ssh start echo [entrypoint] init hadoop hdfs/yarn bash /scripts/hadoop_init.sh echo [entrypoint] init mysql and hive schema bash /scripts/mysql_init.sh echo [entrypoint] start hive metastore and hiveserver2 bash /scripts/hive_start.sh echo [entrypoint] start kafka bash /scripts/start_kafka.sh # 保持容器前台运行防止 docker run 退出 tail -f /dev/null这里有一个容易被忽略的订单MySQL 初始化必须在 Hive 启动之前。原因是 Hive 的元数据需要先有数据库和用户如果 hive_start.sh 先跑它去连接 MySQL 时库还不存在Hive Metastore 就会反复报错。hadoop_init.sh 里通常会执行hdfs namenode -format和启动 HDFS 各进程这一步也会有坑后面避坑章节单独说。wait_to_die.sh 这个名字很直白它和tail -f /dev/null的作用类似都是为了在 Docker 环境下让容器进程不退出。有些镜像里会把服务进程放到前台执行例如直接运行supervisord或者hue supervisor不需要 wait_to_die.sh。但既然包里带着这个脚本说明原始镜像的设计逻辑是把各服务全部 daemon 化最后用一个等待进程把容器撑住。3. 镜像内 Hadoop / Spark / Hive 的配置思路伪分布式参数、Tez 执行引擎与元数据初始化这套镜像组件本质上是一个“单机伪分布式 YARN 调度”的环境。所谓伪分布式是指 HDFS 的 NameNode 和 DataNode 跑在同一台机器上YARN 的 ResourceManager 和 NodeManager 也都在本地但数据的读写、任务的调度流程和真实集群完全一致。这么做的好处是既能跑通完整链路又不需要多台机器互联对毕设和本地开发来说性价比最高。真正要理解这套配置得从三个文件入手core-site.xml、yarn-site.xml 和 hive-site.xml。3.1 HDFS 配置fs.defaultFS、副本与端口core-site.xml 里最核心的是 fs.defaultFS它决定了 HDFS 的访问入口。在伪分布式环境下这个值一般是hdfs://localhost:9000或者hdfs://容器主机名:9000。如果容器内部使用 hostname 访问那 hosts 文件里必须有对应的 IP 映射如果直接用 localhost则不需要额外配置。configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/data/hadoop/tmp/value /property /configuration第二行的 hadoop.tmp.dir 很容易被忽略但它决定了 NameNode 的元数据存放位置。很多容器重启后 HDFS 数据丢失就是因为这个目录落在容器可写层没有挂载到宿主机磁盘。后文避坑部分我会专门提醒。hdfs-site.xml 里需要关心的是副本数dfs.replication伪分布式环境下只有一台 DataNode所以副本数必须设为 1否则文件写入时会因为找不到第二个 DataNode 一直等待。另外dfs.namenode.http-address默认是 9870这是你浏览器访问 HDFS Web UI 的端口端口冲突时优先检查这里。3.2 Spark 在容器里的内存参数如何给Spark 在容器里最头疼的问题不是功能而是内存分配。我们通常在 Docker 启动时通过-m参数限制容器可用内存如果 Spark 的 executor 申请的内存超过这个限制NodeManager 会直接杀掉容器表现为作业刚提交就失败。更隐蔽的是 YARN 本身也有一个内存判断NodeManager 可用内存必须大于所有已申请 container 内存的总和。# spark-defaults.conf 中常见的容器内参数配置 spark.master yarn spark.driver.memory 1g spark.executor.memory 1g spark.executor.cores 1 spark.yarn.executor.memoryOverhead 512m spark.sql.shuffle.partitions 4参数说明spark.master 设为 yarn 表示让 YARN 来管理 Spark 的 Executor 生命周期executor.memory 是每个执行进程的堆内存memoryOverhead 是堆外内存用于 JVM 本身、网络缓冲等在容器里需要和堆内存一起计入容器总内存。举个例子容器限制为 4gNameNode 和 DataNode 各占 1g剩下给 Spark 的空间最多也就 2g 左右这时候 executor 内存开到 2g 加 overhead 512m 就是安全的。spark.sql.shuffle.partitions 在数据量不大时可以调小一点否则每次 shuffle 都生成大量小任务本地跑起来反而慢。3.3 Hive 用 Tez 作为执行引擎时的参数Hive 默认执行引擎是 MapReduce但 MapReduce 在交互式查询场景下启动开销大所以很多环境会切换到 Tez。Tez 把 Map 和 Reduce 阶段整合成 DAG 有向无环图中间结果不落盘对小数据量查询的提升非常明显。在 hive-site.xml 里设置property namehive.execution.engine/name valuetez/value /property property namehive.tez.container.size/name value1024/value /propertyhive.tez.container.size 表示每个 Tez 任务申请的容器内存单位是 MB。这个值必须小于 YARN 单个 NodeManager 的可用内存同时也要和 Spark 的 executor 内存错开避免两个引擎同时申请资源时把容器挤爆。Tez 的 DAG 执行图会直接显示在 YARN 的 Application 页面上你可以通过这个图来判断 Hive 任务是否真的走了 Tez 引擎。3.4 mysql_init.sh 与 hive_start.sh元数据初始化顺序这套组件里Hive 的元数据存储在 MySQL 里所以 mysql_init.sh 承担的任务是启动 MySQL 服务、创建 Hive 元数据库、创建用户并授权。hive_start.sh 则负责启动 Hive Metastore 和 HiveServer2。注意Metastore 和 HiveServer2 是两个独立进程前者提供表结构信息给客户端后者接受 JDBC/Beeline 连接。如果只启动 MetastoreBeeline 无法连接如果只启动 HiveServer2则建表查表时连不上 Metastore 会直接报错。4. 一键启动后怎么验证环境hadoop fs、spark-submit、beeline、Hue 四步验收环境拉起后不要急着写业务代码先用四个步骤从底层到上层验收一遍。顺序是先确认容器进程状态再验证 HDFS 文件读写然后用 Spark 提交一个任务最后通过 Hive 查询和 Hue 页面确认服务之间的连通性。下面四个小节就是完整的验收流程。4.1 第一步run-bdp.sh 启动脚本run-bdp.sh 一般会把 docker run 的参数固化好包括端口映射、容器名称和挂载目录。它做的事情是检查本地是否存在 bitdata-hadoop 镜像不存在则提示先执行 build.sh然后根据预设参数启动容器。实际执行逻辑类似这样#!/bin/bash # 启动大数据基础镜像容器 # -d 后台运行--name 固定容器名便于 docker exec # -p 映射宿主机端口到容器端口顺序为 宿主机:容器 docker run -d \ --name bitdata-hadoop \ -p 8088:8088 \ -p 9870:9870 \ -p 9083:9083 \ -p 10000:10000 \ -p 8000:8000 \ -v /data/hadoop:/data/hadoop \ bitdata-hadoop:latest端口说明8088 是 YARN ResourceManager 的 Web UI9870 是 HDFS NameNode 的 Web UI9083 是 Hive Metastore 的 Thrift 端口10000 是 HiveServer2 的 JDBC 端口8000 是 Hue 的 Web UI 端口。最后有一个-v /data/hadoop:/data/hadoop挂载把容器的 HDFS 数据目录挂到宿主机这个参数非常重要没有它的话容器每次删除重建都会丢数据。启动后立刻查看日志docker logs -f bitdata-hadoop。正常情况下能看到“start ssh”“init hadoop”“start hive”这些步骤的输出最后停在 tail 等待状态。接着用docker ps确认容器处于 Up 状态。4.2 第二步HDFS 上传与 Spark WordCount进容器执行docker exec -it bitdata-hadoop bash先看 HDFS 是否就绪。# 进入容器后验证 HDFS 状态 hdfs dfsadmin -report # 创建测试目录并上传一个本地文件 hdfs dfs -mkdir -p /input hdfs dfs -put /opt/test.txt /input/test.txt hdfs dfs -cat /input/test.txt如果dfsadmin -report能看到 Live datanode 为 1说明 HDFS 正常。这时候再用 spark-submit 提交一个简单统计任务验证 YARN 和 Spark 的配合# 提交 Spark 自带示例作业统计圆周率 spark-submit \ --master yarn \ --deploy-mode client \ --class org.apache.spark.examples.SparkPi \ /opt/spark/examples/jars/spark-examples_2.12-*.jar 10如果作业最终输出 Pi 的近似值说明 Spark 能正常申请 YARN 资源并执行计算。YARN 页面上应该能看到一个运行完成的 Spark application点进去可以看到 Executor 的日志。4.3 第三步Hive beeline 建表查询Hive 的验证不能只看 CLI 能不能进要真正用 beeline 走一遍 JDBC 连接# 通过 beeline 连接 HiveServer2 /opt/hive/bin/beeline -u jdbc:hive2://localhost:10000 -n root # 在 beeline 中执行建表和查询 CREATE TABLE test_line (id INT, name STRING); INSERT INTO test_line VALUES (1, hadoop), (2, spark); SELECT * FROM test_line;能执行成功说明 HiveServer2、Metastore、MySQL 三层全部打通。这里需要注意如果 INSERT 执行时发现 MR 或 Tez 任务启动耗时很长属于正常现象因为 DAG 引擎首次启动需要申请资源、加载 jar 包。可以考虑在查询前加一句set hive.execution.enginetez;验证 Tez 是否被正确加载。4.4 第四步Hue UI 看作业和端口浏览器分别打开http://localhost:9870看 HDFS 文件目录http://localhost:8088看 YARN 应用列表http://localhost:8000进 Hue 登录页。Hue 默认账号通常是 admin密码在 README.md 或者 hue.ini 里有说明。进入 Hue 后能看到左侧的 HDFS 文件浏览和 Hive 查询入口这里如果“无法连接到 HiveServer2”需要回看第 5 章的排查点。Hue 这个组件的主要价值是把多个组件的入口收纳到一个页面里对课程设计答辩时做界面演示非常有用。5. 避坑指南从 NameNode 到 Hue 的五类常见问题这套镜像组件因为是打包好的跑通不难但改配置或者重启环境时很容易触发几个经典问题。下面按“现象 → 原因 → 解决”的结构记录我实际拆包过程中遇到的五类坑。5.1 Hive 启动报 Database lock现象容器重启后执行 hive_start.shMetastore 进程起不来日志里出现 “Cannot create directory ... Database/Table lock” 或 “Derby” 相关字样。原因如果 hive-site.xml 里没有把元数据库指向 MySQLHive 默认使用 Derby 内嵌数据库它只允许单进程访问上次进程没被正常关掉时Derby 会留下锁文件。解决先确认 mysql_init.sh 是否真正执行成功再查看 hive-site.xml 中javax.jdo.option.ConnectionURL的值确保是 mysql 协议而不是 derby。如果确认是 Derby 残留锁删除 Derby 的 metastore_db 目录后重启。5.2 Spark 作业在 YARN 一直 ACCEPTED现象spark-submit 提交后YARN 页面显示 Application 一直处于 ACCEPTED 状态既不运行也不失败。原因NodeManager 所在容器内存不足或 YARN 可用内存计算有偏差Spark 申请的资源大于 NodeManager 能提供的资源ResourceManager 会一直等待节点释放内存。解决把 yarn-site.xml 里yarn.nodemanager.resource.memory-mb调低比如从 8g 调到 3g同时把yarn.scheduler.maximum-allocation-mb也改小保证 Spark executor 申请的值在范围内。另一个连带问题是虚拟内存容器里如果发现报 “Virtual memory exceeded” 错误把yarn.nodemanager.vmem-check-enabled设为 false。5.3 Hue 连不上 HiveServer2现象Hue 页面能打开点击 Hive 查询时提示无法连接 HiveServer2。原因HiveServer2 没有起来或者 hue.ini 里配置的 hive_server_host 端口不对。常见的情况是 entrypoint.sh 中途某个脚本失败后面的 hive_start.sh 根本没执行。解决先单独执行bash /scripts/hive_start.sh并观察日志然后用netstat -tlnp | grep 10000确认端口在监听最后打开 hue/conf/hue.ini检查[[[hive]]]段里的server_host和server_port是否为 localhost 和 10000。Hue 对 HiveServer2 状态判断比较严格Metastore 起来但 HiveServer2 没起来也会报这个错。5.4 容器重启后 HDFS 数据丢失现象docker stop 再 docker start 后/input 目录和已上传的文件全部消失。原因HDFS 的 nameservice 和 datanode 数据存储在临时目录中例如hadoop.tmp.dir指向的路径没挂载到宿主机容器一旦被删除重建数据随镜像层丢失。解决在 run-bdp.sh 中构造-v /data/hadoop:/data/hadoop这样的挂载参数并把 core-site.xml 的hadoop.tmp.dir指到该目录。另外一个常见副产物是 namenode 格式化问题如果容器重建后直接hdfs namenode -format而 DataNode 上残留旧数据会出现 “There is a mismatch between the name and the datanode” 的错误处理办法是把 HDFS 数据目录整个清掉重新格式化。5.5 Hive 用 Tez 跑得慢小文件参数现象同样是 SELECT 语句Hive 走 Tez 引擎时启动慢、Map 任务数量几千个整个任务在 DAG 阶段卡很久。原因HDFS 上的小文件太多每个文件都会生成一个 Map 任务而 Tez 启动每个任务都有固定开销小文件越多效率越低。解决一方面是输入侧合并设置mapreduce.input.fileinputformat.split.maxsize和hive.hadoop.supports.splittable.combineinputformat另一方面是输出侧合并提交前使用set hive.merge.mapfilestrue; set hive.merge.size.per.task128000000;让小文件合并成大块。更根本的做法是在数据写入时用DISTRIBUTE BY rand()控制 reducer 文件数。6. 进阶技巧Tez 引擎下验证一条 ETL 链路并合并小文件环境搭好以后最有价值的动作是用 Tez 引擎真实跑一条 ETL 链路确认你改过的参数确实生效。下面这段 Hive SQL 是我平时用来验证环境的“试金石”它把一段文本日志按类型统计后写入目标表同时通过 DISTRIBUTE BY 控制输出文件数量。-- 设置 Tez 引擎与会话参数 set hive.execution.enginetez; set hive.merge.mapfilestrue; set hive.merge.size.per.task134217728; -- 创建一张原始表并写入测试数据 CREATE TABLE IF NOT EXISTS ods_log (line STRING); INSERT INTO ods_log VALUES (INFO: start job), (WARN: retry once), (ERROR: connection lost), (INFO: job finished); -- ETL 统计逻辑输出合并为少量文件 CREATE TABLE IF NOT EXISTS dws_log_type AS SELECT split(line, :)[0] AS log_type, count(*) AS cnt FROM ods_log DISTRIBUTE BY log_type;执行完之后用下面这句检查中间结果的分区数与文件数DESCRIBE FORMATTED dws_log_type;你会在输出里看到 Num Buckets、Location 这些信息。再去hdfs dfs -ls /user/hive/warehouse/dws_log_type确认文件数量。如果设置生效目录下应该只有少量几个文件而不是一大把零碎小文件。这套验证方式能一次性检验三件事Tez 引擎是否启用、DISTRIBUTE BY 是否控制住了文件数量、HiveServer2 到 HDFS 的写入链路是否正常。从那以后我每次搭完或者改完大数据环境都会拿这条 ETL 语句走一遍不跑通就不急着部署业务代码。这个习惯帮我筛掉了至少一半的 YARN 内存和 Hive 端口隐患你可以直接把它加进自己的验收清单。希望帮到你。本文还有配套的精品资源点击获取
返回列表