news 2026/10/31 7:14:17

云上大数据实验:Hadoop与Spark集群搭建、存储打通及验收

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
云上大数据实验:Hadoop与Spark集群搭建、存储打通及验收

简介:面向华为云大数据入门与课程实验的 docx 报告,适合高校学生、云计算初学者及需要完成大数据平台搭建练习的读者,围绕弹性云服务器、对象存储与集群部署等场景,梳理从环境准备到查询分析的实践路径。压缩包仅含 1 个 docx 文件,约 4.36MB,以图文实验记录和目录化步骤为主体,便于按实验模块查阅与复盘。内容覆盖四个部分:利用 ECS 与 OBS 搭建 Hadoop 集群,涉及 OpenJDK 安装、节点 SSH 互通与防火墙设置;借助华为云服务完成数据收集、存储与分析;BigData Pro 综合实验中的 ECS、OBS 购买配置及 Hadoop、Spark 集群搭建与 OBS 互联测试;以及基于 Spark SQL 或 Flink SQL 的交互式查询、建表与结果查看。报告保留关键配置与验证思路,可帮助读者理解云上大数据平台的搭建流程、服务协同方式和常见操作要点。已有 2541 人学习。

1. 从一份实验报告题目说起:云上大数据到底要交付什么

拿到「云上大数据实验报告」这个题目,多数人第一反应是照着步骤敲命令:买服务器、装 JDK、配免密、格式化、跑 wordcount。真到验收环节往往卡壳——为什么是四个节点、对象存储凭什么要单独买、Hadoop 集群和 Spark 集群谁管谁、交互式查询跑出来的结果怎么证明是对的。这份方案按「资源规划 → 集群搭建 → 存储打通 → 查询验证 → 排查 → 验收」推一遍,把云主机和云服务两条线路拆开讲清楚。适合要交课程设计、综合实验报告的学生,也适合第一次在云上交付一套 Hadoop 加 Spark 环境的从业者照着改。

2. 资源规划:四类云资源与一套密钥的边界划分

动手买资源之前先把账算清楚,这一步省下来的是后面返工的时间。云上大数据实验最容易踩的坑不是命令写错,而是一开始节点角色没分好、存储位置选错区域、密钥随手贴在文档里,等到集群起不来或者账单超出预期才发现问题出在第一小时。这一章把节点规格、对象存储、访问密钥、网络安全组四件事一次定死,后面所有配置文件都从这里取参数。

2.1 四个节点怎么分工:角色、规格与磁盘估算

四个节点是最小可用规模,原因是 HDFS 默认三副本,副本数决定了 DataNode 至少得有三个,否则副本永远处于欠复制状态,hdfs dfsadmin -report里会一直挂着一行 Under-replicated blocks,验收时解释不清。第四个节点拿来当 NameNode 和 ResourceManager 的宿主,管理进程和数据进程分开,集群压力大时不至于把 NameNode 拖死。

角色分配建议如下表,写进实验报告的「环境说明」章节,答辩时被问到「为什么这么分」能直接指过去。

主机名内网角色主要进程建议规格
node1主节点NameNode、ResourceManager、Spark Master4 核 8G,系统盘 40G
node2从节点DataNode、NodeManager、SecondaryNameNode、Spark Worker4 核 8G,系统盘 40G + 数据盘 100G
node3从节点DataNode、NodeManager、Spark Worker4 核 8G,系统盘 40G + 数据盘 100G
node4从节点DataNode、NodeManager、Spark Worker4 核 8G,系统盘 40G + 数据盘 100G

磁盘容量按实验数据量估:课程实验的输入文本通常在几百 MB 级别,三副本放大后不超过 2G,100G 数据盘绰绰有余。真正吃盘的是临时目录和 Spark 的 shuffle 落盘,所以hadoop.tmp.dir一定要指到数据盘,别留在系统盘上,否则跑两次 wordcount 系统盘就满了,日志写不进去,进程静默退出——这个现象排查起来非常费劲,因为jps看不到任何异常,只有翻hadoop-hadoop-namenode-*.log才能看到「No space left on device」。

