简介面向华为云大数据入门与课程实验的 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系统盘 40Gnode2从节点DataNode、NodeManager、SecondaryNameNode、Spark Worker4 核 8G系统盘 40G 数据盘 100Gnode3从节点DataNode、NodeManager、Spark Worker4 核 8G系统盘 40G 数据盘 100Gnode4从节点DataNode、NodeManager、Spark Worker4 核 8G系统盘 40G 数据盘 100G磁盘容量按实验数据量估课程实验的输入文本通常在几百 MB 级别三副本放大后不超过 2G100G 数据盘绰绰有余。真正吃盘的是临时目录和 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 注册不上 NameNodehdfs 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 -versionjava -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.xmlHDFS 入口 临时目录 对象存储密钥 -- ?xml version1.0? configuration !-- 默认文件系统指向 node1 的 NameNode RPC 端口 -- property namefs.defaultFS/name valuehdfs://node1:8020/value /property !-- 运行时临时目录必须落在数据盘上避免系统盘写满 -- property namehadoop.tmp.dir/name valuefile:///data/hadoop/tmp/value /property !-- 对象存储访问密钥从环境变量读取避免明文落盘 -- property namefs.obs.access.key/name value${env:OBJECT_STORAGE_AK}/value /property property namefs.obs.secret.key/name value${env:OBJECT_STORAGE_SK}/value /property !-- 允许多个文件系统实现共存HDFS 与对象存储各走各的 -- property namefs.defaultFS.impl.disable.cache/name valuetrue/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 version1.0? configuration !-- 三副本四个节点时至少有三个 DataNode 能满足 -- property namedfs.replication/name value3/value /property !-- NameNode 元数据目录单独放方便备份和排查 -- property namedfs.namenode.name.dir/name valuefile:///data/hadoop/name/value /property !-- DataNode 数据块目录 -- property namedfs.datanode.data.dir/name valuefile:///data/hadoop/data/value /property !-- 二次元数据节点放在 node2和 NameNode 错开 -- property namedfs.namenode.secondary.http-address/name valuenode2:9868/value /property /configurationdfs.replication写 3 是三副本的标准配置。如果实验时为了省磁盘改成 1dfsadmin -report里 Configured Capacity 会好看很多但验收时问「副本机制解决了什么问题」就答不上来而且完全失去了分布式存储的意义不建议这么省。!-- yarn-site.xml资源调度器主机与容器内存上限 -- ?xml version1.0? configuration !-- ResourceManager 所在主机 -- property nameyarn.resourcemanager.hostname/name valuenode1/value /property !-- shuffle 服务MapReduce 任务必须开 -- property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property !-- 单节点可供 YARN 调度的总内存按 8G 机器留出系统开销后给 6G -- property nameyarn.nodemanager.resource.memory-mb/name value6144/value /property !-- 单个容器最大内存超过这个值的任务会被直接拒绝 -- property nameyarn.scheduler.maximum-allocation-mb/name value4096/value /property /configurationyarn.nodemanager.resource.memory-mb是这个文件里最需要按机器调整的参数。8G 内存的机器给 6144 是比较稳的值给满 8192 会让 NodeManager 自己抢不到内存容器还没起来就被系统 OOM 杀掉日志里会出现Container exited with a non-zero exit code 137这个错误码值得记下来看到它先怀疑内存超卖。!-- mapred-site.xml告诉 MapReduce 去 YARN 上跑 -- ?xml version1.0? configuration property namemapreduce.framework.name/name valueyarn/value /property !-- 容器内执行 MapReduce 任务所需的 classpath -- property namemapreduce.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/ done3.3 格式化与启动只格式化一次启动后逐项核对进程格式化是整个实验里唯一一个「做错就得重来」的动作。hdfs namenode -format会在 NameNode 目录下生成一个新的 clusterIDDataNode 启动时会比对本地记录的 clusterID不一致就直接拒绝注册。所以格式化只能在第一次启动前执行一次之后不管怎么改配置都不能再格。# 第一次启动前执行且只执行一次 hdfs namenode -format # 启动 HDFS 和 YARN脚本会自动 SSH 到 workers 里的节点拉进程 start-dfs.sh start-yarn.sh # 在四台机器上分别执行核对进程 jpsjps的期望输出是分机器看的node1 上有NameNode、ResourceManagernode2 上有DataNode、NodeManager、SecondaryNameNodenode3 和 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_HOSTnode1 export SPARK_MASTER_PORT7077 # 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 EOFHADOOP_CONF_DIR是这三个变量里最关键的一个。不设它Spark 读hdfs://路径时会报No FileSystem for scheme hdfs读对象存储路径时报同样的错但换成对应 scheme很多人误以为是 Spark 缺依赖其实是它压根没去读 Hadoop 的配置。设好之后把这三份配置同步到三个 Worker 节点再在 Master 上启动。# 启动 Spark 集群Master 起在 node1Worker 按 workers 文件拉 $SPARK_HOME/sbin/start-all.sh # 验证Master 上应看到 Master 进程Worker 上应看到 Worker 进程 jps | grep -E Master|Worker # 进 spark-sql 交互式客户端 $SPARK_HOME/bin/spark-sqljps里看到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 BatchModeyes -o ConnectTimeout3 $dst echo ok \ || echo 不通: $src - $dst done doneBatchModeyes的作用是禁止交互输入密码一旦需要密码就直接失败不会卡在提示符上等人。5.3 现象8088 界面打不开但集群进程都在原因是安全组没放行端口或者放行了但规则绑到了别的安全组上。进程正常、jps看得到 ResourceManager说明服务本身没问题问题在网络层。解决方式是先去控制台核对安全组入方向规则确认 8088 在列表里并且规则关联的是当前实例所在的安全组。如果规则没问题在机器上执行ss -lntp | grep 8088确认端口确实在监听。两个都对了还打不开检查是不是浏览器访问的是公网 IP 而规则只放行了内网——这种情况下用 SSH 本地端口转发最稳妥。5.4 现象对象存储能 ls 但 put 报 403原因是密钥有读权限没有写权限或者桶的策略限制了写入前缀。ls只需要 ListBucket 权限put需要 PutObject 权限两者在权限策略里是分开配的。解决办法是回控制台看这个访问密钥绑定的账号或子用户有哪些权限把对象存储的读写权限补全。如果用的是主账号密钥一般不会缺权限那就要怀疑桶策略里有没有显式 DenyDeny 的优先级高于 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 -lsdistcp列出目录拷贝后大小一致Spark 集群可用jps 8080 界面Alive Workers 为 3交互式查询spark-sql建表与聚合结果非空执行计划含 FileScan清单之外答辩时最常被追问的三个问题值得提前想清楚。第一个是「为什么 NameNode 和数据节点分开部署」答案要落到单点压力和故障隔离上而不是「教程这么写的」。第二个是「三副本带来了什么代价」答案要能说出存储放大三倍、写入需要等三个节点确认这是拿可靠性换空间和写延迟的取舍。第三个是「Spark 的 shuffle 和 MapReduce 的有什么区别」答案要能指出 Spark 的中间结果优先落内存、落盘时按分区聚合而 MapReduce 每个阶段都要落 HDFS。演示顺序也有讲究。先放进程和报障最少的 HDFS 报告中间演示 wordcount 和 SQL 查询这两个出结果的环节把对象存储互通放最后因为它依赖网络和密钥是最可能临时出状况的一环放在最后即使卡住也不影响前面的展示。每个环节的截图要包含主机名和命令本身只有结果没有命令的截图说服力要打对折。还有一个细节实验报告里的密钥、公网 IP、桶名这类信息交之前统一过一遍该打码的打码该用占位符的用占位符。我曾经见过一份写得很完整的报告因为附件里带着一张包含完整访问密钥的终端截图被要求全部重做——配置可以重来密钥泄露的后果不可逆。从那以后我每次交报告前都会用关键词把 PDF 和附件搜一遍确认没有明文凭证才发出去。理清资源、搭通集群、留下可复现的证据这套流程走完之后剩下的就是把这套结构照搬到你自己的题目里。希望帮到你。本文还有配套的精品资源点击获取