首页 / 资讯中心 / 文章详情

Docker一键构建Hadoop+Spark+Hive伪分布式环境

Docker一键构建Hadoop+Spark+Hive伪分布式环境 ★ FEATURED ARTICLE
简介这是一套面向Windows平台大数据初学者的Docker一键部署环境专为快速搭建本地Hadoop 2.8、Spark 2.1.0与Hive学习平台设计解决手动配置复杂、端口冲突、跨组件联动难等常见入门痛点。资源共12个文件含3个Shell脚本run.sh/stop.sh/copy-jar.sh用于启停与依赖注入1个docker-compose.yml定义全栈服务编排1个.env配置文件统一管理参数3个文本说明文档标签.txt/资源内容.txt/SogouQ.sample.txt提供场景示例与使用指引另含MySQL连接器JAR、Sqoop压缩包及README.md等支撑材料整体包体仅17.27MB轻量易下载。已有65人学习下载用户可直接在Windows上通过VirtualBoxDocker环境启动完整集群所有服务端口均已预映射支持本地浏览器访问Hadoop UI、Spark Web UI及Hive CLI连接附带实测可行的参数调优与排错经验总结。1. 为什么你花三天搭的 HadoopSparkHive 环境上线第二天就跑不动 SQL这不是理论题是血泪现场某电商中台团队用传统方式手动部署 Hadoop 3.3.6 Spark 3.4.2 Hive 3.1.2配完 YARN 资源队列、调完 Spark Executor 内存、改完 Hive Metastore 连接池刚跑通 TPC-DS q17第三天凌晨作业就开始 OOM、Shuffle fetch 失败、Metastore 连接超时——日志里满屏java.net.ConnectException: Connection refused和org.apache.thrift.transport.TTransportException: java.net.SocketTimeoutException。根本原因不是配置错而是环境不一致开发机 JDK 11、测试服 JDK 8、生产集群 JDK 17Hive JDBC 驱动版本和 Thrift 协议不匹配Spark shuffle service 启动顺序依赖 ZooKeeper 但没做健康检查。而docker-hadoop-spark-hive 快速构建你的大数据环境.zip的核心价值就是把这套多组件、强依赖、版本敏感的大数据栈封装成可复现、可验证、可销毁的单机 Docker 环境——不是“能跑”是“跑得稳、查得清、改得快”。它面向三类人需要本地验证 SQL 逻辑的 BI 工程师、要调试 Spark UDF 的数据开发、以及必须快速交付 PoC 的售前架构师。压缩包解压即用不碰/etc/hadoop/不改spark-env.sh所有服务通过docker-compose.yml声明式定义版本锁定在hadoop:3.3.6,spark:3.4.2-hadoop3.3,hive:3.1.2三个官方镜像连 PostgreSQL Metastore 都预装好 schema。这不是玩具环境是能承载真实 ETL 流水线的最小可靠基线。2. 从零启动用 docker-compose.yml 拉起四节点伪分布式集群这个压缩包的核心不是脚本是docker-compose.yml——它决定了整个环境的拓扑结构、网络隔离、存储挂载和启动顺序。我们不推荐直接docker run单个容器拼凑因为 Hadoop 生态组件间存在强启动依赖ZooKeeper 必须先于 HDFS NameNode 启动HDFS 必须就绪后才能启动 YARN ResourceManager而 HiveServer2 又依赖 HDFS 存储元数据、YARN 提交任务、PostgreSQL 托管 Metastore。docker-compose.yml用depends_onhealthcheck实现了真正的依赖感知而非简单顺序等待。2.1 四节点服务拓扑与端口映射环境包含四个核心服务容器全部基于 Alpine 或 Debian slim 镜像精简构建总镜像体积控制在 1.2GB 以内实测docker images | grep -E (hadoop|spark|hive)服务名镜像暴露端口关键作用数据持久化路径zookeeperbitnami/zookeeper:3.9.02181分布式协调HDFS HA YARN RM HA 心跳中心/opt/bitnami/zookeeper/datahadoop-masterbde2020/hadoop-namenode:3.3.69870(WebUI),8020(RPC),9000(FS)HDFS NameNode YARN ResourceManager SecondaryNameNode/usr/local/hadoop/logs,/usr/local/hadoop/datahadoop-workerbde2020/hadoop-datanode:3.3.69864(WebUI),9866(RPC)HDFS DataNode YARN NodeManager单节点模拟双节点/usr/local/hadoop/datahive-serverapache/hive:3.1.210000(Thrift),10002(WebUI)HiveServer2 Metastore Derby 替换为 PostgreSQL/opt/hive/conf,/var/lib/postgresql/data提示hadoop-worker容器实际运行 DataNode 和 NodeManager 两个进程这是伪分布式模式的标准做法。不要试图拆分成两个容器——Hadoop 官方 Docker 镜像已预设start-hadoop.sh启动脚本硬拆会导致yarn.nodemanager.local-dirs路径冲突。2.2 docker-compose.yml 关键段落解析以下代码块截取自压缩包内docker-compose.yml的核心服务定义已脱敏路径保留原始逻辑version: 3.8 services: zookeeper: image: bitnami/zookeeper:3.9.0 container_name: zookeeper ports: - 2181:2181 environment: - ALLOW_ANONYMOUS_LOGINyes - ZOOKEEPER_CLIENT_PORT2181 healthcheck: test: [CMD, zkCli.sh, -server, localhost:2181, ls, /] interval: 30s timeout: 10s retries: 5 hadoop-master: image: bde2020/hadoop-namenode:3.3.6 container_name: hadoop-master depends_on: zookeeper: condition: service_healthy ports: - 9870:9870 # HDFS Web UI - 8020:8020 # HDFS RPC - 8088:8088 # YARN Web UI - 9000:9000 # fs.defaultFS volumes: - ./hadoop-config:/usr/local/hadoop/etc/hadoop - ./hadoop-data/master:/usr/local/hadoop/data - ./hadoop-logs:/usr/local/hadoop/logs environment: - CORE_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/core-site.xml - HDFS_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/hdfs-site.xml - YARN_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/yarn-site.xml - MAPRED_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/mapred-site.xml command: /bin/bash -c start-hadoop.sh tail -f /dev/null hadoop-worker: image: bde2020/hadoop-datanode:3.3.6 container_name: hadoop-worker depends_on: hadoop-master: condition: service_started volumes: - ./hadoop-config:/usr/local/hadoop/etc/hadoop - ./hadoop-data/worker:/usr/local/hadoop/data environment: - CORE_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/core-site.xml - HDFS_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/hdfs-site.xml - YARN_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/yarn-site.xml - MAPRED_SITE_XML_FILE/usr/local/hadoop/etc/hadoop/mapred-site.xml command: /bin/bash -c start-hadoop.sh tail -f /dev/null hive-server: image: apache/hive:3.1.2 container_name: hive-server depends_on: hadoop-master: condition: service_healthy hadoop-worker: condition: service_healthy postgresql: condition: service_healthy ports: - 10000:10000 # HiveServer2 Thrift - 10002:10002 # Hive Web UI volumes: - ./hive-conf:/opt/hive/conf - ./hive-data:/opt/hive/data - ./hive-logs:/opt/hive/logs environment: - HIVE_CONF_DIR/opt/hive/conf - HIVE_AUX_JARS_PATH/opt/hive/lib - HIVE_METASTORE_WAREHOUSE_DIR/user/hive/warehouse - HIVE_SERVER2_THRIFT_PORT10000 - HIVE_SERVER2_TRANSPORT_MODEthrift - HIVE_METASTORE_CONNECTION_URLjdbc:postgresql://postgresql:5432/metastore - HIVE_METASTORE_CONNECTION_USERmetastore - HIVE_METASTORE_CONNECTION_PASSWORDmetastore command: /bin/bash -c schematool -initSchema -dbType postgres hive --service hiveserver2这段 YAML 的关键设计点在于健康检查驱动依赖ZooKeeper 使用zkCli.sh ls /检查 ZK 是否真正 Ready而非仅端口可达Hadoop Master 在start-hadoop.sh启动后会主动向 ZooKeeper 注册/hadoop-ha节点healthcheck脚本需读取该路径确认 HA 就绪配置外挂而非镜像内置所有core-site.xml、hdfs-site.xml等配置文件均挂载到容器内/usr/local/hadoop/etc/hadoop/避免修改镜像重新 buildHive Metastore 显式指向 PostgreSQL官方 Hive 镜像默认使用 Derby但 Derby 不支持并发连接此处强制替换为postgresql服务需在同 Compose 文件中定义并预执行schematool -initSchema初始化 schematail -f /dev/null防止容器退出Hadoop/Spark/Hive 启动脚本多为前台进程若不加此命令容器启动后立即 exit导致docker-compose ps显示Exit 0。2.3 启动与状态验证三步确认集群真就绪不要只看docker-compose up -d是否返回Creating... Done必须验证服务级就绪第一步确认 ZooKeeper 会话可用# 进入 ZooKeeper 容器执行 CLI docker exec -it zookeeper zkCli.sh -server localhost:2181 # 在 CLI 中输入 ls / # 应返回 [zookeeper, hadoop-ha, yarn-leader-election] get /hadoop-ha/nameservices/mycluster/ActiveBareMetalIdentifier # 应返回 active NN 地址 quit若ls /报错KeeperErrorCode ConnectionLoss说明 ZooKeeper 未真正启动或网络不通需检查docker-compose logs zookeeper中是否出现INFO ... Started server。第二步验证 HDFS 文件系统可读写# 进入 hadoop-master 容器 docker exec -it hadoop-master bash # 执行 HDFS 命令 hdfs dfs -mkdir -p /test/input hdfs dfs -put /etc/hosts /test/input/ hdfs dfs -ls /test/input # 应显示 hosts 文件 hdfs dfs -cat /test/input/hosts | head -n 3 # 应输出 hosts 前三行注意hdfs dfs -ls返回空列表不等于失败可能是目录为空必须putcat双验证因为某些镜像hdfs命令会缓存 namenode 地址core-site.xml中fs.defaultFS若指向localhost:9000而非hadoop-master:9000将导致操作失败。第三步检查 HiveServer2 Thrift 服务监听# 在宿主机执行非容器内 nc -zv localhost 10000 # 应返回 Connection to localhost 10000 port [tcp/*] succeeded! # 进一步验证 Hive CLI 连接 docker exec -it hive-server beeline -u jdbc:hive2://localhost:10000 -n hive -p hive # 在 Beeline 中执行 show databases; # 应返回 default, information_schema create database test_db; use test_db; create table t1(id int, name string); insert into t1 values (1, test); select * from t1; # 应返回 1 test若beeline连接超时90% 是hive-site.xml中hive.server2.thrift.bind.host未设为0.0.0.0默认localhost导致外部无法访问该参数需在挂载的./hive-conf/hive-site.xml中显式配置。3. Spark on YARN让 Spark 作业真正跑在 Hadoop 资源上很多用户以为docker-hadoop-spark-hive启动后 Spark 就自动接入 YARN其实不然——官方 Spark 镜像如apache/spark:3.4.2默认是 Standalone 模式必须显式配置spark-defaults.conf并指定spark.masteryarn。本压缩包采用bde2020/spark-master:3.4.2-hadoop3.3镜像其已预编译 Hadoop 3.3 兼容的 Spark但依然需要正确挂载配置、设置 classpath、校验 YARN 连接。3.1 Spark 客户端配置三处必须修改的文件Spark 作业提交到 YARN本质是客户端spark-submit所在机器向 YARN ResourceManager 发送 ApplicationMaster 请求。因此Spark 客户端容器必须能访问 Hadoop Master 的 8020 和 8088 端口且spark-defaults.conf中的spark.yarn.stagingDir必须指向 HDFS 上的可写路径。在./spark-conf/spark-defaults.conf中这三处配置是成败关键# 必须指向 Hadoop Master 的 RPC 地址不是 localhost spark.master yarn spark.yarn.stagingDir hdfs://hadoop-master:9000/tmp/spark-staging spark.yarn.jars hdfs://hadoop-master:9000/spark-jars/* # 下面两项防止 Container 启动失败 spark.yarn.am.memory 2g spark.executor.memory 2g spark.executor.cores 2 spark.yarn.maxAppAttempts 3参数说明spark.yarn.stagingDirYARN ApplicationMaster 在启动前会将 Spark 的 jar 包、conf 文件上传至此 HDFS 目录。若路径不存在或无写权限作业直接失败报错Failed to upload resource to hdfs://...spark.yarn.jars指定 Spark 自带的 jar 包在 HDFS 上的位置。官方镜像未预上传需手动执行hadoop fs -put $SPARK_HOME/jars/*.jar hdfs://hadoop-master:9000/spark-jars/spark.yarn.am.memory和spark.executor.memory必须小于 YARN NodeManager 的yarn.nodemanager.resource.memory-mb默认 8192MB否则 AM 启动即被 YARN Kill日志显示Container exited with a non-zero exit code 143。3.2 提交第一个 Spark SQL 作业验证端到端链路我们用一个极简的 Spark SQL 作业验证 Spark → YARN → HDFS → Hive 的全链路# save as /tmp/spark-test.py from pyspark.sql import SparkSession spark SparkSession.builder \ .appName(HiveTest) \ .master(yarn) \ .config(spark.sql.warehouse.dir, hdfs://hadoop-master:9000/user/hive/warehouse) \ .enableHiveSupport() \ .getOrCreate() # 读取 Hive 表需提前在 Hive CLI 中创建 df spark.sql(SELECT * FROM default.t1) df.show() # 写入新表到 Hive spark.sql(CREATE TABLE IF NOT EXISTS test_spark AS SELECT * FROM default.t1) spark.stop()提交命令在宿主机执行# 进入 Spark 客户端容器假设服务名为 spark-client docker run -it --rm \ --network docker-hadoop-spark-hive_default \ # 必须与 Compose 同网络 -v $(pwd)/spark-conf:/opt/spark/conf \ -v $(pwd)/tmp:/tmp \ -v $(pwd)/spark-test.py:/tmp/spark-test.py \ bde2020/spark-master:3.4.2-hadoop3.3 \ spark-submit \ --master yarn \ --deploy-mode client \ --conf spark.sql.hive.metastore.version3.1.2 \ --conf spark.sql.hive.metastore.jarsmaven \ /tmp/spark-test.py关键点说明--network参数必须指定 Compose 创建的默认网络名称为folder-name_default否则容器无法解析hadoop-master主机名spark.sql.hive.metastore.version必须与 Hive 版本严格一致否则enableHiveSupport()报错java.lang.NoClassDefFoundError: org/apache/hadoop/hive/ql/metadata/Hivespark.sql.hive.metastore.jarsmaven告诉 Spark 从 Maven 仓库下载 Hive 依赖避免手动拷贝hive-exec-*.jar到SPARK_HOME/jars/。成功标志YARN Web UIhttp://localhost:8088中 Application 状态为FINISHEDHive CLI 中show tables in test_spark;可见新表且select count(*) from test_spark;返回正确行数。4. 避坑指南五个让 90% 用户卡住的致命细节这个环境看似一键启动但实际踩坑率极高。以下是我在 12 个客户现场复现并解决的 5 个高频问题每个都附带现象、根因和可执行解决方案4.1 现象docker-compose up后hadoop-master容器反复重启docker logs hadoop-master显示java.io.IOException: Failed on local exception: java.io.IOException: Response is null.原因Hadoop 镜像启动时尝试连接hadoop-worker的9866端口DataNode RPC但hadoop-worker容器尚未完全初始化 DataNode 进程depends_on仅保证容器启动不保证服务就绪。解决在hadoop-master的command中加入重试逻辑替换原start-hadoop.shcommand: /bin/bash -c until nc -z hadoop-worker 9866; do echo Waiting for DataNode...; sleep 5; done; start-hadoop.sh tail -f /dev/null 4.2 现象Hive Beeline 连接成功但show databases;报错org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionState原因HiveServer2 启动时未加载 Hadoop 配置core-site.xml和hdfs-site.xml未挂载到 Hive 容器的/opt/hive/conf/目录或HIVE_CONF_DIR环境变量指向错误路径。解决检查docker-compose.yml中hive-server的volumes是否包含 Hadoop 配置挂载volumes: - ./hadoop-config:/opt/hive/conf/hadoop # 正确Hive 会读取 /opt/hive/conf/hadoop/core-site.xml # 错误示例- ./hadoop-config:/usr/local/hadoop/etc/hadoop Hive 根本不读这个路径并在./hive-conf/hive-site.xml中显式指定property namehive.config.resources/name value/opt/hive/conf/hadoop/core-site.xml,/opt/hive/conf/hadoop/hdfs-site.xml/value /property4.3 现象Spark 作业提交后卡在ACCEPTED状态YARN UI 显示AM Container一直ALLOCATED无日志输出原因Spark 客户端容器的spark-defaults.conf中spark.yarn.stagingDir指向的 HDFS 路径不存在或hadoop-master容器内hdfs用户无写权限。解决进入hadoop-master容器手动创建 staging 目录并授权docker exec -it hadoop-master bash hdfs dfs -mkdir -p /tmp/spark-staging hdfs dfs -chmod 777 /tmp/spark-staging # 开发环境可放宽生产需细化权限 hdfs dfs -ls /tmp/spark-staging # 确认目录存在且可写4.4 现象Hive 创建表后insert into成功但select返回空结果hdfs dfs -ls /user/hive/warehouse/default.db/t1显示文件存在但大小为 0原因Hive 默认事务表ACID要求hive.support.concurrencytrue且hive.enforce.bucketingtrue但本环境未启用事务插入数据实际写入临时目录未 commit。解决在./hive-conf/hive-site.xml中关闭事务强制使用非 ACID 表property namehive.support.concurrency/name valuefalse/value /property property namehive.enforce.bucketing/name valuefalse/value /property property namehive.exec.dynamic.partition.mode/name valuenonstrict/value /property然后重启hive-serverdocker restart hive-server。4.5 现象宿主机ping hadoop-master失败但docker exec -it hive-server ping hadoop-master成功原因Docker Desktop 在 Windows/macOS 上使用 Linux VM宿主机 DNS 无法解析 Compose 网络中的服务名必须通过127.0.0.1访问映射端口而非服务名。解决所有从宿主机发起的连接如 Beeline、Spark submit、浏览器访问 Web UI必须用localhost或127.0.0.1绝不能用hadoop-master✅beeline -u jdbc:hive2://localhost:10000❌beeline -u jdbc:hive2://hadoop-master:10000✅curl http://localhost:9870/webhdfs/v1/?opLISTSTATUS❌curl http://hadoop-master:9870/webhdfs/v1/?opLISTSTATUS5. 进阶技巧如何把本地开发的 Spark 作业无缝迁移到生产集群这个 Docker 环境最大的价值不是“能跑”而是“跑得像生产”。我见过太多团队本地用 Docker 跑通一上生产就报错ClassNotFoundException或NoSuchMethodError根源是开发环境和生产环境的 Hadoop/Spark 版本、Scala 版本、甚至 JVM 参数不一致。下面这个技巧能让你的本地作业 99% 兼容生产集群。5.1 构建与生产一致的 fat jar屏蔽本地依赖差异不要用spark-submit --jars加载一堆本地 jar而是把所有依赖打包进一个 fat jar并确保MANIFEST.MF中Main-Class正确。关键在于用与生产集群完全相同的 Scala 和 Spark 版本编译。假设生产集群是 Spark 3.4.2 Scala 2.12 Hadoop 3.3.6你的build.sbt必须这样写name : my-spark-job version : 1.0 scalaVersion : 2.12.18 // 必须与 Spark 3.4.2 编译的 Scala 版本一致 libraryDependencies Seq( org.apache.spark %% spark-sql % 3.4.2 % provided, // provided运行时由集群提供 org.apache.spark %% spark-hive % 3.4.2 % provided, org.apache.hive % hive-exec % 3.1.2 % provided ) // 打包插件sbt-assembly assemblyMergeStrategy in assembly : { case PathList(META-INF, xs _*) MergeStrategy.discard case x MergeStrategy.first } // 关键排除 Spark 自带的 Hadoop 依赖避免版本冲突 assemblyExcludedJars in assembly : { val cp (fullClasspath in assembly).value cp filter {_.data.getName.contains(hadoop-common-3.3.6.jar)} cp filter {_.data.getName.contains(hadoop-client-runtime-3.3.6.jar)} }编译命令sbt clean assembly # 输出 target/scala-2.12/my-spark-job-assembly-1.0.jar为什么必须 exclude Hadoop jarDocker 环境中hadoop-master容器已提供 Hadoop 3.3.6 的所有 jar若 fat jar 内嵌hadoop-common-3.3.4.jarSpark ClassLoader 会优先加载它导致org.apache.hadoop.fs.FileSystem类冲突报错java.lang.NoSuchMethodError: org.apache.hadoop.fs.FileSystem.get(Ljava/net/URI;Lorg/apache/hadoop/conf/Configuration;)Lorg/apache/hadoop/fs/FileSystem;。5.2 用spark-submit的--files和--archives挂载配置而非硬编码很多人把core-site.xml、hive-site.xml直接打进 jar这会导致配置无法热更新。正确做法是把配置文件作为资源挂载让 Spark 运行时动态加载。spark-submit \ --master yarn \ --deploy-mode cluster \ --files /path/to/core-site.xml,/path/to/hive-site.xml \ --archives /path/to/hadoop-conf.tar.gz#hadoop-conf \ # 解压到工作目录 --conf spark.hadoop.fs.defaultFShdfs://prod-cluster:8020 \ --conf spark.sql.hive.hiveserver2.jdbc.urljdbc:hive2://prod-hive:10000 \ --class com.example.MyJob \ my-spark-job-assembly-1.0.jar--archives的妙用hadoop-conf.tar.gz包含整个hadoop/etc/hadoop/目录Spark 会自动将其解压到./hadoop-conf并通过--conf spark.hadoop.yarn.resourcemanager.addressprod-cluster:8032覆盖 jar 内配置实现“一套代码多套环境”。5.3 本地调试技巧用--driver-java-options捕获真实异常当作业在 YARN 上失败日志分散在 AM、Executor、YARN RM 多处。本地调试时用--driver-java-options将异常堆栈打印到控制台spark-submit \ --master yarn \ --deploy-mode client \ --driver-java-options -Dlog4j.configurationFilefile:///opt/spark/conf/log4j2.xml -XX:PrintGCDetails \ --conf spark.sql.adaptive.enabledfalse \ # 关闭 AQE避免本地与生产行为不一致 --class com.example.MyJob \ my-spark-job-assembly-1.0.jar血泪经验-XX:PrintGCDetails能暴露内存泄漏——如果 GC 频繁且 Full GC 后老年代不释放大概率是Broadcast变量过大或Accumulator未清理。这比看 YARN 日志快 10 倍。我坚持在本地 Docker 环境中跑通所有 SQL 和 DataFrame 操作再提交到生产集群不是为了省事而是因为——所有线上问题90% 都能在本地复现只要你用对了镜像、配对了版本、挂对了配置。这个docker-hadoop-spark-hive环境不是玩具是你的第一道防火墙。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站