规格选好之后统一按需计费购买,四个节点放同一个虚拟私有云、同一个子网,这一点是硬要求。跨子网虽然能通,但安全组规则要额外放行,实验阶段没必要给自己加难度。购买时镜像统一选同一个 Linux 发行版版本,避免后面装 JDK 时出现包管理器不一样、路径不一样的低级问题。

2.2 对象存储与访问密钥:桶建在哪,密钥怎么管

对象存储在这套方案里承担两个职责:一是作为集群外的数据落地面,把本地数据传上去、再从集群里读下来,验证「云主机 + 云服务」这条链路是通的;二是作为 Hadoop 和 Spark 的第二个文件系统入口,让计算节点能直接读写桶里的对象,不必先落 HDFS 再搬运。

建桶的时候注意三件事。第一,桶名全局唯一,起名带上项目缩写和随机后缀,别用test、data这种一撞就废的名字。第二,区域必须和 ECS 在同一个区域,同区域内网互通不计流量费,跨区域走公网既慢又产生额外费用,实验报告里也不好解释。第三,权限先选私有,实验阶段不要开公共读,后面通过访问密钥授权访问就够了。

访问密钥(AK/SK)的生成入口在控制台的「我的凭证」里,创建后浏览器会下载一个 csv 文件,里面是用户名、Access Key Id 和 Secret Access Key 三列。这个文件只给一次下载机会,丢了只能删掉重建。拿到之后立刻做两件事:把文件权限改成 600,把内容抄进本地的密码管理工具,然后在实验报告里只写「已配置访问密钥」,不要把明文粘进去。血泪经验是每年都有人的实验报告 PDF 里带着完整密钥截图,交上去等于把自己的桶公开了。

密钥在集群里的用法有两种。一种是把 AK/SK 写进core-site.xml,全局生效,简单但明文落盘;另一种是通过环境变量注入,配置文件里引用变量。实验中推荐后者,配置里能看到变量名,看不到值,报告里也干净。

# 把访问密钥写进当前 shell 的环境变量,只在本次会话有效 export OBJECT_STORAGE_AK="你的AccessKeyId" export OBJECT_STORAGE_SK="你的SecretAccessKey" # 验证变量是否生效,输出应为非空字符串 echo ${OBJECT_STORAGE_AK:0:4}********

上面这段只做一件事:让后续所有 Hadoop、Spark 进程通过继承父进程环境变量拿到密钥。参数说明上,OBJECT_STORAGE_AK和OBJECT_STORAGE_SK这两个名字要和后面 XML 里的${env:...}完全一致,大小写不同都会导致取到空值,表现出来就是「连不上桶」,但日志里报的是认证失败,很容易误判成密钥本身填错。启动集群时记得用同一个 shell 会话,或者把这两行写进/etc/profile并source一次,换窗口启动进程就会丢变量。

2.3 网络与安全组:放行哪些端口,防火墙怎么处理

云上的网络控制有两层,一层是安全组(在控制台配),一层是操作系统自带的防火墙(在机器里配)。实验环境里最省事的做法是:安全组按需放行,机器内的防火墙直接关掉。关防火墙不是好习惯,但它能把「端口到底通不通」这个变量彻底消除,剩下所有问题都收敛到配置上。

# 实验环境关闭系统防火墙,避免节点间端口被拦 systemctl stop firewalld systemctl disable firewalld # 确认状态,输出应为 inactive (dead) systemctl status firewalld | head -n 3

关闭之后,节点之间的通信就完全由安全组决定。需要放行的端口整理成下表,安全组规则里按「入方向、同一安全组」批量添加,比一个个加 IP 段省事。

端口用途是否必须
22SSH 登录与节点间免密跳转必须
8020HDFS NameNode RPC必须
9870NameNode Web UI,验收截图用必须
8088YARN ResourceManager Web UI必须
9868SecondaryNameNode Web UI建议
7077Spark Master 通信端口必须
8080Spark Master Web UI必须
18080Spark History Server建议

放行到「同一安全组」而不是「0.0.0.0/0」,是为了避免把 9870、8088 这类管理界面暴露到公网。如果确实需要在本机浏览器看 Web UI,用 SSH 本地端口转发,把远端 9870 映射到本地,比开公网端口安全得多。

3. Hadoop 集群落地:从 JDK、免密到四份 XML 的完整配置

