news 2026/10/31 7:14:18

云上大数据实验:Hadoop集群搭建与Spark SQL查询

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
云上大数据实验:Hadoop集群搭建与Spark SQL查询

简介:《华为云大数据实验报告hhu》面向高校大数据课程学习者与华为云入门实践者,围绕云上大数据平台的部署与管理给出四组实验记录。内容从弹性云服务器ECS与对象存储OBS的环境准备切入,覆盖Hadoop集群搭建、节点SSH互通、关闭防火墙与OpenJDK安装,并延伸至云服务支撑的大数据流程、BigData Pro中Hadoop与Spark集群配置及OBS互联测试,最后落到Spark SQL等交互式查询的数据表创建与分析实践。资源包仅含1个docx文档,约4.36MB,目录按实验模块编排,便于对照操作与复盘关键配置。已有2542人学习,适合需要完成课程实验、梳理华为云大数据操作链路或查漏补缺的读者参考。

1. 云上大数据实验全景:从一台云主机到一条查询语句

在云上做 big data(大数据)和在本地机房做,差别不在于 Hadoop 本身,而在于资源从哪里来。这套实验把整条链路切成四段:先用云主机把集群跑起来,再用对象存储把数据放进去,接着用一站式大数据平台把部署过程缩短,最后用交互式查询把数据用起来。四段实验训练的知识点相同,都落在节点、网络、存储、计算、查询这条主线上,只是每一段替你解决一个具体麻烦:第一段解决“机器怎么来”,第二段解决“数据放哪”,第三段解决“部署能不能更快”,第四段解决“数据怎么问出答案”。

这套内容适合已经会用 Linux 基础命令、知道 HDFS 和 YARN 大概负责什么,但一上手就卡在“节点之间连不通”“密钥到底是什么”这类问题上的人。往下看,重点不要放在照着敲步骤上,应该放在每一步背后那条不能断的因果关系上:为什么私网 IP 写进 hosts、为什么不配 HADOOP_CONF_DIR 就会报错、为什么 namenode 只能格式化一次。把这条因果链记住,换一台机器、换一个区域,你照样能搭起来。

2. 资源准备:云主机、对象存储与访问密钥的三角关系

云上大数据的第一道关卡不在 Linux,而在资源模型。很多人在本地搭过伪分布式,觉得上云只是“把机器换成虚拟机”,结果第一步就卡住,因为没有分清三个东西各自负责哪一段:云主机负责计算和运行进程,对象存储负责放数据和结果文件,访问密钥负责“你凭什么能碰这个桶”。这三者组成一个三角形,缺一边或者配错边,后面的集群都搭不起来。

2.1 弹性云服务器:先定规格再定网络

买云主机(弹性云服务器,ECS)的时候,有几个参数需要先想清楚,不是随便点一下就买。

区域(Region)要先定。所有资源尽量放在同一个区域,因为你后面要买的的对象存储桶也在某个区域,跨区域访问会有额外的网络延迟,甚至因为权限策略不通而直接失败。实验里用到的 endpoint 形如obs.cn-north-4.myhuaweicloud.com,中间那段就是区域标识,区域选错,后面的链接一定对不上。

规格上,四节点的 Hadoop 集群,每台 2 vCPU / 4 GB 是能跑起来的下限;如果还要在同一批机器上跑 Spark 作业,namenode 那台建议提到 4 vCPU / 8 GB。磁盘 40 GB 起步,因为要放 JDK、Hadoop、Spark 三个压缩包加上解压后的目录,空间紧张的时候连解压都会失败。镜像选通用 Linux 发行版即可,关键是能正常使用yum或apt,并且默认带ssh服务。

网络这一步最容易含糊。四台机器放在同一个 VPC、同一个子网里,互相之间用私网 IP 通信。私网 IP 是192.168.x.x这种形式,只有同子网内互通;公网 IP 只在你用本地终端登录的时候用。这个区分在实验里被反复验证:/etc/hosts里写的一定是私网 IP,写公网 IP 会让节点间通信绕出云外,速度慢,还可能被安全组挡掉。

节点名私网 IP 示例承担角色
node1192.168.0.10NameNode、ResourceManager、SecondaryNameNode
node2192.168.0.53DataNode、NodeManager
node3192.168.0.169DataNode、NodeManager
node4192.168.0.77DataNode、NodeManager

