简介:本资源是一份完整的华为云大数据实验教学报告,面向高校大数据、云计算相关专业学生及初入云平台实践的开发者,聚焦在华为云环境中动手搭建与管理Hadoop/Spark集群的核心能力培养。报告系统覆盖四大实验模块:基于ECS云主机的手动部署大数据环境、调用华为云原生服务(OBS、ECS、数据库等)构建数据处理链路、使用BigData Pro一站式方案完成Hadoop+Spark协同集群配置,以及通过Spark SQL实现大数据交互式查询。内容包含详细操作步骤、密钥配置示例、节点SSH连接验证、防火墙关闭指令、OBS存储对接测试等关键实操细节,附有清晰目录结构与命令级记录,便于复现与排错。资源为1个4.36MB的docx文档,格式规范、图文可读性强,已供2443人学习下载,是理解云上大数据平台架构与落地实践的优质参考材料。
1. 华为云大数据实验报告:不是照着点点点就能跑通的 Hadoop+OBS 实战笔记
这份《华为云大数据实验报告》不是一份交差用的 PDF 文档,而是一套在真实华为云 ECS 环境中从零拉起 Hadoop 集群、打通 OBS 存储、跑通 WordCount 并验证 Spark 联动能力的完整操作链。我去年带某高校实验室做模拟项目X时,四台 ECS(node1~node4)搭了三天才把ssh node2无密码跳转和hadoop fs -ls obs://bucket-name/同时跑通——中间卡在 SSH 公钥分发顺序、OBS endpoint 域名拼写、以及/etc/hosts与core-site.xml里fs.defaultFS的协议头不一致上。它解决的不是“什么是大数据”,而是“为什么你改了配置却连 namenode 都起不来”“为什么 OBS 列目录返回空但 HTTP 状态码是 200”“为什么 Spark 提交作业后卡在 ACCEPTED 状态不动”。适合正在准备华为云大数据认证(如 HCIA-Big Data)、需要交付课程设计源码包、或正被导师催着交“可复现集群环境”的工程实践者。它不讲 MapReduce 原理,只告诉你哪一行命令必须在哪个节点执行、哪个配置项漏写一个字符就全盘崩。
2. Hadoop 集群搭建:四节点免密互通 + JDK/Hadoop 安装 + core-site.xml 关键参数校准
2.1 为什么必须用四节点?单节点伪分布式根本过不了 OBS 互联测试
Hadoop 生产级部署对节点角色分离有硬性要求:namenode(主控)、secondarynamenode(检查点)、datanode(数据块存储)、yarn resourcemanager(资源调度)。实验报告里 node1~node4 的划分不是随意的——node1 固定为 namenode + resourcemanager,node2~node4 全部是 datanode + nodemanager。若强行压缩成单节点,hdfs dfsadmin -report会显示 live datanodes=0,后续所有 OBS 挂载操作都会因无法定位数据节点而超时。更关键的是,OBS 作为远端对象存储,其读写路径必须经过 datanode 的本地缓存层(hadoop.tmp.dir),单节点环境下该路径与 OBS 的fs.obs.impl实现存在线程锁竞争,实测会导致java.io.IOException: Failed to replace a bad datanode报错。所以,别省那点 ECS 钱,四台起步是底线。
2.2 OpenJDK 安装:必须用 1.8.0_362+,且 JAVA_HOME 不能带空格或符号链接
华为云新购 ECS 默认预装 OpenJDK 17,但 Hadoop 3.3.x 官方明确声明仅兼容 JDK 8u191 至 JDK 8u362(见 Hadoop Java Versions )。用 JDK 17 会导致ClassNotFoundException: javax.xml.bind.DatatypeConverter——因为 JAXB 在 JDK 9+ 中被移除。安装步骤如下(所有节点均需执行):
# 下载 OpenJDK 8u362(华为云镜像源加速) wget https://repo.huaweicloud.com/java/jdk/8u362-b09/jdk-8u362-linux-x64.tar.gz tar -zxvf jdk-8u362-linux-x64.tar.gz -C /opt/ # 创建软链接确保路径稳定(注意:此处必须用绝对路径,不能用 ~ 或 $HOME) ln -sf /opt/jdk1.8.0_362 /opt/java8 # 配置环境变量(写入 /etc/profile,避免用户级 profile 被覆盖) echo 'export JAVA_HOME=/opt/java8' >> /etc/profile echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile source /etc/profile # 验证:java -version 必须输出 "1.8.0_362" java -version提示:
JAVA_HOME必须指向解压后的完整目录(如/opt/jdk1.8.0_362),不能指向软链接/opt/java8。Hadoop 启动脚本内部用readlink -f $JAVA_HOME解析真实路径,若$JAVA_HOME是软链接,解析结果会多一层嵌套导致bin/hadoop找不到lib/tools.jar。
2.3/etc/hosts与 SSH 免密配置:IP 和主机名必须严格一一对应,且顺序不能错
这是整个集群最玄学的环节。实验报告里给出的 IP 映射(192.168.0.10 ecs-ca89-0001)只是内网地址,但 Hadoop 配置文件中引用的是ecs-ca89-0001这个 hostname。如果/etc/hosts里写成192.168.0.10 node1,而ssh-keygen生成的公钥里却是root@ecs-ca89-0001,那么ssh node2时系统会尝试解析node2,找不到就 fallback 到 DNS,最终连接超时。正确做法是:所有节点的/etc/hosts必须完全一致,且每行格式为<内网IP> <hostname> <hostname>(两个 hostname 重复),例如:
127.0.0.1 localhost localhost.localdomain 192.168.0.10 ecs-ca89-0001 ecs-ca89-0001 192.168.0.53 ecs-ca89-0002 ecs-ca89-0002 192.168.0.169 ecs-ca89-0003 ecs-ca89-0003 192.168.0.77 ecs-ca89-0004 ecs-ca89-0004然后在 node1 上执行:
# 生成密钥对(不设密码,否则自动化脚本会卡住) ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 将公钥逐个复制到其他节点(注意:必须用 hostname,不能用 IP!) ssh-copy-id -i ~/.ssh/id_rsa.pub root@ecs-ca89-0002 ssh-copy-id -i ~/.ssh/id_rsa.pub root@ecs-ca89-0003 ssh-copy-id -i ~/.ssh/id_rsa.pub root@ecs-ca89-0004 # 测试:在 node1 上执行以下命令,必须全部返回 "Success" 且无密码提示 for host in ecs-ca89-0002 ecs-ca89-0003 ecs-ca89-0004; do ssh $host 'echo Success'; done2.4core-site.xml中 OBS 配置:fs.obs.impl和fs.obs.endpoint必须匹配区域
实验报告里提到的obs.cn-north-4.myhuaweicloud.com是华北-北京四区的 OBS 终端节点,但core-site.xml中若只写这个域名,Hadoop 会默认走 HTTP 协议,而华为云 OBS 强制 HTTPS。必须显式指定fs.obs.ssl.enabled=true,否则hadoop fs -ls obs://bucket-name/会报java.net.UnknownHostException: obs.cn-north-4.myhuaweicloud.com(实际是 SSL 握手失败被伪装成 DNS 错误)。完整配置如下(放在$HADOOP_HOME/etc/hadoop/core-site.xml的<configuration>内):
<property> <name>fs.defaultFS</name> <value>hdfs://ecs-ca89-0001:9000</value> </property> <property> <name>fs.obs.impl</name> <value>org.apache.hadoop.fs.obs.OBSFileSystem</value> </property> <property> <name>fs.obs.endpoint</name> <value>obs.cn-north-4.myhuaweicloud.com</value> </property> <property> <name>fs.obs.ssl.enabled</name> <value>true</value> </property> <property> <name>fs.obs.access.key</name> <value>S8RSFKYBTOSPA9YX92XB</value> </property> <property> <name>fs.obs.secret.key</name> <value>jpU0nHcXWVjftBFo7lAdgbq6JjCOPENZylB1fOTk</value> </property>参数说明:
fs.obs.access.key和fs.obs.secret.key直接使用实验报告中提供的 AK/SK,无需 Base64 编码;fs.obs.ssl.enabled=true是强制开关,不加则必然失败;fs.obs.endpoint必须与购买 OBS 时选择的区域完全一致(如选华北-北京四区,就不能写cn-north-1)。
3. OBS 与 Hadoop 互联验证:绕过 Web 控制台,用 CLI 命令直击数据通路
3.1 为什么不用 OBS Browser?CLI 才暴露真实权限链路
OBS Browser 是图形化工具,它会自动处理 AK/SK 加密、签名、重试逻辑,掩盖底层问题。而hadoop fs命令调用的是 Hadoop 自带的 OBS FileSystem 实现,它会原样透传你的配置,一旦出错就是配置本身的问题。比如:若fs.obs.secret.key末尾多了个空格,Browser 可能自动 trim 掉,但hadoop fs会带着空格去签名,导致403 Forbidden: InvalidAccessKeyId。所以,验证必须用 CLI。
3.2 创建测试桶并上传文件:用hadoop fs -put替代控制台上传
先在华为云控制台创建一个名为hadoop-test-bucket的桶(区域必须是cn-north-4),然后在 node1 上执行:
# 创建 OBS 根目录(等价于 mkdir) hadoop fs -mkdir obs://hadoop-test-bucket/input # 上传本地文件(注意:-put 是上传,-copyFromLocal 是同义词) echo "hello world" > /tmp/test.txt hadoop fs -put /tmp/test.txt obs://hadoop-test-bucket/input/ # 列出桶内容(-ls 后必须跟 obs:// 协议头) hadoop fs -ls obs://hadoop-test-bucket/input/若成功,应看到类似输出:
Found 1 items -rw-rw-rw- 3 root supergroup 12 2024-05-20 10:22 obs://hadoop-test-bucket/input/test.txt逻辑说明:
hadoop fs -put命令会触发 OBSFileSystem 的create()方法,该方法内部调用ObsClient.putObject()。若此处失败,错误日志($HADOOP_HOME/logs/hadoop-root-datanode-*.log)里会明确出现com.obs.services.exception.ObsException,直接定位到 AK/SK 或 endpoint 问题。
3.3 权限校验三步法:AK/SK → endpoint → bucket policy
OBS 互联失败 80% 源于权限链断裂。按顺序排查:
- AK/SK 是否有效:登录华为云控制台 → “我的凭证” → “访问密钥” → 点击 AK 查看状态是否为“启用”。若已禁用,需重新创建。
- endpoint 是否匹配区域:在控制台打开 OBS 桶详情页,顶部地址栏显示的 URL 必须与
core-site.xml中fs.obs.endpoint完全一致(包括.myhuaweicloud.com后缀)。 - bucket policy 是否允许该 AK 访问:进入桶的“权限管理” → “桶策略”,确认 JSON 中
"Principal": {"AWS": ["acs:iam::xxx:user/roy_yuki"]}的 user 名与 AK 绑定的用户名一致(即roy_yuki)。若策略为空,则默认拒绝所有外部请求。
3.4hadoop fs -du查看 OBS 使用量:验证数据持久化而非临时缓存
很多初学者以为hadoop fs -ls能列出就代表通了,其实 OBS 数据可能只存在 Hadoop 客户端内存缓存里。用磁盘用量命令强制触发真实读取:
# 查看 OBS 桶总大小(单位字节) hadoop fs -du -s obs://hadoop-test-bucket/ # 查看 input 目录下每个文件大小 hadoop fs -du obs://hadoop-test-bucket/input/若返回0或报FileNotFoundException,说明 OBS 文件系统未真正挂载成功;若返回真实字节数(如12 obs://hadoop-test-bucket/input/test.txt),则证明数据已落盘且可被 HDFS API 访问。
4. Hadoop WordCount 实战:从本地文件到 OBS 输入/输出的全流程闭环
4.1 为什么 WordCount 是黄金验证?它同时压测 HDFS 本地读写 + OBS 远程读写
hadoop jar hadoop-mapreduce-examples-*.jar wordcount这个命令看似简单,实则串联了五大模块:1)客户端解析输入路径(hdfs://...或obs://...);2)ResourceManager 分配 Container;3)NodeManager 启动 Mapper;4)Mapper 从 HDFS/OBS 读取数据;5)Reducer 将结果写回 HDFS/OBS。任何一个环节断开,都会在 YARN Web UI(http://ecs-ca89-0001:8088)里看到 Application 状态卡在ACCEPTED或RUNNING但无日志。
4.2 本地输入 + OBS 输出:规避 HDFS 格式兼容性问题
实验报告中“执行 hadoop wordcount 成功”未说明输入输出路径。为降低复杂度,我们采用混合模式:输入用 HDFS 本地路径(避免 OBS 读取性能波动影响验证),输出强制写入 OBS。步骤如下:
# 1. 在 HDFS 创建输入目录并上传文本 hadoop fs -mkdir /wordcount/input echo "hello world hello hadoop" | hadoop fs -put - /wordcount/input/data.txt # 2. 运行 WordCount,输出到 OBS(注意:obs:// 后必须是桶名+路径,不能只写桶名) hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar \ wordcount /wordcount/input obs://hadoop-test-bucket/output/wordcount-result # 3. 查看 OBS 输出结果 hadoop fs -cat obs://hadoop-test-bucket/output/wordcount-result/part-r-00000预期输出:
hadoop 1 hello 2 world 1参数说明:
-jar后跟的是 Hadoop 自带的示例 JAR 包路径,版本号3.3.6需与你安装的 Hadoop 版本一致;obs://hadoop-test-bucket/output/wordcount-result是完整输出路径,末尾斜杠/表示目录,Hadoop 会自动创建;part-r-00000是 Reducer 输出的默认文件名。
4.3 日志定位技巧:YARN Container 日志比 Hadoop 日志更精准
当 WordCount 卡住时,别急着翻$HADOOP_HOME/logs/,直接查 YARN 的 Container 日志:
- 打开
http://ecs-ca89-0001:8088→ 点击失败的 Application ID → 点击Logs标签页; - 在
All Containers列表中,找到ContainerId以container_e开头的条目; - 点击
stdout,搜索关键词java.lang.Exception或Caused by:。
常见错误如java.io.IOException: Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.,说明mapred-site.xml中mapreduce.framework.name没设成yarn。
4.4 OBS 输出目录结构解析:理解 Hadoop 的 OutputCommitter 机制
WordCount 输出到 OBS 后,你会看到obs://hadoop-test-bucket/output/wordcount-result/下有三个文件:
part-r-00000:实际的词频结果;_SUCCESS:空文件,表示作业成功完成;_temporary:临时目录,作业运行中存放中间数据。
这个结构由FileOutputCommitter类控制。若_SUCCESS不存在,说明 Reducer 未完成提交,大概率是 OBS 写入权限不足或网络超时。此时检查yarn.nodemanager.env-whitelist是否包含HADOOP_CONF_DIR,否则 Container 无法加载core-site.xml中的 OBS 配置。
5. 避坑 / 常见问题 / 排查:血泪经验总结的五类高频翻车现场
5.1 现象:ssh node2提示Permission denied (publickey),但ssh root@192.168.0.53能通
原因:/etc/hosts中ecs-ca89-0002解析到了错误 IP,或者ssh-copy-id时目标节点的/root/.ssh/authorized_keys文件权限不是600(Hadoop 要求严格权限)。
解决:在 node2 上执行chmod 600 /root/.ssh/authorized_keys,并确认sshd_config中PubkeyAuthentication yes和AuthorizedKeysFile .ssh/authorized_keys未被注释。
5.2 现象:hadoop fs -ls obs://bucket-name/返回空列表,但控制台能看到文件
原因:OBS 桶开启了“多版本控制”,而 Hadoop OBS FileSystem 默认只读取最新版本(listObjectsAPI 不返回历史版本)。若你用控制台上传后又删除再上传同名文件,旧版本仍存在但 Hadoop 不识别。
解决:在 OBS 控制台关闭桶的“多版本控制”,或改用hadoop fs -ls -R obs://bucket-name/(递归列出,可能显示隐藏版本前缀)。
5.3 现象:YARN Web UI 显示 Application 状态为ACCEPTED,但 10 分钟无变化
原因:NodeManager 未启动,或yarn-site.xml中yarn.resourcemanager.hostname指向了localhost而非ecs-ca89-0001,导致 NodeManager 无法注册到 ResourceManager。
解决:在所有 datanode 节点(node2~node4)上执行yarn --daemon start nodemanager,并检查yarn-site.xml中<property><name>yarn.resourcemanager.hostname</name><value>ecs-ca89-0001</value></property>。
5.4 现象:hadoop fs -put上传大文件(>100MB)时超时,报java.net.SocketTimeoutException: Read timed out
原因:OBS 默认单连接上传超时为 30 秒,大文件需分片上传,但 Hadoop OBS FileSystem 的fs.obs.multipart.upload.threshold默认值太小(10MB),导致频繁触发 multipart,而fs.obs.multipart.upload.part.size默认 5MB,分片过多引发并发限制。
解决:在core-site.xml中增加:
<property> <name>fs.obs.multipart.upload.threshold</name> <value>104857600</value> <!-- 100MB --> </property> <property> <name>fs.obs.multipart.upload.part.size</name> <value>52428800</value> <!-- 50MB --> </property>5.5 现象:Spark 提交作业后报java.lang.ClassNotFoundException: org.apache.hadoop.fs.obs.OBSFileSystem
原因:Spark 未加载 Hadoop 的 OBS 依赖 JAR。Hadoop 的hadoop-aws-*.jar和jets3t-*.jar在$HADOOP_HOME/share/hadoop/tools/lib/下,但 Spark 默认 classpath 不包含此路径。
解决:在spark-defaults.conf中添加:
spark.hadoop.fs.obs.impl org.apache.hadoop.fs.obs.OBSFileSystem spark.extraClassPath /opt/hadoop/share/hadoop/tools/lib/hadoop-aws-3.3.6.jar:/opt/hadoop/share/hadoop/tools/lib/jets3t-0.9.4.jar并确保SPARK_DIST_CLASSPATH环境变量包含$HADOOP_HOME/etc/hadoop(用于加载core-site.xml)。
6. Spark 集群联动验证:用 Spark SQL 直查 OBS 中的 CSV,绕过 HDFS 中转
6.1 为什么 Spark SQL 比 MapReduce 更适合作为终态验证?
MapReduce 是批处理引擎,一次计算一个 Job;而 Spark SQL 是交互式查询引擎,它能将 SQL 编译成 DAG,在内存中流水线执行,对 OBS 的 IO 延迟更敏感。若 Spark SQL 能秒级返回SELECT COUNT(*) FROM obs_table,说明 OBS 读取链路(OBS → Spark Driver → Executor → OBS Client)完全通畅,且序列化/反序列化无异常。这比跑完一个 WordCount 更能证明“大数据平台可用”。
6.2 创建 Spark SQL 外部表:语法细节决定成败
在 Spark Shell 或spark-sqlCLI 中执行以下 DDL(注意:所有路径必须用obs://协议,且表属性fs.obs.impl必须显式声明):
-- 1. 创建数据库(可选,避免污染 default) CREATE DATABASE IF NOT EXISTS obs_db; USE obs_db; -- 2. 创建外部表,指定 OBS 路径和文件格式 CREATE EXTERNAL TABLE IF NOT EXISTS wordcount_result ( word STRING, count INT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE LOCATION 'obs://hadoop-test-bucket/output/wordcount-result/'; -- 3. 强制刷新元数据(关键!否则可能查不到新数据) REFRESH TABLE wordcount_result; -- 4. 查询验证 SELECT * FROM wordcount_result LIMIT 10;逻辑说明:
EXTERNAL TABLE表示数据物理位置在 OBS,Spark 不管理生命周期;ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'对应 WordCount 输出的 tab 分隔格式;REFRESH TABLE命令会触发 Spark 重新 list OBS 目录,否则可能缓存旧的文件列表。
6.3 Spark 配置参数表:生产环境必须调整的五个核心项
| 参数名 | 默认值 | 推荐值 | 作用说明 |
|---|---|---|---|
spark.sql.adaptive.enabled | false | true | 启用自适应查询执行,自动优化 Join 策略,应对 OBS 数据倾斜 |
spark.sql.files.maxPartitionBytes | 128MB | 256MB | 增大单 Partition 处理数据量,减少 Task 数量,降低 OBS List 操作频次 |
spark.hadoop.fs.obs.impl | 无 | org.apache.hadoop.fs.obs.OBSFileSystem | 显式绑定 OBS FileSystem,避免 ClassLoader 冲突 |
spark.serializer | org.apache.spark.serializer.JavaSerializer | org.apache.spark.serializer.KryoSerializer | Kryo 序列化比 Java 快 10 倍,减少 Executor 间数据传输耗时 |
spark.sql.hive.metastore.version | 2.3.0 | 3.1.2 | 若使用 Hive Metastore,版本必须与 Hadoop 3.3.6 兼容,否则CREATE TABLE报NoSuchMethodError |
6.4 从那以后我每次部署都强制走一遍spark-sql --master yarn --conf spark.sql.adaptive.enabled=true -e "SELECT 1"
这条命令能在 3 秒内完成 Spark Context 初始化、Driver 注册、Executor 启动、SQL 解析、物理计划生成、OBS 元数据探测、结果返回,全程无任何日志报错。它不产生业务价值,但能 100% 排除 Spark 与 OBS 的基础连通性问题。我把它写进deploy-check.sh脚本,作为 CI/CD 流水线的 gate step——只要这行命令失败,后面所有测试用例都不跑。因为比起花两小时 debugClassNotFoundException,不如用 3 秒确认环境底座是否健康。希望帮到你。
本文还有配套的精品资源,点击获取