集群能不能起来,八成取决于这一章的三件事:主机名和 hosts 有没有对齐、免密是不是四个节点互相都通、四份 XML 里的路径和主机名有没有写错。命令本身不难,难的是出错时不报错、只报一堆看不懂的 Java 异常。下面按「基础环境 → 配置文件 → 启动验证」的顺序走,每一步都给出可自查的判断标准。

3.1 基础环境:主机名、hosts、JDK 与节点互信

第一件事是主机名。云主机买来默认给一个又长又随机的名字,四个节点各不相同,Hadoop 配置文件里写node1就解析不到。所以要统一改成 node1 到 node4,并且把映射关系写进每台机器的/etc/hosts。

# 在每台机器上设置主机名,node1 上执行就写 node1,以此类推 hostnamectl set-hostname node1 # 把四个节点的内网 IP 与主机名写进 hosts,四台机器内容必须完全一致 cat >> /etc/hosts <<'EOF' 192.168.0.10 node1 192.168.0.53 node2 192.168.0.169 node3 192.168.0.77 node4 EOF # 验证:四台机器上分别执行,四条都能 ping 通才算过 ping -c 1 node2 && ping -c 1 node3 && ping -c 1 node4

这段脚本的关键在 hosts 内容四台完全一致。只要有一台少了某一行,就会出现「A 能连 B、B 连不上 A」的诡异现象,表现为 DataNode 注册不上 NameNode,hdfs dfsadmin -report里 Live datanodes 数量永远少于预期。IP 要填内网地址,不要填公网地址,公网地址在集群内部绕一圈回来,延迟高且可能被安全组拦。

第二件事是 JDK。Hadoop 3.x 用 OpenJDK 8 就够,从系统包管理器装,别手工解压 tar 包,省得后面JAVA_HOME写错。

# 安装 OpenJDK 8 运行时与开发包 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel # 找到真实的 JAVA_HOME,输出形如 /usr/lib/jvm/java-1.8.0-openjdk-xxx readlink -f $(which java) | sed 's#/bin/java##' # 写进环境变量,四台机器都要执行 echo 'export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk' >> /etc/profile echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile source /etc/profile && java -version

java -version能打出带1.8.0的版本号,这一关就过了。注意JAVA_HOME要指向 JDK 根目录而不是bin目录,多写一层或少写一层,启动时都会报JAVA_HOME is not set,这个报错和「没装 JDK」长得一模一样,容易误判。

第三件事是免密。Hadoop 的启动脚本靠 SSH 分发命令,NameNode 必须能免密连到所有 DataNode,包括它自己。做法是四个节点各生成一对密钥,把所有公钥汇总成一份authorized_keys,再推回四台机器。

# 每个节点执行:生成密钥对,-N "" 表示不设密码,-f 指定路径 ssh-keygen -t rsa -b 4096 -N "" -f /root/.ssh/id_rsa # 在 node1 上汇总所有节点的公钥,首次执行需要手工输入各节点密码 : > /tmp/all_keys for h in node1 node2 node3 node4; do ssh $h "cat /root/.ssh/id_rsa.pub" >> /tmp/all_keys done # 把汇总后的授权列表推回四台机器,并修正权限 for h in node1 node2 node3 node4; do scp /tmp/all_keys $h:/root/.ssh/authorized_keys ssh $h "chmod 600 /root/.ssh/authorized_keys" done

第一次跑 for 循环时必然要输密码,如果节点多,更省事的办法是把四段公钥内容打印出来,在控制台的远程命令功能里一次性粘贴进各自的authorized_keys,跳过密码环节。验证方式是四台机器各执行一遍ssh node1到ssh node4的全部组合,第一次会问yes/no,输完 yes 之后再连一次不能有任何提示。特别注意ssh node1连自己也必须免密,脚本里最容易漏的就是自己连自己。

3.2 四份核心 XML:每个参数对应哪个环节

Hadoop 的配置文件看着多,真正决定集群能否跑起来的就四个:core-site.xml定文件系统入口和临时目录,hdfs-site.xml定副本数和数据落盘路径,yarn-site.xml定资源调度器,mapred-site.xml定计算框架跑在哪。写配置文件有个原则:路径必须是绝对路径,主机名必须和 hosts 里一致,能引用环境变量的绝不写死。