还有一个容易忽略的点:云主机默认分配的私网 IP,在关机再开机之后不保证不变。做实验的当天最好一次开完四台,中途别关;如果确实要重启,重开之后先ip addr看一眼私网 IP 有没有变化,变了就同步改四台的/etc/hosts,不然集群会莫名其妙地少节点。

2.2 对象存储:桶、并行文件系统与 endpoint

对象存储(OBS)在实验里出现了两种形态,很多人把它们混为一谈,实际上语义完全不同。

普通桶是对象语义:里面存的是 key-value,通过 HTTP API 读写,适合放安装包、日志、最终结果文件。你在控制台点“创建桶”,填一个全局唯一的桶名,选好区域和访问策略,桶就建好了。桶名全局唯一这件事会带来一点麻烦:如果名字被别人占了,创建会直接失败,换一个带自己前缀的名字就行。

并行文件系统是 POSIX 语义:有目录树、能挂载到云主机上当成一块盘用,读写行为和本地文件系统接近。它更适合给 Hadoop、Spark 当共享存储,因为很多计算框架假设自己有目录、有文件句柄。两种形态各有用途,实验里“创建桶对象”和“创建并行文件系统”是并列出现的,别以为只是同一个东西换了两个入口。

endpoint 是访问入口,格式一般是obs.<区域>.<域名>。实验里还给出了一个双栈地址obs.dualstack.cn-north-4.myhuaweicloud.com,多出来的dualstack表示同时支持 IPv4 和 IPv6。这个地址要不要用,取决于你的集群网络是否开了 IPv6;没开就老老实实用普通地址,强行用双栈反而会解析失败。

提示:endpoint、桶名、区域这三样必须自洽。排查连通性问题时,先用一条不带任何密钥的请求确认域名能不能通,再去怀疑密钥。

# 只探测域名与网络连通性,不带任何凭证 curl -I https://obs.cn-north-4.myhuaweicloud.com # 返回 200 或 403 都说明网络和域名没问题(403 是没带凭证的正常拒绝) # 返回 Could not resolve host,基本可以判定区域写错或 DNS 没配

这条命令的价值在于分层:它把“网络通不通”和“密钥对不对”拆成两个独立问题。很多人一上来就怀疑 AK/SK 写错,折腾半天,最后发现是区域填错导致域名根本不存在。

2.3 访问密钥:AK/SK 到底在验证什么

地址解决了“往哪发请求”,密钥解决“凭什么让你发”。这两个是正交的,配错任意一个都会失败,但报错信息完全不同,这是排查时的分水岭。

在控制台创建访问密钥后,会下载到一个credentials.csv文件,里面三列:User Name、Access Key Id、Secret Access Key。Access Key Id 简称 AK,是身份标识,可以理解为用户名;Secret Access Key 简称 SK,是密钥,相当于密码。两者配对使用,只给 AK 不给 SK 是签不出请求的。

SK 有一个残酷的特性:只在创建时完整展示一次,页面关掉之后再也看不到,丢了只能删掉重建。所以拿到credentials.csv的第一件事是确认里面的内容完整,然后把它放到一个不会误提交的位置。

# 推荐做法:用环境变量注入,避免密钥写进代码或配置文件 export OBS_AK="你的Access Key Id" export OBS_SK="你的Secret Access Key" export OBS_ENDPOINT="obs.cn-north-4.myhuaweicloud.com" # 校验变量是否生效,注意不要 echo 出完整 SK echo "AK 长度: ${#OBS_AK} SK 长度: ${#OBS_SK}"

用环境变量的好处是密钥不落盘到项目目录,git status里不会突然冒出一个带密钥的配置文件。代价是每个新开的终端都要重新 export 一次,这一点在实验里会造成“刚才还能用,换个窗口就 403”的错觉,后面易错点那章会专门说。

还有一层容易漏:密钥对只是身份,权限是另一回事。如果这个用户所属的账号没有被授予目标桶的读写策略,密钥再正确也会被拒。现象是“认证通过但操作被拒绝”,和“认证失败”是两种不同的错误码,看到前者要去查权限策略,不要再去折腾密钥本身。

