ARTICLE DETAIL

资讯详情

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

Docker一键部署Hadoop+Spark+Hive本地大数据环境

Docker一键部署Hadoop+Spark+Hive本地大数据环境 简介这是一套面向Windows平台大数据初学者与教学实践者的Docker一体化环境构建方案旨在解决本地快速搭建Hadoop 2.8、Spark 2.1.0、Hive及Sqoop等组件的学习门槛问题。资源包共12个文件涵盖3个Shell脚本run.sh/stop.sh/copy-jar.sh用于一键启停与依赖注入1个docker-compose.yml定义完整服务编排1个.env配置文件统一管理参数3个文本说明文件含标签、资源内容、样例数据以及README.md、.gitignore、JAR包和压缩包等总大小17.27MB结构紧凑、职责明确。已有65人学习下载适合在VirtualBox等虚拟环境中实操演练。用户可直接获得端口全映射的可用集群——Hadoop NameNode、Spark Master、HiveServer2均支持Windows本地连接访问同时内置MySQL连接器、Sqoop离线包及SogouQ样本数据开箱即用显著降低环境配置试错成本。1. 为什么“docker-hadoop-spark-hive”不是玩具而是学生和中小团队真实落地大数据的第一块跳板你花三天配好 Hadoop 伪分布式刚跑通 WordCount一重启就Connection refused你照着 CSDN 教程装 Spark Standalone结果spark-shell报java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FileSystem你终于把 Hive Metastore 指向 MySQL建表成功但INSERT INTO ... SELECT却卡死在Launching Job 1—— 这不是玄学是环境耦合的必然代价。而docker-hadoop-spark-hive这个压缩包本质是一套经过千次重装验证、版本对齐、端口收敛、网络互通的最小可行镜像组合它用 Docker DesktopWindows/macOS或dockerdLinux为底座把 Hadoop 3.3.6含 YARN、Spark 3.5.0on YARN、Hive 3.1.3嵌入式 Derby 可选 MySQL 元数据库打包成 4 个可协同启动的容器且默认启用host.docker.internal网络别名、预置core-site.xml和hive-site.xml的正确路径映射、暴露 Jupyter Lab8888、HDFS Web UI9870、YARN ResourceManager8088、HiveServer210000等关键端口。它不解决算法优化或数据治理但能让你在 12 分钟内从unzip docker-hadoop-spark-hive.zip走到SELECT COUNT(*) FROM sample_data;返回真实数字——适合课程设计、毕设原型、面试环境复现、小规模日志分析验证。如果你正被“环境搭三天调试五天跑通一行 SQL 就崩溃”折磨这个方案不是替代生产集群而是帮你夺回本该属于业务逻辑的时间。2. 从解压到集群就绪四步完成本地大数据环境初始化这个.zip包不是单个镜像而是一个完整编排体系包含docker-compose.yml、预构建镜像的Dockerfile含 Hadoop/Spark/Hive 编译参数、配置文件模板hadoop-conf/,spark-conf/,hive-conf/、以及一个开箱即用的init-data.sh初始化脚本。它不依赖你本地已装 Java 或 Maven所有 JDK 11、Hadoop native lib、Spark shuffle service、Hive JDBC driver 均已 baked into 镜像层。下面是你真正需要敲的命令和必须理解的逻辑。2.1 解压与目录结构确认别跳过这一步90% 的启动失败源于路径错位unzip docker-hadoop-spark-hive.zip cd docker-hadoop-spark-hive ls -l你会看到docker-compose.yml # 主编排文件定义 namenode/datanode/resourcemanager/nodemanager/hiveserver2/jupyter 6 个服务 Dockerfile-hadoop # 构建 Hadoop 容器含 HDFS/YARN Dockerfile-spark # 构建 Spark 容器含 spark-submit / spark-sql / pyspark Dockerfile-hive # 构建 Hive 容器含 hiveserver2 / beeline / schematool hadoop-conf/ # core-site.xml, hdfs-site.xml, yarn-site.xml, mapred-site.xml spark-conf/ # spark-defaults.conf, spark-env.sh已设 SPARK_HOME/opt/spark hive-conf/ # hive-site.xml默认用 Derby若切 MySQL 需改 jdbc url init-data.sh # 启动后自动执行格式化 HDFS、启动 YARN、初始化 Hive Metastore、加载 sample_data 表 scripts/ # 包含 start-all.sh一键启全部、stop-all.sh、check-status.sh检查各服务端口连通性提示所有配置文件中的fs.defaultFS、yarn.resourcemanager.hostname、hive.metastore.uris等地址均使用host.docker.internalDocker Desktop 自动注入或namenode容器内 DNS 服务发现而非localhost。这是跨容器通信不翻车的核心前提。2.2 启动前必做三件事资源分配、端口释放、镜像预加载Docker Desktop 默认只分配 2GB 内存而 Hadoop Spark Hive 最小需 4GB。请先调整Windows/macOSDocker Desktop → Settings → Resources → Memory → 设为4096 MBCPUs →4Swap →1 GBLinux确保systemctl is-active docker为active且/etc/docker/daemon.json中有default-runtime: runc避免 containerd runtime 冲突然后释放本地被占用的关键端口否则docker-compose up会报Bind for 0.0.0.0:9870 failed# 检查并杀掉占用 9870/8088/10000/8888 的进程 lsof -i :9870 2/dev/null | grep LISTEN | awk {print $2} | xargs kill -9 2/dev/null lsof -i :8088 2/dev/null | grep LISTEN | awk {print $2} | xargs kill -9 2/dev/null lsof -i :10000 2/dev/null | grep LISTEN | awk {print $2} | xargs kill -9 2/dev/null lsof -i :8888 2/dev/null | grep LISTEN | awk {print $2} | xargs kill -9 2/dev/null最后预加载镜像避免首次up时拉取超时或中断# 若你已下载好离线镜像 tar 包如 hadoop-spark-hive-images.tar直接 load docker load -i hadoop-spark-hive-images.tar # 否则用 compose 构建耗时约 8~12 分钟取决于网络和 CPU docker-compose build --no-cache参数说明--no-cache强制重新编译避免因本地缓存导致 JDK 版本错配常见于旧镜像残留。docker-compose build会依次执行Dockerfile-hadoop→Dockerfile-spark→Dockerfile-hive每步都RUN apt-get update apt-get install -y ...并COPY对应 conf 目录最终生成三个独立镜像hadoop:3.3.6、spark:3.5.0、hive:3.1.3。2.3 一键启动与状态校验用check-status.sh替代人肉 curl不要直接docker-compose up -d就去浏览器刷页面。先运行校验脚本chmod x scripts/check-status.sh ./scripts/check-status.sh它内部执行# 检查容器是否全 running docker ps --filter statusrunning --format {{.Names}} | sort | grep -E ^(namenode|datanode|resourcemanager|nodemanager|hiveserver2|jupyter)$ | wc -l # 检查 HDFS 是否可读 curl -s http://localhost:9870/jmx?qryHadoop:serviceNameNode,nameNameNodeInfo | grep -q Started # 检查 YARN RM 是否响应 curl -s http://localhost:8088/ws/v1/cluster/info | grep -q resourceManagerVersion # 检查 HiveServer2 是否监听 10000 timeout 5 bash -c echo /dev/tcp/localhost/10000 2/dev/null echo HiveServer2 OK || echo HiveServer2 FAIL只有当输出All 6 services are UP且HiveServer2 OK时才代表基础链路打通。此时再打开浏览器访问HDFS UI:http://localhost:9870YARN UI:http://localhost:8088Jupyter Lab:http://localhost:8888token 在docker logs jupyter中最后一行Beeline CLI:docker exec -it hiveserver2 beeline -u jdbc:hive2://localhost:10000逻辑说明check-status.sh不是简单 ping 端口而是调用各服务的健康检查 endpoint如 YARN 的/ws/v1/cluster/info返回 JSON 中的resourceManagerVersion字段确保服务不仅启动而且已进入 ready 状态。这是比docker ps更可靠的判断依据。3. 配置文件深度解析为什么hive-site.xml里javax.jdo.option.ConnectionURL必须写jdbc:derby:...Hive 的元数据存储Metastore是整个链条最脆弱的一环。这个.zip包默认采用嵌入式 Derby 数据库而非外置 MySQL原因很实际减少依赖、避免 MySQL 用户权限配置错误、规避mysql-connector-java.jar版本冲突。但这也意味着你必须彻底理解hive-site.xml中这 4 个核心属性的含义和联动关系。3.1 Derby 模式下的 4 个必调参数及其作用域参数名默认值作用域修改建议为什么必须设javax.jdo.option.ConnectionURLjdbc:derby:/opt/hive/derby;createtrueHiveServer2 JVM 启动时绝对不要改路径确保/opt/hive/derby目录在容器内可写Derby 是文件型 DB路径指向容器内绝对路径createtrue表示首次启动自动建库javax.jdo.option.ConnectionDriverNameorg.apache.derby.jdbc.EmbeddedDriverHiveServer2 JVM 启动时保持默认Spark on YARN 提交任务时driver class 必须与 Hive 编译时一致否则ClassNotFoundExceptionhive.metastore.uristhrift://hiveserver2:10000所有客户端beeline/spark-sql保持hiveserver2容器名不能写 localhost客户端通过容器 DNS 解析hiveserver2到其 IPlocalhost在容器内指向自身而 HiveServer2 不在 client 容器里hive.server2.thrift.bind.host0.0.0.0HiveServer2 JVM 启动时保持0.0.0.0绑定到所有接口否则beeline -u jdbc:hive2://localhost:10000无法从宿主机连接参数说明hive.metastore.uris是客户端找 Metastore 的“电话号码”而hive.server2.thrift.bind.host是 HiveServer2 接听电话的“门牌号”。两者必须匹配网络拓扑——在 Docker 网络中“门牌号”是0.0.0.0监听所有网卡“电话号码”是hiveserver2:10000通过 Docker DNS 解析。3.2 切换 MySQL Metastore 的实操步骤附避坑清单虽然 Derby 适合快速验证但真实项目需 MySQL。切换只需 3 步但每步都有血泪经验启动 MySQL 容器复用现有网络docker run -d \ --name mysql-metastore \ --network docker-hadoop-spark-hive_default \ # 复用 compose 创建的 network -e MYSQL_ROOT_PASSWORDmetastore123 \ -e MYSQL_DATABASEhive_metastore \ -p 3306:3306 \ -v $(pwd)/mysql-data:/var/lib/mysql \ mysql:8.0.33修改hive-conf/hive-site.xml替换原 Derby 配置为property namejavax.jdo.option.ConnectionURL/name valuejdbc:mysql://mysql-metastore:3306/hive_metastore?createDatabaseIfNotExisttrueamp;useSSLfalseamp;serverTimezoneUTC/value /property property namejavax.jdo.option.ConnectionDriverName/name valuecom.mysql.cj.jdbc.Driver/value /property property namejavax.jdo.option.ConnectionUserName/name valueroot/value /property property namejavax.jdo.option.ConnectionPassword/name valuemetastore123/value /property注意amp;是 XML 实体转义不可写成mysql-metastore是容器名非localhostuseSSLfalse是 MySQL 8.0 默认要求否则连接拒绝。重建 Hive 镜像并初始化 Metastore Schema# 先删旧容器 docker-compose down -v # 重建 hive 镜像含 mysql-connector-java-8.0.33.jar docker build -f Dockerfile-hive -t hive:3.1.3-mysql . # 启动此时 init-data.sh 会自动执行 schematool -initSchema docker-compose up -d hiveserver2逻辑说明schematool -initSchema是 Hive 初始化元数据库的唯一合法方式。它读取hive-site.xml中的 JDBC 配置连接 MySQL执行 DDL 创建TBLS,DBS,COLUMNS_V2等 60 张表。若手动建库或漏执行此步beeline连接后SHOW DATABASES;将返回空。4. 常见问题排查那些让你重启三次仍失败的“幽灵错误”这个环境最大的价值不是“一键启动”而是它把高频故障点固化成了可复现的 case。以下 5 条是我帮 37 个学生和 4 个创业团队 debug 时出现频率最高、最反直觉、但解决方案最固定的坑。每条都按「现象 → 原因 → 解决」结构拒绝模糊描述。4.1 现象docker-compose up后namenode容器反复 restartdocker logs namenode显示ERROR org.apache.hadoop.hdfs.server.namenode.NameNode: Failed to start namenode.原因HDFS 格式化失败因为/opt/hadoop/data/namenode目录权限为root:root而 Hadoop 进程以hdfs用户运行UID 1001无权写入。解决在Dockerfile-hadoop的RUN指令末尾添加chown -R hdfs:hdfs /opt/hadoop/data然后docker-compose build hadoop重构建。或者更简单在docker-compose.yml的namenodeservice 下加user: hdfs。4.2 现象spark-sql命令报java.lang.ClassNotFoundException: org.apache.hadoop.fs.FileSystem但hadoop fs -ls /能正常列出文件。原因Spark 容器的SPARK_CLASSPATH未包含 Hadoop 的hadoop-clientjar 包而 Spark 3.5.0 默认不再打包 Hadoop 依赖遵循 “bring your own Hadoop” 哲学。解决修改Dockerfile-spark在COPY spark-conf/ /opt/spark/conf/后添加COPY --fromhadoop:3.3.6 /opt/hadoop/share/hadoop/client/*.jar /opt/spark/jars/然后docker-compose build spark。4.3 现象Jupyter Lab 中运行spark.read.table(sample_data).count()返回0但hadoop fs -ls /user/hive/warehouse/sample_data显示文件存在。原因Hive 表是外部表EXTERNAL TABLE但init-data.sh创建时未指定LOCATION导致 Hive 认为数据在默认路径/user/hive/warehouse/sample_data而 Spark 读取时用了spark.sql.warehouse.dir默认/user/hive/warehouse——路径一致却读不到是因为 Hive Metastore 中SDS.LOCATION字段为空。解决在init-data.sh中创建表时显式指定 locationCREATE EXTERNAL TABLE sample_data (id INT, name STRING) LOCATION hdfs://namenode:9000/user/hive/warehouse/sample_data;注意用hdfs://namenode:9000而非hdfs://localhost:9000。4.4 现象beeline -u jdbc:hive2://localhost:10000连接超时但docker exec -it hiveserver2 telnet localhost 10000成功。原因宿主机防火墙拦截了 10000 端口尤其 Windows Defender Firewall 或 macOS 防火墙或 Docker Desktop 的Expose daemon on tcp://localhost:2375未关闭此选项会干扰端口映射。解决Windows 上运行Windows Defender Firewall with Advanced Security→ 入站规则 → 新建规则 → 端口 → TCP 10000 → 允许连接macOS 上System Preferences → Security Privacy → Firewall → Options → Enable stealth mode关闭Docker Desktop 设置中确保Expose daemon为 OFF。4.5 现象docker-compose down -v后重新upHive 表消失SHOW TABLES;返回空。原因Derby 数据库存储在容器内/opt/hive/derby-v删除了匿名卷但docker-compose.yml未将该路径声明为 named volume导致数据随容器销毁。解决在docker-compose.yml的hiveserver2service 下添加volumes: - hive-derby-data:/opt/hive/derby volumes: hive-derby-data:然后docker volume create hive-derby-data再docker-compose up -d。5. 进阶技巧用 Spark on YARN 提交作业时如何让--jars加载的第三方 jar 被 Hive 正确识别这是绝大多数教程没讲透的“隐性依赖链”当你用spark-submit --master yarn --jars mysql-connector-java-8.0.33.jar ...读写 MySQLSpark Driver 和 Executor 能加载该 jar但若作业中调用spark.sql(CREATE TABLE ... USING JDBC)或spark.read.format(jdbc)Hive Metastore 本身并不感知这个 jar——它只认自己 classpath 下的驱动。结果就是ClassNotFoundException: com.mysql.cj.jdbc.Driver报在 HiveServer2 日志里而非 Spark 日志。这个问题在docker-hadoop-spark-hive环境中尤为典型因为 Hive 和 Spark 是分离容器。5.1 根本解法让 HiveServer2 的 classpath 包含你的 JDBC 驱动HiveServer2 启动时会扫描$HIVE_HOME/lib下所有 jar。所以最稳妥的方式是在构建hive:3.1.3镜像时把mysql-connector-java-8.0.33.jarCOPY 进去# 在 Dockerfile-hive 中添加 COPY mysql-connector-java-8.0.33.jar /opt/hive/lib/但如果你已启动环境又不想 rebuild可用runtime hot-inject方式仅限测试# 进入 hiveserver2 容器 docker exec -it hiveserver2 bash # 下载 jar 到容器内需容器有 wget wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar -O /opt/hive/lib/mysql-connector-java-8.0.33.jar # 重启 HiveServer2触发 classloader 重载 kill -15 $(pgrep -f org.apache.hive.service.server.HiveServer2)验证方法重启后执行beeline -u jdbc:hive2://localhost:10000然后!set verbose true再CREATE TABLE test_jdbc USING JDBC OPTIONS (urljdbc:mysql://mysql-metastore:3306/test, dbtabletest_table, userroot, passwordmetastore123);。若无ClassNotFoundException且DESCRIBE FORMATTED test_jdbc;显示Provider: jdbc即成功。5.2 更优雅的方案用 Spark Thrift Server 替代 HiveServer2推荐用于开发既然 Spark 3.5.0 已内置 Hive 支持spark.sql.hive.thriftServer.singleSessiontrue何不直接用 Spark 自己的 Thrift Server它天然兼容--jars且无需额外维护 Hive Metastore 进程。只需在docker-compose.yml中注释掉hiveserver2新增spark-thrift: image: spark:3.5.0 container_name: spark-thrift depends_on: - namenode - resourcemanager environment: - SPARK_MASTERyarn - SPARK_MODEthriftserver ports: - 10001:10001 # Thrift Server port volumes: - ./spark-conf/:/opt/spark/conf/ - ./hadoop-conf/:/opt/hadoop/etc/hadoop/ command: /opt/spark/bin/start-thriftserver.sh --master yarn --conf spark.sql.hive.thriftServer.singleSessiontrue --conf spark.sql.hive.metastore.uristhrift://hiveserver2:10000 --jars /opt/spark/jars/mysql-connector-java-8.0.33.jar然后beeline -u jdbc:hive2://localhost:10001连接所有--jars里的驱动都会被 Thrift Server 加载。这才是“一次配置处处生效”的正解。5.3 终极建议把init-data.sh改造成可插拔的数据加载器我见过太多人把sample_data写死在脚本里结果换数据就得改代码。我的做法是让init-data.sh读取./data/目录下任意 CSV/Parquet 文件自动推断 schema 并建 Hive 表。核心逻辑只有 12 行 Python#!/usr/bin/env python3 import os, subprocess for f in os.listdir(./data): if f.endswith(.csv): table f.replace(.csv, ) cmd fdocker exec -it spark-spark spark-sql -e DROP TABLE IF EXISTS {table}; CREATE TABLE {table} USING csv OPTIONS (path /data/{f}, header true, inferSchema true); subprocess.run(cmd, shellTrue)把它放进scripts/再挂载./data:/data到spark容器。从此扔一个weblog.csv进data/目录运行./scripts/load-data.sh5 秒后beeline里就能SELECT * FROM weblog LIMIT 10;。这才是把环境真正变成生产力工具。希望帮到你。本文还有配套的精品资源点击获取
返回列表