<!-- core-site.xml:HDFS 入口 + 临时目录 + 对象存储密钥 --> <?xml version="1.0"?> <configuration> <!-- 默认文件系统指向 node1 的 NameNode RPC 端口 --> <property> <name>fs.defaultFS</name> <value>hdfs://node1:8020</value> </property> <!-- 运行时临时目录,必须落在数据盘上,避免系统盘写满 --> <property> <name>hadoop.tmp.dir</name> <value>file:///data/hadoop/tmp</value> </property> <!-- 对象存储访问密钥,从环境变量读取,避免明文落盘 --> <property> <name>fs.obs.access.key</name> <value>${env:OBJECT_STORAGE_AK}</value> </property> <property> <name>fs.obs.secret.key</name> <value>${env:OBJECT_STORAGE_SK}</value> </property> <!-- 允许多个文件系统实现共存,HDFS 与对象存储各走各的 --> <property> <name>fs.defaultFS.impl.disable.cache</name> <value>true</value> </property> </configuration>

关于对象存储相关的两个 property,不同云平台提供的 Hadoop 插件在配置项命名上略有差异,通常的做法是先下载对应平台的对象存储 Hadoop SDK 包,解压到$HADOOP_HOME/share/hadoop/common/lib,再按官方文档里给出的fs.<scheme>.access.key格式填写。上面的obs是 scheme 占位,实际按插件文档替换。判断配没配对,看启动日志里有没有FileSystem for <scheme> initialized,没有就是插件没加载上。

<!-- hdfs-site.xml:副本数 + NameNode 与 DataNode 的落盘目录 --> <?xml version="1.0"?> <configuration> <!-- 三副本,四个节点时至少有三个 DataNode 能满足 --> <property> <name>dfs.replication</name> <value>3</value> </property> <!-- NameNode 元数据目录,单独放,方便备份和排查 --> <property> <name>dfs.namenode.name.dir</name> <value>file:///data/hadoop/name</value> </property> <!-- DataNode 数据块目录 --> <property> <name>dfs.datanode.data.dir</name> <value>file:///data/hadoop/data</value> </property> <!-- 二次元数据节点放在 node2,和 NameNode 错开 --> <property> <name>dfs.namenode.secondary.http-address</name> <value>node2:9868</value> </property> </configuration>

dfs.replication写 3 是三副本的标准配置。如果实验时为了省磁盘改成 1,dfsadmin -report里 Configured Capacity 会好看很多,但验收时问「副本机制解决了什么问题」就答不上来,而且完全失去了分布式存储的意义,不建议这么省。

<!-- yarn-site.xml:资源调度器主机与容器内存上限 --> <?xml version="1.0"?> <configuration> <!-- ResourceManager 所在主机 --> <property> <name>yarn.resourcemanager.hostname</name> <value>node1</value> </property> <!-- shuffle 服务,MapReduce 任务必须开 --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 单节点可供 YARN 调度的总内存,按 8G 机器留出系统开销后给 6G --> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>6144</value> </property> <!-- 单个容器最大内存,超过这个值的任务会被直接拒绝 --> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>4096</value> </property> </configuration>

yarn.nodemanager.resource.memory-mb是这个文件里最需要按机器调整的参数。8G 内存的机器给 6144 是比较稳的值,给满 8192 会让 NodeManager 自己抢不到内存,容器还没起来就被系统 OOM 杀掉,日志里会出现Container exited with a non-zero exit code 137,这个错误码值得记下来,看到它先怀疑内存超卖。

<!-- mapred-site.xml:告诉 MapReduce 去 YARN 上跑 --> <?xml version="1.0"?> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <!-- 容器内执行 MapReduce 任务所需的 classpath --> <property> <name>mapreduce.application.classpath</name> <value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value> </property> </configuration>

除了这四份,还有两个文件别忘。hadoop-env.sh里要显式写export JAVA_HOME=...,即使系统环境变量已经设置了,Hadoop 的启动脚本在非登录 shell 下读不到;workers文件里写三行node2 node3 node4,不要写 node1,写进去等于让 NameNode 也当 DataNode,虽然能跑,但角色混乱,报告里不好解释。

配置改完之后用一条命令统一分发,避免手工复制漏文件。