3. Hadoop 集群:四节点、互信与配置文件里的必改项

资源准备好之后,真正的集群搭建才开始。这一章是整份实验报告里内容最密的一段,因为它同时涉及主机名解析、免密登录、四个 XML 配置文件和一次性的格式化操作。任何一处没对上,start-dfs.sh跑完之后jps就会少进程,而且报错往往指向别处,非常考验按层排查的耐心。

3.1 节点规划与 /etc/hosts 的写法

四台机器的角色分配是固定的:node1 当主节点,跑 NameNode、ResourceManager、SecondaryNameNode;node2 到 node4 当从节点,跑 DataNode 和 NodeManager。这是单 NameNode 架构,没有高可用,对实验来说完全够用,但要知道它意味着 node1 挂了整个 HDFS 就不可用。

/etc/hosts的作用是让机器名和 IP 建立映射,Hadoop 的配置文件里到处写的是主机名而不是 IP,所以这份文件必须在四台上完全一致。

# 四台机器上都要写入同样的内容 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 2 node2

格式是「IP + 主机名」,行内用空格或 Tab 分隔,不要写成node1 192.168.0.10。写完立刻验证,别等到启动集群才发现解析不了。

这里有一个隐藏的坑:主机名必须和hostname命令的真实返回值一致。有些镜像默认主机名是一长串自动生成的字符串,而你在 hosts 里手写了node1,Hadoop 启动时 DataNode 会拿真实主机名去 NameNode 注册,两边对不上,结果就是 NameNode 起来了、DataNode 也起来了,但hdfs dfsadmin -report里一个存活节点都没有。补法是先hostname看一眼,再用hostnamectl set-hostname node1把真实主机名改成和 hosts 一致,改完重新登录生效。

同一批要做的还有两件基础工作。一是装 JDK,实验里用的是 OpenJDK,装完要确认JAVA_HOME指向正确,因为后面hadoop-env.sh里要显式写死这个路径。二是关防火墙,systemctl stop firewalld && systemctl disable firewalld,再把 SELinux 设成disabled并写进/etc/selinux/config,否则重启之后又会回来。这一步经常被当成走过场,但 NodeManager 和 DataNode 之间那些端口一旦被拦,症状就是进程在、端口不通。

3.2 SSH 免密互信:把四台机器变成一台

Hadoop 的主从架构依赖一个前提:主节点能免密登录到所有从节点,并且从节点之间最好也能互相免密。因为start-dfs.sh在 node1 上执行时,它要 SSH 到 node2、node3、node4 去拉起各自的守护进程。

原理很朴素:本地生成一对密钥,公钥追加到目标机器的~/.ssh/authorized_keys里,之后本地用私钥签名,对方用公钥验证,就不用输密码了。

# 在每台机器上生成密钥对,-N "" 表示不设密码短语 ssh-keygen -t rsa -b 2048 -N "" -f ~/.ssh/id_rsa # 查看生成结果,id_rsa 是私钥(绝不能外传),id_rsa.pub 是公钥 ls -l ~/.ssh/ # 把本机公钥复制到目标节点(会要求输一次目标机密码) ssh-copy-id node2

如果要四台两两互通,一共需要 12 次复制。手敲太累,可以套一层循环:

# 在每台机器上执行,把自己推给其它三台 for target in node1 node2 node3 node4; do if [ "$(hostname)" != "$target" ]; then ssh-copy-id -o StrictHostKeyChecking=no "$target" fi done

-o StrictHostKeyChecking=no的作用是跳过第一次连接时的指纹确认,否则每台都要手动输一次 yes。

验证方式是用ssh node2 "hostname"这种带命令的形式,如果直接返回node2而不问密码,就说明通了。别只看“没报错”,有些环境会卡在密码提示上,你没注意就以为成功了。

权限是这里最容易翻车的地方。~/.ssh目录必须是 700,authorized_keys必须是 600,id_rsa建议 600。权限松了,sshd 会直接忽略这个文件,表现就是“文件明明有内容,但还是要密码”。

chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_rsa

还有一点认知层面的混淆:实验报告里贴出来的那一长串以ssh-rsa开头的内容是公钥,不是私钥。公钥本来就可以公开,贴出来没问题;但如果你把id_rsa(没有.pub后缀的那个)当成公钥发出去或者写进 authorized_keys,那就直接把私钥泄了,而且互信也不会生效。

3.3 四个 XML 文件的最小改动集

Hadoop 的配置项有几百个,但实验里真正需要动的就那么几个。记住“最小改动集”比背下所有参数有用得多,因为剩下的都是默认值在起作用。

core-site.xml定两件事:默认文件系统是谁,以及临时目录放哪。

<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node1:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/hadoop/data/tmp</value> </property> </configuration>

fs.defaultFS写成hdfs://node1:9000,端口 9000 是约定俗成的,改成别的也能用,但要保证所有客户端配置一致。hadoop.tmp.dir决定了 NameNode 和 DataNode 的元数据、块文件落在哪,默认值在/tmp下面,机器一重启就可能被清空,所以一定要改成持久化目录。

hdfs-site.xml定副本数和数据目录:

<configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/opt/hadoop/data/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/opt/hadoop/data/datanode</value> </property> </configuration>

副本数 3 是 HDFS 的默认值,四个 DataNode 撑得住。如果实验环境只开了两个从节点,就得改成 2,否则 HDFS 会一直处于“副本不足”的告警状态,虽然能读写,但看着很别扭。

mapred-site.xml只有一行关键配置,告诉 MapReduce 跑在 YARN 上:

<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>

yarn-site.xml定 ResourceManager 的位置和 shuffle 服务:

<property> <name>yarn.resourcemanager.hostname</name> <value>node1</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>

mapreduce_shuffle这个名字必须一字不差,写成mapreduce-shuffle或者shuffle都会导致 Reduce 阶段卡死在 0%。

除了这四个文件,还有两处必须改。一是hadoop-env.sh里的JAVA_HOME,默认是注释掉的,不显式写死,启动时会报JAVA_HOME is not set。二是 workers 文件(老版本叫 slaves),里面每行一个从节点主机名,写node2、node3、node4,不要写 node1,主节点不承担 DataNode 角色。

改完之后,环境变量也别忘了:

# 追加到 /etc/profile 或 ~/.bashrc export HADOOP_HOME=/opt/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk

写完要source /etc/profile才生效,这一步漏掉的话,hadoop命令会提示 command not found,而你会以为安装失败。

3.4 格式化、启动与 wordcount 验证

配置齐了,接下来是一次性的格式化:

# 只在 node1 上执行,且整个集群生命周期内只执行一次 hdfs namenode -format

这条命令会在dfs.namenode.name.dir里生成一个 clusterID,DataNode 启动时靠这个 ID 认主。如果重复执行格式化,clusterID 会变,而已经跑过的 DataNode 目录里存的还是老 ID,两边对不上,DataNode 就拒绝启动,日志里会写Incompatible clusterIDs。

真遇到了怎么办?两条路:一是把每个 DataNode 的dfs.datanode.data.dir目录清空,让它们重新注册;二是把 NameNode 的目录也清掉,重新格式化一次。前者保数据但操作碎,后者简单但数据全丢。实验环境一般选后者,生产环境只能选前者。

启动顺序是先 HDFS 后 YARN,都在 node1 上执行:

start-dfs.sh start-yarn.sh # 用 jps 分别在四台机器上确认进程 jps

node1 上应该看到 NameNode、SecondaryNameNode、ResourceManager;node2 到 node4 上应该看到 DataNode 和 NodeManager。少哪个就去对应机器的logs目录翻日志,日志文件名里带角色名,很好找。

集群起来之后先做健康检查:

# 查看存活节点数、总容量、已用容量 hdfs dfsadmin -report

存活节点数应该是 3(三个 DataNode),如果显示 0,问题多半在 hosts 解析或者主机名不一致。确认没问题,再跑 wordcount 做端到端验证:

# 造一份输入数据并上传到 HDFS echo "hello hadoop hello spark hello bigdata" > /opt/data/words.txt hdfs dfs -mkdir -p /input hdfs dfs -put /opt/data/words.txt /input # 提交自带示例作业,注意 /output 目录必须不存在 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ wordcount /input /output # 查看结果 hdfs dfs -cat /output/part-r-00000