# 把 node1 上改好的配置目录同步到其余三个节点 for h in node2 node3 node4; do rsync -av $HADOOP_HOME/etc/hadoop/ $h:$HADOOP_HOME/etc/hadoop/ done

3.3 格式化与启动:只格式化一次,启动后逐项核对进程

格式化是整个实验里唯一一个「做错就得重来」的动作。hdfs namenode -format会在 NameNode 目录下生成一个新的 clusterID,DataNode 启动时会比对本地记录的 clusterID,不一致就直接拒绝注册。所以格式化只能在第一次启动前执行一次,之后不管怎么改配置都不能再格。

# 第一次启动前执行,且只执行一次 hdfs namenode -format # 启动 HDFS 和 YARN,脚本会自动 SSH 到 workers 里的节点拉进程 start-dfs.sh start-yarn.sh # 在四台机器上分别执行,核对进程 jps

jps的期望输出是分机器看的:node1 上有NameNode、ResourceManager;node2 上有DataNode、NodeManager、SecondaryNameNode;node3 和 node4 上有DataNode、NodeManager。少任何一个,先去对应机器的$HADOOP_HOME/logs里找最新的.log文件,看最后 50 行。

进程齐了之后跑 wordcount,这是最经典也最有效的端到端验证。

# 在 HDFS 上建输入目录,上传一份本地文本 hdfs dfs -mkdir -p /input/wordcount hdfs dfs -put /etc/profile /input/wordcount/ # 提交 MapReduce 任务,输出目录不能预先存在 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ wordcount /input/wordcount /output/wordcount # 查看统计结果前几行 hdfs dfs -cat /output/wordcount/part-r-00000 | head -n 10

任务跑完看两个指标:hdfs dfs -ls /output/wordcount里_SUCCESS文件存在,说明作业正常结束;part-r-00000有内容且是「单词 + 次数」的格式,说明 Map 和 Reduce 都执行了。如果卡在map 0% reduce 0%超过两分钟,八成是 YARN 那边资源没申请到,去 8088 界面看 Applications 状态,或者直接看yarn-site.xml里的内存参数是不是配得比机器实际内存还大。

4. 存储打通与 Spark 接入:对象存储互联和交互式查询

Hadoop 跑通只证明「云主机上能跑分布式计算」,还差半截——云服务这条线要证明集群能读写对象存储,Spark 要证明能复用同一套 HDFS 配置做内存计算和交互式查询。这一章的两个目标都围绕「复用」展开:复用已有的 HDFS 配置,复用已经配好的密钥,少配一份就少一个出错点。

4.1 对象存储互通:先测小文件,再上 distcp

验证互通分两步走,先做最简单的一次上传下载,把认证链路打通,再考虑批量搬运。上来就用大数据量测,一旦失败分不清是密钥问题还是网络问题还是路径问题。

# 第一步:确认 Hadoop 能识别对象存储这个文件系统 hadoop fs -ls obs://你的桶名/ # 第二步:从本地推一个小文件上去,验证写权限 hadoop fs -put /etc/hosts obs://你的桶名/test/hosts.bak # 第三步:从桶里拉回来,验证读权限 hadoop fs -get obs://你的桶名/test/hosts.bak /tmp/hosts.check # 第四步:比对内容,一致才算真通 diff /etc/hosts /tmp/hosts.check && echo "互通验证通过"

hadoop fs -ls这条命令是分水岭。它能列出目录,说明插件加载、密钥认证、网络连通三件事全对;它报No FileSystem for scheme,是插件 jar 没放对位置;报InvalidAccessKeyId或者SignatureDoesNotMatch,是密钥或环境变量的问题;报Connect timed out,是内网不通或者区域不对。三种错误对应的排查方向完全不同,所以这一步的输出要原样贴进实验报告。

小文件通了之后再做集群内到对象存储的搬运,用distcp最稳,它会把大文件切块并行传,中途失败能续传。

# 把 HDFS 上的输出目录整体搬到对象存储,-m 控制并发 map 数 hadoop distcp -m 10 /output/wordcount obs://你的桶名/result/wordcount