三个参数分别是输入路径、输出路径和作业名省略后的默认行为。输出目录如果已经存在,作业会直接报FileAlreadyExistsException,这不是 bug,是 MapReduce 的保护机制,防止误覆盖上一次的结果。删掉重跑或者换个输出目录名就行。

看到hello 3、hadoop 1这样的计数结果,说明 HDFS 读写、YARN 调度、MapReduce 执行三条链路全通了。这一步跑通,实验一的核心目标就算达成。

4. Spark 与存储打通:从离线计算到交互式查询

Hadoop 跑通之后,计算层的下一站是 Spark。它和 Hadoop 的关系不是替代,而是叠加:HDFS 继续当存储,YARN 继续当资源调度,Spark 只是换了一种计算引擎,把中间结果尽量放在内存里,迭代型作业的速度差距就出来了。这一章的重点有两个,一是 Spark 怎么挂到已有的 YARN 上,二是怎么让它读写云上的对象存储。

4.1 部署模式怎么选

Spark 有三种常见部署方式,选错会让后面所有配置都对不上。

local 模式是单机多线程,只适合验证代码逻辑,不涉及集群,实验里用它跑个spark-shell试试语法还行,正式作业不能这么跑。standalone 模式自带一套 Master/Worker 调度,不依赖 YARN,好处是独立、配置简单,坏处是集群里同时存在两套资源调度器,容易出现“YARN 觉得空闲、Spark 觉得没资源”的尴尬。on YARN 模式把资源申请交给 YARN,Spark 只作为客户端提交应用,这是实验里选的路子,也是把 Hadoop 集群利用率拉满的做法。

选 on YARN 之后,要理解一个前提:Spark 的安装包不需要装在每一个节点上,YARN 的 NodeManager 会在需要时把依赖分发下去。但spark-submit所在的机器必须能读到 YARN 和 HDFS 的配置,否则它不知道资源管理器在哪。

实际做法是把 Spark 装在 node1 上,同时把HADOOP_CONF_DIR指向 Hadoop 的配置目录,让它借用那份 XML。这样集群拓扑只有一份定义,改一处两边都生效。

4.2 spark-env.sh 与 spark-defaults.conf 的关键项

spark-env.sh管的是进程级的环境变量,spark-defaults.conf管的是应用级的默认参数,两者不要混着写。

# $SPARK_HOME/conf/spark-env.sh 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_LOCAL_IP=192.168.0.10

HADOOP_CONF_DIR是这里最关键的一行。不配它,spark-submit --master yarn会直接报找不到 YARN 配置,或者报Yarn application has already ended,让人以为是集群挂了,其实是客户端根本不知道去哪找 ResourceManager。SPARK_LOCAL_IP也要写私网 IP,不写的话 Spark 可能拿公网 IP 去注册,节点之间连不上。

spark-defaults.conf里几个参数值得手动写死:

spark.master yarn spark.submit.deployMode client spark.eventLog.enabled true spark.eventLog.dir hdfs://node1:9000/spark-eventlog spark.serializer org.apache.spark.serializer.KryoSerializer spark.driver.memory 1g spark.executor.memory 2g spark.executor.cores 2

deployMode选 client,driver 跑在提交作业的那台机器上,日志直接打在终端里,调试方便;选 cluster 则 driver 也在集群里,终端看不到输出,适合正式跑长作业。eventLog打开之后,作业历史可以在 History Server 里回看,排查失败原因时是唯一的现场记录。

内存参数要和机器规格对齐。executor.memory设成 4g 而节点只有 4 GB 物理内存,YARN 会因为超出yarn.nodemanager.resource.memory-mb而拒绝分配容器,表现出来就是作业一直停在 ACCEPTED 状态、进度条不动。这时候要去 YARN 的资源页面看可用内存,别在 Spark 侧反复改参数。

启动之后先用spark-shell --master yarn验证一下,能进去并且sc.master返回yarn,说明客户端和集群接上了。

4.3 读写对象存储的两种接法

Spark 要处理的数据很多时候不在 HDFS 上,而在对象存储里。这一步是实验里“测试与 OBS 互联”对应的内容,有两种接法,适用场景不同。