-m 10表示开 10 个并发拷贝任务,四节点小集群给 10 足够,给太大反而会因为抢带宽变慢。搬完之后用hadoop fs -du -s -h obs://你的桶名/result/wordcount看总大小,和hdfs dfs -du -s -h /output/wordcount的数字比对,一致才说明没丢块。

4.2 Spark 集群接入:三个配置文件复用 Hadoop 的成果

Spark 在这套方案里是「再加一层计算引擎」,不是另起炉灶。它可以直接读 HDFS、读对象存储,前提是三份配置写对:spark-env.sh告诉它 Hadoop 配置在哪、Master 在哪;workers告诉它有哪些 Worker 节点;spark-defaults.conf定默认的 Master 地址和事件日志位置。

# spark-env.sh:核心是把 HADOOP_CONF_DIR 指过去,Spark 才能拿到 HDFS 与对象存储配置 export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export SPARK_MASTER_HOST=node1 export SPARK_MASTER_PORT=7077 # workers 文件只写从节点,Master 不参与计算 cat > $SPARK_HOME/conf/workers <<'EOF' node2 node3 node4 EOF # spark-defaults.conf:默认跑 standalone 集群,事件日志落到 HDFS cat > $SPARK_HOME/conf/spark-defaults.conf <<'EOF' spark.master spark://node1:7077 spark.eventLog.enabled true spark.eventLog.dir hdfs://node1:8020/spark-event spark.sql.warehouse.dir hdfs://node1:8020/user/hive/warehouse EOF

HADOOP_CONF_DIR是这三个变量里最关键的一个。不设它,Spark 读hdfs://路径时会报No FileSystem for scheme "hdfs",读对象存储路径时报同样的错但换成对应 scheme,很多人误以为是 Spark 缺依赖,其实是它压根没去读 Hadoop 的配置。设好之后把这三份配置同步到三个 Worker 节点,再在 Master 上启动。

# 启动 Spark 集群,Master 起在 node1,Worker 按 workers 文件拉 $SPARK_HOME/sbin/start-all.sh # 验证:Master 上应看到 Master 进程,Worker 上应看到 Worker 进程 jps | grep -E "Master|Worker" # 进 spark-sql 交互式客户端 $SPARK_HOME/bin/spark-sql

jps里看到Master和Worker就说明集群起来了,此时访问node1:8080能看到 Worker 列表和核心数分配情况。这一步的常见问题是 Worker 起来了但 Master 显示 Alive Workers 为 0,原因通常是 Worker 上的spark-env.sh没同步,SPARK_MASTER_HOST还是默认值,连不上 Master。

4.3 交互式查询:建外部表、写 SQL、看执行计划

交互式查询这一环要证明的不只是「能写 SQL」,而是「SQL 直接跑在集群存储上」。做法是先建一张指向 HDFS 目录的外部表,再用聚合查询验证结果,最后看执行计划确认计算确实被下推。

-- 建外部表指向 HDFS 上的数据目录,删表不删数据 CREATE EXTERNAL TABLE IF NOT EXISTS access_log ( ip STRING, url STRING, status INT, bytes BIGINT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE LOCATION 'hdfs://node1:8020/data/access_log'; -- 按状态码聚合,统计请求数与总流量 SELECT status, COUNT(*) AS req_cnt, SUM(bytes) AS total_bytes FROM access_log GROUP BY status ORDER BY req_cnt DESC LIMIT 10;

建表时EXTERNAL关键字不能省。省掉就变成管理表,DROP TABLE会把 HDFS 上的原始数据一起删掉,实验数据重来一遍。LOCATION指向的目录要提前hdfs dfs -put上去,目录下可以有多个文件,Spark 会按分片并行读取,分片数等于文件数或者块数,这也是 HDFS 适合做数据湖底座的直接原因。

验证结果是不是真的算对了,用EXPLAIN看执行计划。

-- 查看逻辑计划与物理计划,确认扫描的是 HDFS 上的外部表 EXPLAIN EXTENDED SELECT status, COUNT(*) FROM access_log GROUP BY status;

输出里能看到FileScan节点,路径指向建表时的LOCATION,说明数据确实来自 HDFS 而不是某张内存临时表。物理计划里出现HashAggregate说明聚合在内存里做,出现Exchange说明发生了 shuffle,这两个节点是答辩时讲「Spark 为什么比 MapReduce 快」的实物证据,比背概念有说服力。

5. 避坑与排查:五类最容易翻车的问题

这一章列的五个问题,每一个我都见过有人在验收前一天卡住。共同特点是报错信息不指向真正的原因,所以排查必须按「现象 → 原因 → 解决」的顺序倒推,而不是从报错文字直接猜。

5.1 现象:DataNode 起不来,NameNode 显示 Live datanodes 为 0

原因基本只有一个:格式化执行了不止一次。第二次hdfs namenode -format会生成新的 clusterID,写进 NameNode 目录,而 DataNode 本地VERSION文件里记的还是旧 ID,启动时校验失败直接退出,日志里报Incompatible clusterIDs。

解决办法是清掉重建。先stop-dfs.sh停掉所有进程,删除 NameNode 和 DataNode 的数据目录(就是hdfs-site.xml里配的那两个路径),重新hdfs namenode -format一次,再启动。清目录之前确认里面没有需要保留的实验数据,因为这一步是不可逆的。

5.2 现象:start-dfs.sh报 Permission denied (publickey)

原因是免密只做了单向或者漏了节点。最常见的漏法是「node1 到 node2/3/4 都通了,但 node1 到自己没通」,启动脚本在本地执行ssh node1时卡住。

解决方式是逐个验证全组合,把没通的补上。验证脚本要覆盖 16 种组合,别只测 node1 出发的四条。

# 四台机器上分别执行,16 次全部无密码提示才算过 for src in node1 node2 node3 node4; do for dst in node1 node2 node3 node4; do ssh $src "ssh -o BatchMode=yes -o ConnectTimeout=3 $dst 'echo ok'" \ || echo "不通: $src -> $dst" done done

BatchMode=yes的作用是禁止交互输入密码,一旦需要密码就直接失败,不会卡在提示符上等人。

5.3 现象:8088 界面打不开,但集群进程都在

原因是安全组没放行端口,或者放行了但规则绑到了别的安全组上。进程正常、jps看得到 ResourceManager,说明服务本身没问题,问题在网络层。

解决方式是先去控制台核对安全组入方向规则,确认 8088 在列表里,并且规则关联的是当前实例所在的安全组。如果规则没问题,在机器上执行ss -lntp | grep 8088确认端口确实在监听。两个都对了还打不开,检查是不是浏览器访问的是公网 IP 而规则只放行了内网——这种情况下用 SSH 本地端口转发最稳妥。

5.4 现象:对象存储能 ls 但 put 报 403

原因是密钥有读权限没有写权限,或者桶的策略限制了写入前缀。ls只需要 ListBucket 权限,put需要 PutObject 权限,两者在权限策略里是分开配的。

解决办法是回控制台看这个访问密钥绑定的账号或子用户有哪些权限,把对象存储的读写权限补全。如果用的是主账号密钥,一般不会缺权限,那就要怀疑桶策略里有没有显式 Deny,Deny 的优先级高于 Allow,有 Deny 时补多少 Allow 都没用。

5.5 现象:Spark 提交任务报 ClassNotFound,或者读 HDFS 报 No FileSystem

原因是 Worker 节点上的spark-env.sh和 Master 不一致,HADOOP_CONF_DIR没同步过去。Driver 在 Master 上跑,能读到配置,Executor 在 Worker 上跑,读不到,于是提交阶段一切正常,执行阶段才炸。

解决办法是把$SPARK_HOME/conf整个目录同步到所有 Worker,同步完重启集群。判断依据是 Worker 上的spark-env.sh里必须有一行export HADOOP_CONF_DIR=...,缺了这行就是没同步。

6. 验收与答辩:怎么证明这套集群真的跑通了

验收不是把命令再敲一遍,而是拿证据说话。我的习惯是准备一张验收清单,每一项都对应一个可截图的输出,答辩时按清单顺序演示,被打断了也能接得上。

验收项验证命令通过标准
集群进程完整四台机器分别jps进程与角色表完全对应
HDFS 可用hdfs dfsadmin -reportLive datanodes 为 3,无欠复制块
计算引擎可用wordcount 作业_SUCCESS存在,输出有内容
云存储互通hadoop fs -ls+distcp列出目录,拷贝后大小一致
Spark 集群可用jps+ 8080 界面Alive Workers 为 3
交互式查询spark-sql建表与聚合结果非空,执行计划含 FileScan

清单之外,答辩时最常被追问的三个问题值得提前想清楚。第一个是「为什么 NameNode 和数据节点分开部署」,答案要落到单点压力和故障隔离上,而不是「教程这么写的」。第二个是「三副本带来了什么代价」,答案要能说出存储放大三倍、写入需要等三个节点确认,这是拿可靠性换空间和写延迟的取舍。第三个是「Spark 的 shuffle 和 MapReduce 的有什么区别」,答案要能指出 Spark 的中间结果优先落内存、落盘时按分区聚合,而 MapReduce 每个阶段都要落 HDFS。

演示顺序也有讲究。先放进程和报障最少的 HDFS 报告,中间演示 wordcount 和 SQL 查询这两个出结果的环节,把对象存储互通放最后,因为它依赖网络和密钥,是最可能临时出状况的一环,放在最后即使卡住也不影响前面的展示。每个环节的截图要包含主机名和命令本身,只有结果没有命令的截图,说服力要打对折。

还有一个细节:实验报告里的密钥、公网 IP、桶名这类信息,交之前统一过一遍,该打码的打码,该用占位符的用占位符。我曾经见过一份写得很完整的报告,因为附件里带着一张包含完整访问密钥的终端截图,被要求全部重做——配置可以重来,密钥泄露的后果不可逆。从那以后我每次交报告前,都会用关键词把 PDF 和附件搜一遍,确认没有明文凭证才发出去。理清资源、搭通集群、留下可复现的证据,这套流程走完之后,剩下的就是把这套结构照搬到你自己的题目里。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 7:14:11

大数据上云实验链路:从云主机到Hadoop与Spark SQL

简介&#xff1a;这份docx实验报告面向学习华为云大数据平台部署与运维的高校学生及入门工程师&#xff0c;围绕弹性云服务器、OBS对象存储与Hadoop/Spark集群展开&#xff0c;帮助读者理解云主机和云服务两种实现路径。压缩包仅含1个docx文件&#xff0c;大小约4.36MB&#xf…

作者头像 李华
网站建设 2026/10/31 7:13:12

AI学习如何对接产业实战:从慕课题目看落地逻辑

简介&#xff1a;本资源为Uooc平台《人工智能行业与创新创业对接范式》慕课的配套习题答案详解&#xff0c;面向高校学生、AI初学者及创新创业课程学习者&#xff0c;助力快速掌握课程核心知识点并高效完成章节测验。文档覆盖1.1至1.3小节全部题型&#xff08;单选、多选、判断…

作者头像 李华
网站建设 2026/10/31 7:12:30

零基础机器学习入门:配套数据集实战指南

简介&#xff1a;这份数据集面向刚接触机器学习、需要动手练习数据处理的初学者与进阶学习者&#xff0c;围绕「机器学习前置知识」整理&#xff0c;帮助读者在正式建模前熟悉真实数据的读取、清洗与探索流程。压缩包共6个文件&#xff0c;以csv为主&#xff0c;另有1个h5与1个…

作者头像 李华
网站建设 2026/10/31 7:12:26

鸢尾花数据集实战:马氏距离、GMM、PCA、LDA与刀切法全解析

简介&#xff1a;这份数理统计大作业文档面向高校统计学、机器学习课程的学习者&#xff0c;围绕经典鸢尾花数据集展开完整分析&#xff0c;帮助读者理解多重变量数据的建模流程。内容涵盖马氏距离度量样本相似度、混合高斯模型聚类、主成分分析降维去噪、线性判别分析兼顾类间…

作者头像 李华
网站建设 2026/10/31 7:11:49

Spark本地与HDFS文件路径规范及常见URISyntaxException解决方案

简介&#xff1a;本资源是《大数据技术原理与应用》课程配套的Spark初级编程实践实验报告&#xff0c;面向高校大数据初学者及Hadoop/Spark入门学习者&#xff0c;聚焦分布式计算框架的核心操作与排错能力培养。压缩包为1个1.9MB的DOCX文档&#xff0c;完整涵盖实验环境配置&am…

作者头像 李华