第一种是 s3a 直连。对象存储兼容 S3 协议,Spark 通过 Hadoop 的 s3a 文件系统直接读写,不需要额外挂载。

# 在 spark-defaults.conf 或提交时用 --conf 传入 spark.hadoop.fs.s3a.access.key 你的AK spark.hadoop.fs.s3a.secret.key 你的SK spark.hadoop.fs.s3a.endpoint obs.cn-north-4.myhuaweicloud.com spark.hadoop.fs.s3a.path.style.access true

path.style.access这一项容易被漏掉。默认是虚拟主机风格(bucket.endpoint),但很多对象存储实现要求路径风格(endpoint/bucket),不开这一项会解析到错误的地址,症状是域名解析失败而不是权限错误。配好之后先用命令行验证:

# 用 hadoop 命令列一下桶里的内容,能列出来说明鉴权和端点都对 hadoop fs -ls s3a://你的桶名/

第二种是把并行文件系统挂载到本地目录,Spark 直接按普通路径读写。这种接法的好处是完全不用改配置,/mnt/obs/data对 Spark 来说就是个本地目录;坏处是多了一层挂载,性能和一致性取决于挂载实现,大批量随机写不如走 HDFS。

# 走 s3a 直连的读写示例 df = spark.read.csv("s3a://你的桶名/input/words.csv", header=True) df.createOrReplaceTempView("words") result = spark.sql(""" SELECT word, COUNT(*) AS cnt FROM words GROUP BY word ORDER BY cnt DESC LIMIT 10 """) # 结果写回对象存储,coalesce(1) 让它输出单个文件方便查看 result.coalesce(1).write.mode("overwrite").csv("s3a://你的桶名/output/top10")

coalesce(1)的含义是把分区数降到 1,避免输出目录里散着一堆part-00000小文件。代价是大数据量时会退化成单任务,只适合看结果,不适合生产。

4.4 交互式查询:Spark SQL 的最小闭环

综合实验四讲的是大数据交互式查询,落到工具上就是 Spark SQL。它不是另一个系统,而是 Spark 之上的一层 SQL 接口,底层还是同一套执行引擎。

最小闭环是三步:建表、查询、看结果。建外部表的好处是删表不删数据,反复实验的时候不用每次重新上传。

-- 建一张指向 HDFS 目录的外部表,字段按分隔符切分 CREATE EXTERNAL TABLE IF NOT EXISTS access_log ( ip STRING, url STRING, status INT, bytes BIGINT ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION 'hdfs://node1:9000/warehouse/access_log';

LOCATION要指到具体目录,不是文件路径;目录里可以放多个文件,Spark 会全部当成分区数据读进来。FIELDS TERMINATED BY必须和数据文件里的分隔符一致,逗号写成竖线,查出来所有字段就都是 NULL。

查询可以用spark-sql交互式敲,也可以通过spark.sql()在代码里执行:

# 交互式进入,自带 SQL 补全和历史 spark-sql --master yarn
-- 按状态码分组看流量分布 SELECT status, COUNT(*) AS req_cnt, SUM(bytes) AS total_bytes FROM access_log GROUP BY status ORDER BY req_cnt DESC;

结果对不对,先看行数,再看聚合值。行数明显偏少,多半是分隔符切分后部分行字段数不够被丢弃;聚合值明显偏大,多半是重复读了一个目录下的多个副本文件。

如果要把查询结果开放给外部工具,可以起一个 Thrift Server,用 JDBC 连进来,这一步实验里没有展开,但知道有这条路就够了。

5. 易错点清单:五个一跑就翻车的地方

前面三章讲的是“应该怎么做”,这一章讲“实际做的时候会怎么错”。这些点有个共同特征:报错信息指向的地方,往往不是真正出问题的地方。所以每条都按「易漏点 → 为什么漏 → 怎么补」的结构展开,重点是最后那一步。

5.1 区域与 endpoint 对不上,密钥再对也白搭

易漏点:桶建在 A 区域,endpoint 写的是 B 区域,或者 endpoint 拼错一个字符。

为什么漏:这类错误在控制台侧是看不出来的,桶明明建好了,AK/SK 也是刚下载的,人的第一反应永远是“密钥是不是贴错了”。而且报错信息通常只有一句访问失败,不告诉你是域名解析的问题。

怎么补:排查顺序固定成三步。第一步curl -I探测 endpoint 域名能不能解析,解析失败就是区域写错或者网络不通;第二步用hadoop fs -ls s3a://桶名/验证鉴权,认证失败和权限不足是两种错误码;第三步才去核对 AK/SK。把这个顺序固化下来,能省掉绝大多数瞎折腾。

5.2 免密互信看着做了,其实没生效

易漏点:authorized_keys写进去了,但目录权限 755、文件权限 644。

为什么漏:文件内容是对的,cat出来能看见公钥,视觉上完全正常。sshd 的判断依据是权限,不是内容,权限太松它会静默忽略整个文件,不报任何错。

怎么补:复制完立刻跑一遍权限修正,再用带命令的 ssh 验证,而不是只ssh node2看它连不连。看到密码提示,第一件事就是查这三个权限位:.ssh700、authorized_keys600、id_rsa600。另外要分清公钥和私钥,ssh-rsa开头的是公钥,可以到处贴;没有.pub后缀的是私钥,贴出去就是事故。

5.3 重复格式化 NameNode,集群再也起不来

易漏点:集群起不来,习惯性再跑一次hdfs namenode -format,越跑越坏。

为什么漏:格式化看起来像“重置”,直觉上应该能修好一切,实际上每次格式化都会生成新的 clusterID,而 DataNode 目录里存的还是旧 ID,两边不匹配就互相拒绝。

怎么补:把“只格式化一次”当成铁律。真需要重来,要么清空每台机器的 DataNode 数据目录让它重新注册,要么把 NameNode 目录也清掉重新格式化。判断依据在日志里,看到Incompatible clusterIDs就说明是这个问题,别再重复格式化。

5.4 集群起来了,作业却一直停在 ACCEPTED

易漏点:jps显示进程齐全,HDFS 也能读写,但 Spark 作业提交后卡在 ACCEPTED 不动。

为什么漏:进程在运行不代表资源够用。YARN 能分配的内存和每个节点实际物理内存是两码事,spark.executor.memory设得比节点可用内存大,容器申请永远满足不了,作业就一直排队。

怎么补:先去 YARN 的资源页面看可用内存和可用 vcore,再回头调 Spark 的 executor 参数。经验值是单节点可用内存留 1 GB 给系统,剩下的才是 YARN 能分配的。另外别忽略内核参数,vm.overcommit_memory设得太保守也会让容器申请被拒。

5.5 环境变量只在当前终端生效

易漏点:export完命令能用了,换个终端窗口又报 command not found。

为什么漏:export是会话级的,关掉就没了。而实验里经常要开多个窗口,一个跑spark-submit,一个看日志,另一个改配置,很容易在“这个窗口能用那个不能用”的状态里打转。

怎么补:所有需要长期生效的变量写进/etc/profile.d/下的独立脚本,或者写进~/.bashrc,写完source一次,然后新开一个终端验证。判断标准是“新窗口里echo $HADOOP_HOME有输出”,不是当前窗口能用就行。密钥类变量更要注意,别为了图省事写进全局 profile,那是把 SK 明文摊在所有用户面前。

6. 复习清单:一条能自己跑通的自测路径

复习这份实验报告,别从第一页翻到最后一页,那样只会把步骤又看一遍。更有效的做法是按“能不能跑通”来验收,每一项都有一个可执行的判断命令,跑通了打勾,跑不通就回到对应章节。

阶段验收动作通过标准对应章节
资源curl -I https://obs.<区域>.<域名>返回 200 或 4032.2
资源hadoop fs -ls s3a://桶名/能列出目录内容2.3
网络四台机器互ping主机名全部可达3.1
互信ssh node2 "hostname"返回 node2 且不问密码3.2
HDFShdfs dfsadmin -report存活节点数等于 DataNode 数3.4
计算wordcount 作业 SUCCEEDED输出目录有 part-r-000003.4
Sparkspark-shell --master yarn后sc.master返回 yarn4.2
查询SELECT COUNT(*) FROM 表名行数与源数据一致4.4

具体操作上,我建议分三轮,每轮只关注一个维度,不要把网络、配置、计算混在一起查。

第一轮只查“通不通”。四台机器互 ping、互 ssh、endpoint 能 curl 通、对象存储能 ls 出来。这一轮全部用命令行验证,不看控制台,因为控制台显示“运行中”不代表端口通。

第二轮只查“配置对不对”。把四个 XML 文件、hadoop-env.sh、spark-env.sh、spark-defaults.conf挨个打开,逐项对照最小改动集。重点核三样:主机名和/etc/hosts一致、JAVA_HOME是绝对路径且真实存在、HADOOP_CONF_DIR指向 Hadoop 配置目录而不是安装根目录。

第三轮只查“结果对不对”。跑 wordcount 看计数、跑一个GROUP BY看聚合值、把结果写回对象存储再看一遍。这一轮的意义是端到端,任何一环断开都会在这里暴露。

# 一条命令做完整健康检查,粘到 node1 上直接跑 hdfs dfsadmin -report | head -20 && \ yarn node -list && \ hdfs dfs -ls / && \ echo "--- 三步都无报错说明存储与调度层是健康的 ---"

三个命令分别对应 HDFS 节点状态、YARN 节点状态、HDFS 根目录可读。前两个看的是“集群在不在”,第三个看的是“权限对不对”。如果前两个正常、第三个报权限错误,问题在用户身份而不是集群。

最后说一个自己的教训。我刚开始做这类实验的时候,习惯把四台机器一口气全开好,然后从第一步开始按顺序敲,中间不验证。结果经常是敲到第七八步才发现第一步的 hosts 就写错了,前面全白做,还得回头排查是哪一步开始偏的。从那以后我每次动配置之前都强制走一遍“改一处、验一处”,hostname改完立刻ping,authorized_keys写完立刻ssh,XML 改完立刻hdfs dfsadmin -report。看起来慢,实际快得多,因为错误永远停在最小范围内。希望帮到你。

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

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

Hadoop集群搭建排错:JAVA_HOME、SSH互信与OBS接入避坑

简介&#xff1a;《鲲鹏云大数据实验docx》是一份面向大数据初学者、云计算实验课程学生及需要完成华为云Hadoop集群部署实践者的实验报告。文档围绕鲲鹏云环境下的完整建链过程展开&#xff0c;涵盖ECS与OBS购买配置、AK/SK获取、节点互信与SSH免密、Hadoop安装包分发、core-s…

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

图形学作业0虚拟机环境排错:从挂载、增强功能到编译运行

简介&#xff1a;这份PDF文档对应GAMES101计算机图形学课程作业0&#xff0c;由闫令琪授课&#xff0c;面向刚接触图形学编程、需要搭建统一开发环境的学习者&#xff0c;重点解决虚拟机配置与作业框架运行的环境准备问题。全文围绕VirtualBox安装、虚拟硬盘挂载、Guest Additi…

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

UML系统分析与设计复习指南:多重度、交互图与GRASP高频考点

简介&#xff1a;面向备考UML系统分析与设计课程的学生及刚接触面向对象建模的开发者&#xff0c;这份复习试题文档围绕统一建模语言在系统分析与设计中的应用组织内容&#xff0c;可用于课程复习、考前自测与知识点查漏补缺。压缩包共1个doc文件&#xff0c;约132KB&#xff0…

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

ThingsBoard Gateway接入OPC-UA实战:从节点映射到可查可告警数据

简介&#xff1a;本资源是一份面向工业物联网开发者与自动化工程师的实操型技术文档&#xff0c;聚焦ThingsBoard Gateway与OPC-UA协议的端到端集成方案&#xff0c;解决工业现场设备如何安全、跨平台接入云端平台的核心问题。文档以KEPServerEX6模拟OPC-UA服务端、UaExpert作为…

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

【轻量化复刻大模型】Linear Attention 与 Sparse Attention 梳理

目录 【轻量化复刻大模型】Linear Attention 与 Sparse Attention 梳理 0x00 概要 0.1 新系列 0.2 注意力 0x01 总览&#xff1a;两条路线到底在压缩什么 1.1 Full Attention 的特色 1.2 差别 1.3 深度思考&#xff1a;三条压缩轴 1.3.1 token 序列轴 1.3.2 hidden‑dim 通道轴…

作者头像 李华