ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

华为云四节点Hadoop+Spark+OBS大数据实验环境搭建

华为云四节点Hadoop+Spark+OBS大数据实验环境搭建

简介:面向高校大数据与云计算课程实验及华为云入门实践的实验报告文档,围绕云主机与云服务两条路径组织内容,帮助读者理解在华为云上搭建与管理大数据平台的关键操作。包内共1个docx文件,压缩包约4.36MB,正文以图文步骤、命令记录和配置说明为主,覆盖ECS与OBS配置、Hadoop集群搭建、节点通信测试、Spark集群部署及交互式查询等实验环节。目录按实验一、实验二、综合实验一和综合实验四划分,包含环境准备、购买ECS与OBS、集群配置、测试与OBS互联等模块,便于按实验进度检索和复盘。已有2607人学习,适合课程实验对照、云平台操作练习与大数据集群部署入门参考;也可据此核对节点配置、密钥与存储桶设置,梳理从环境准备到查询验证的完整实验链路。

1. 从四台虚拟机到四台云主机:一套能跑通 Hadoop、Spark 与 OBS 的实验底座

华为云上做 big data 大数据实验,最容易出问题的地方并非敲命令,而在环境准备:本地开四台虚拟机,宿主机 16G 内存跑到一半就开始换页,NameNode 和 DataNode 抢同一个 CPU 核,jps出来少一个进程,你根本分不清是配置错了还是机器扛不住。这份实验报告资源解决的就是这件事——把 ECS 云主机、OBS 对象存储、Hadoop 集群、Spark 集群和交互式查询串成一条完整链路,四台机器跑在云上,宿主机只留一个浏览器。适合两类人:一是要交课程实验、需要一份能对着改参数的报告骨架的;二是想把“云上 Hadoop 到底和本地差在哪”这件事一次性搞明白的。四个实验递进关系很清楚,先单机通,再多机通,最后接对象存储和 SQL 查询。

2. 云上底座对号入座:ECS 规格、OBS 桶类型与 AK/SK 的最小权限

2.1 四台 ECS 的规格怎么分,才不至于跑到 YARN 就 OOM

实验报告里是 node0001 到 node0004 四台,但四台不应该一个规格。NameNode 要扛 fsimage 和 editlog,ResourceManager 要维护全集群的资源账本,Spark Master 还要在这里起,这台机器的内存必须留余量;另外三台只跑 DataNode、NodeManager 和 Spark Worker,2 核 4G 够用。常见做法是 1 台 4 核 8G 加 3 台 2 核 4G,系统盘统一 40G 起步,因为要放 JDK、Hadoop、Spark 三套包,再加上 HDFS 的hadoop.tmp.dir和 Spark 的临时目录,40G 很容易在跑两轮wordcount之后告急。

节点角色建议规格系统盘必须放通的端口
node0001NameNode / ResourceManager / Spark Master4 核 8G60G22、9000、9870、8088、7077、8080
node0002DataNode / NodeManager / Spark Worker2 核 4G40G22
node0003DataNode / NodeManager / Spark Worker2 核 4G40G22
node0004DataNode / NodeManager / Spark Worker2 核 4G40G22

端口这一列是给安全组用的,四台机器放同一个 VPC、同一个子网,内网默认互通,但 9870(HDFS Web UI)、8088(YARN Web UI)、8080(Spark Master UI)这几个你想在本地浏览器里看,就得给 node0001 绑一个弹性公网 IP,再在安全组里按源 IP 放行。别图省事写 0.0.0.0/0,集群刚搭好就被扫端口是常有的事。

还有个细节:dfs.replication在四节点集群里设 3 是合理的,但如果你把副本数设成 4,DataNode 只有 3 台活着的时候,hdfs dfsadmin -report会一直报 under-replicated blocks,看起来像集群坏了,其实只是副本数比可用节点多。实验报告里没有强调这一点,但这是新手第一个会怀疑人生的地方。

2.2 OBS 桶类型选错,后面 rename 会慢到怀疑人生

OBS 是对象存储,没有真正的目录概念,obs://bucket/a/b/c里的/只是 key 的一部分。这件事直接决定了 HDFS 和 OBS 的行为差异:HDFS 的rename是元数据操作,毫秒级;普通对象存储桶的rename在底层是 copy 加 delete,一个大目录改名可能要几分钟。所以实验里如果只是把wordcount的输出distcp到 OBS 做归档,普通桶完全够用;但如果你打算让 Spark 直接把 OBS 当 warehouse 目录,中间会不断产生_temporary目录的 rename,那就该在建桶时选并行文件系统类型。

维度普通对象存储桶并行文件系统桶
目录语义key 前缀模拟,无真实目录接近 POSIX,目录操作开销低
rename 大目录copy + delete,耗时长元数据级操作,快
适合场景归档、备份、distcp 落地Spark/Hive warehouse、频繁写临时目录
访问方式obsutil、SDK、Hadoop 插件同上,另可挂载为本地文件系统

建桶的时候桶名要全局唯一,区域选和你 ECS 同一个区域,因为跨区域的 endpoint 不一样,填错了后面hadoop fs -ls obs://会直接 403,这个坑在第 5 章会细说。

2.3 AK/SK 拿到手的第一件事:别写进任何会被提交的文件

创建访问密钥之后,页面只会给你一次 Secret Access Key,关掉就再也看不到,只能重建。实验报告里通常会让你把credentials.csv存下来,但这份 csv 绝对不能进 Git 仓库,也不能贴在实验报告的正文里——报告是要交上去的,密钥跟着报告一起流转,等于把桶的读写权限发出去了。

我的习惯是用环境变量加obsutil的配置文件双轨走,命令行里只出现变量名:

# 把 AK/SK 写进当前 shell 的环境变量,不落盘到脚本里 export OBS_AK="<your-access-key-id>" export OBS_SK="<your-secret-access-key>" export OBS_ENDPOINT="obs.cn-north-4.myhuaweicloud.com" # obsutil 初始化,配置文件默认落在 ~/.obsutilconfig ./obsutil config -i="$OBS_AK" -k="$OBS_SK" -e="$OBS_ENDPOINT" # 验证:能列出桶说明 AK/SK 和 endpoint 都对了 ./obsutil ls obs://your-bucket-name/

-i和-k分别对应 Access Key Id 和 Secret Access Key,-e是区域 endpoint,必须和你建桶时选的区域一致。obsutil config执行成功后会打印一行Config file url is ...,路径记住,后面排查权限问题时先看这个文件里的 endpoint 有没有写错。obsutil ls返回桶列表就说明鉴权通了,如果报AccessDenied,九成是 AK/SK 复制时多了空格或者少了字符,重新生成一对再试,别在原 key 上反复折腾。

这一步做完,云上底座就有了:四台机器能互相通,一个桶能读写。接下来才是真正吃时间的部分。

3. 四节点 Hadoop 集群:hosts、四机互信与四个 XML 的最小可用配置

3.1 系统层三件事:hostname、hosts、防火墙与 JDK

四台机器的 hostname 必须先统一,因为 Hadoop 的配置文件里写的是主机名不是 IP,hostname 不一致会导致 DataNode 注册上来之后 NameNode 认不出它是谁。华为云的 ECS 默认主机名是一串实例 ID,改成 node0001 到 node0004,然后四台的/etc/hosts写成完全一样的内容:

# 四台机器都执行,内容必须完全一致 sudo hostnamectl set-hostname node0001 # 其余三台改成 node0002/0003/0004 sudo tee -a /etc/hosts <<'EOF' 192.168.0.11 node0001 192.168.0.12 node0002 192.168.0.13 node0003 192.168.0.14 node0004 EOF # 关防火墙,四台都执行;云上安全组才是真正的边界 sudo systemctl stop firewalld sudo systemctl disable firewalld

hostnamectl set-hostname只改运行时主机名,/etc/hosts里的映射才是解析依据,两处必须对得上。防火墙这一条在云上其实是双保险——真正的流量控制靠安全组,但firewalld默认会拦掉 9000、9870 这些端口,新手排查时容易漏,索性关掉,把边界交给安全组。

JDK 用 OpenJDK 8,四台装同一个路径,后面所有配置文件里的JAVA_HOME才能统一:

# 四台都执行,安装 OpenJDK 8 sudo yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel # 确认路径,一般是 /usr/lib/jvm/java-1.8.0-openjdk readlink -f $(which java)

readlink -f出来的路径去掉末尾的/bin/java就是JAVA_HOME。别用which java直接取,那个是软链接,Hadoop 启动脚本解析时会出问题。

3.2 SSH 免密互信:四台互信,不是只信 node0001

Hadoop 的启动脚本是从 node0001 通过 SSH 去拉起其他节点的守护进程,所以 node0001 必须能免密登录 node0002 到 node0004。但很多实验只做了单向,结果start-dfs.sh起来了,stop-dfs.sh停不掉,因为停止脚本走的是另一条路径。稳妥做法是四台互相都能免密,一共 4×3 条链路,用循环一把梭:

# 每台机器先生成自己的密钥对,-N '' 表示空密码 ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa # node0001 上收集四台的公钥,汇总成一个 authorized_keys for h in node0001 node0002 node0003 node0004; do ssh $h 'cat ~/.ssh/id_rsa.pub' >> /tmp/all_keys done # 把汇总后的文件分发到四台,权限必须收紧 sort -u /tmp/all_keys > ~/.ssh/authorized_keys chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys for h in node0002 node0003 node0004; do scp ~/.ssh/authorized_keys $h:~/.ssh/authorized_keys done

chmod 700 ~/.ssh和chmod 600 ~/.ssh/authorized_keys这两行不能省。SSH 对权限极其敏感,authorized_keys如果是 644,服务端会直接忽略这个文件,表现就是“明明公钥在里面,还是要输密码”。验证方式是四台分别ssh node0001到ssh node0004全跳一遍,全部无交互才算过。第一次连会有 fingerprint 确认,输一次 yes 就行。

3.3 四个 XML 的最小可用配置

Hadoop 3.x 的配置文件在$HADOOP_HOME/etc/hadoop/下,真正要改的是core-site.xml、hdfs-site.xml、yarn-site.xml,外加hadoop-env.sh里的JAVA_HOME。下面这套是四节点、单 NameNode 的最小可用版本:

<!-- core-site.xml:全局默认文件系统和临时目录 --> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node0001:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/module/hadoop-3/data/tmp</value> </property> </configuration>

fs.defaultFS写主机名不写 IP,这样后面换机器只改 hosts 就行。hadoop.tmp.dir一定要显式指定,默认值在/tmp下,机器重启可能被清空,NameNode 的元数据跟着没,集群直接起不来——这是最典型的一次性事故。

<!-- hdfs-site.xml:副本数、元数据目录、DataNode 数据目录 --> <configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///opt/module/hadoop-3/data/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///opt/module/hadoop-3/data/data</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>node0002:9868</value> </property> </configuration>

副本数 3 对应四节点里坏一台还能读。SecondaryNameNode 放到 node0002 上,别和 NameNode 挤一台,它的作用是合并 editlog,和 NameNode 抢内存没好处。

<!-- yarn-site.xml:ResourceManager 地址和 shuffle 服务 --> <configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>node0001</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>3072</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>3072</value> </property> </configuration>

yarn.nodemanager.resource.memory-mb是每个 NodeManager 能给容器分的物理内存上限,2 核 4G 的机器设 3072 比较稳,因为系统本身、DataNode、NodeManager 自己都要占。设成 4096 的后果是容器一启动就被内核 OOM Killer 干掉,日志里只有一行Container killed on request,看不出根因。

3.4 格式化、启动与 jps 对不上的排查顺序

配置分发到四台之后,只在 node0001 上格式化一次:

# 只在 node0001 执行,且只执行一次 hdfs namenode -format # 启动 HDFS 和 YARN start-dfs.sh start-yarn.sh # 四台分别看进程,node0001 应有 NameNode/ResourceManager # node0002~0004 应有 DataNode/NodeManager,node0002 另有 SecondaryNameNode jps

hdfs namenode -format这条命令在一套集群上只能成功执行一次。第二次执行会重新生成一个 clusterID,而 DataNode 的 VERSION 文件里还是旧的 clusterID,结果是 NameNode 起来了、DataNode 全起不来,日志里报Incompatible clusterIDs。真要重来,得把dfs.namenode.name.dir和dfs.datanode.data.dir指向的目录全删掉再格式化,只删 NameNode 那边不够。

jps输出对不上时按这个顺序看:先看 node0001 有没有 NameNode,没有就翻$HADOOP_HOME/logs/hadoop-*-namenode-*.log的前 50 行,八成是JAVA_HOME没配对;NameNode 有但 DataNode 少,去对应机器看 DataNode 日志里的 clusterID 和端口占用;全都起来了但hdfs dfsadmin -report显示 Live datanodes 是 0,那是 hosts 或者 9000 端口不通,回 3.1 检查。

集群起来之后跑一遍自带例子验证,输入输出都走 HDFS:

# 建输入目录,把本地 etc/hadoop 下的 xml 传上去当测试数据 hdfs dfs -mkdir -p /user/root/wordcount/input hdfs dfs -put $HADOOP_HOME/etc/hadoop/*.xml /user/root/wordcount/input # 跑 wordcount,输出目录不能预先存在 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \ wordcount /user/root/wordcount/input /user/root/wordcount/output # 看结果 hdfs dfs -cat /user/root/wordcount/output/part-r-00000 | head

hadoop jar后面那个 jar 包路径带通配符,是因为不同小版本号文件名不一样,用*让 shell 自己展开。输出目录如果已存在,任务会直接抛FileAlreadyExistsException退出,删掉重跑就行,别以为是集群坏了。

4. 打通 OBS 与 Spark:插件落位、endpoint 填写与 spark-sql 读 Parquet

4.1 hadoop-huaweicloud 插件放哪,决定了后面所有报错

Hadoop 原生不认识obs://这个 scheme,必须靠 OBS 的 Hadoop 插件把OBSFileSystem注册进去。插件是一个 jar 包,放的位置有讲究:放到$HADOOP_HOME/share/hadoop/common/lib/下,四台都要放,因为任何一个节点都可能成为任务的执行端。只放 node0001 的后果是提交任务时正常,一到 map 阶段就报No FileSystem for scheme "obs"。

放好之后在core-site.xml里追加六项配置:

<!-- core-site.xml 追加,和原有配置并列 --> <configuration> <property> <name>fs.obs.impl</name> <value>org.apache.hadoop.fs.obs.OBSFileSystem</value> </property> <property> <name>fs.obs.access.key</name> <value>${env.OBS_AK}</value> </property> <property> <name>fs.obs.secret.key</name> <value>${env.OBS_SK}</value> </property> <property> <name>fs.obs.endpoint</name> <value>obs.cn-north-4.myhuaweicloud.com</value> </property> <property> <name>fs.obs.connection.ssl.enabled</name> <value>true</value> </property> <property> <name>fs.obs.buffer.dir</name> <value>/opt/module/obs-buffer</value> </property> </configuration>

fs.obs.impl是固定值,不用改。fs.obs.access.key和fs.obs.secret.key这里用了${env.OBS_AK}的写法,意思是让 Hadoop 从环境变量里读,好处是配置文件可以进版本库而密钥不进;代价是四台机器的环境变量都得配,而且启动脚本要能继承到——如果你在~/.bashrc里 export,用start-dfs.sh起的进程能读到,用 systemd 托管就读不到。图省事可以直接写明文,但那份core-site.xml就别外传了。fs.obs.endpoint必须和桶的区域一致,桶在华北就写华北的,写错区域的表现是 403 而不是 404,很容易误判成权限问题。fs.obs.buffer.dir是本地缓冲目录,大文件上传时会先落这里再分片,目录必须存在且可写。

4.2 连通性验证:先 ls,再 distcp,最后才轮到 Spark

配置改完不用急着重启集群,hadoop fs命令每次都会重新读配置。按三步验证,每步失败的原因都不一样:

# 第一步:能不能列出桶根目录,验证鉴权和 endpoint hadoop fs -ls obs://your-bucket-name/ # 第二步:本地到 OBS 的小文件上传,验证写权限 echo "hello obs" > /tmp/t.txt hadoop fs -put /tmp/t.txt obs://your-bucket-name/demo/ # 第三步:HDFS 到 OBS 的目录级拷贝,验证大文件分片 hadoop distcp /user/root/wordcount/output obs://your-bucket-name/demo/wordcount

第一步报AccessDenied或 403,先看 endpoint,再看 AK/SK 里有没有混进空格。第二步报Permission denied,是桶策略或者 IAM 权限只给了读没给写。第三步跑到一半失败,多半是fs.obs.buffer.dir所在磁盘满了,distcp默认会开多个 map 并发拷贝,每个都要占缓冲。

distcp默认是覆盖模式,同名文件直接盖掉,不会问你。做实验的时候我一般先加-update只同步新增和变化的文件,避免把之前跑好的结果覆盖成半成品。

4.3 Spark 集群:spark-env.sh 里真正影响跑不跑得起来的三行

Spark 装在 node0001,配置好之后用自带的sbin/start-all.sh拉起 Master 和 Worker。spark-env.sh里有三行是决定性的:

# 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=node0001 # Worker 资源,按 2 核 4G 的机器留余量 export SPARK_WORKER_CORES=2 export SPARK_WORKER_MEMORY=3g

HADOOP_CONF_DIR这行是最容易被漏掉的——不配它,Spark 读不到core-site.xml里那套 OBS 配置,spark-sql里一碰obs://就报 scheme 不存在。SPARK_MASTER_HOST写主机名,写localhost的话 Worker 注册不上。另外,Spark 自己的$SPARK_HOME/jars/目录下也得放一份 hadoop-huaweicloud 的 jar,因为 Spark 的类加载器只扫自己的 jars 目录和HADOOP_CONF_DIR能提供的东西,Hadoop 那边的 lib 目录它不看。

workers文件里写 node0002 到 node0004,一行一个,然后start-all.sh。起来之后访问http://node0001:8080看 Worker 数量,三个 Alive Workers 才算正常。

4.4 交互式查询:spark-sql 直接读 OBS 上的 Parquet

到这一步,数据已经在 OBS 上了,交互式查询最省事的路径是spark-sql直连,不经过 Hive Metastore:

-- 启动方式:spark-sql --master spark://node0001:7077 -- 建外部表指向 OBS 上的 parquet 目录,只登记元数据不搬数据 CREATE TABLE page_view ( user_id STRING, page STRING, ts BIGINT ) USING parquet LOCATION 'obs://your-bucket-name/warehouse/page_view'; -- 交互式查询,Spark 会把过滤条件下推 SELECT page, COUNT(*) AS pv FROM page_view WHERE ts >= 1700000000 GROUP BY page ORDER BY pv DESC LIMIT 10;

USING parquet指定文件格式,LOCATION指向 OBS 路径。建表是元数据操作,秒级完成,不会触发数据搬迁。查询时 Spark 会把WHERE ts >= ...这类条件下推到扫描层,只读需要的 parquet row group,这是它比全表扫快的原因。

spark-sql默认是 local 模式启动的,加--master spark://node0001:7077才会把任务分发到三个 Worker 上。不加也能跑,但只在 node0001 单机上跑,四台机器的资源白搭,查询大表时会明显感觉到慢。

5. 排查现场:五个从“起不来”到“跑不通”的真实原因

5.1 公钥放进去了,SSH 还是要输密码

现象:~/.ssh/authorized_keys里明明有四台的公钥,ssh node0002依然提示输密码。

原因:权限不对。authorized_keys是 644,或者家目录是 777,SSH 服务端会认为这个文件不可信,直接跳过不用。

解决:chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys,四台都做一遍。改完用ssh -vvv node0002看 debug 输出,里面会明确写Authentication refused: bad ownership or modes,比猜快得多。

5.2 node0002 的 DataNode 死活起不来

现象:NameNode 正常,jps在 node0002 上只能看到 NodeManager,没有 DataNode,日志报Incompatible clusterIDs。

原因:hdfs namenode -format跑了不止一次,每次格式化都生成新的 clusterID,DataNode 的 VERSION 文件里还是旧的那个。

解决:停掉集群,把dfs.namenode.name.dir和dfs.datanode.data.dir指向的目录全部删掉,然后重新格式化一次、只格式化一次。想验证是不是这个原因,比对 node0001 的data/name/current/VERSION和 node0002 的data/data/current/VERSION里的 clusterID 就行。

5.3 hadoop fs -ls obs:// 报 403,不是 404

现象:桶名肯定没写错,但hadoop fs -ls obs://bucket/直接返回 403。

原因:endpoint 的区域和桶的区域不一致。OBS 的鉴权签名里带了 endpoint 信息,区域不匹配时服务端判定签名无效,返回的是 403 而不是 404,所以特别容易被误判成 AK/SK 错了或者权限不足。

解决:去桶的概览页确认区域,把fs.obs.endpoint改成对应区域的值。改完不用重启,直接再跑一次hadoop fs -ls就能验证。

5.4 YARN 任务卡在 ACCEPTED 不动

现象:hadoop jar提交之后一直停在 ACCEPTED,yarn application -list里状态不变,等十分钟也没动静。

原因:NodeManager 上报的可用内存不够调度器分配一个 container。2 核 4G 的机器上yarn.nodemanager.resource.memory-mb设成 4096,系统自己、DataNode、NodeManager 一占,实际可分配的就没了。

解决:改成 3072,同时把yarn.scheduler.maximum-allocation-mb也调成 3072,两个值要匹配——前者是节点能给的总量,后者是单个容器能申请的上限,只改一个还是会卡。改完重启 YARN,yarn node -list里能看到 Available Memory 变成非零才算对。

5.5 Spark 里读 obs:// 报 No FileSystem for scheme

现象:hadoop fs -ls obs://完全正常,spark-sql里一建表就报No FileSystem for scheme "obs"。

原因:Hadoop 那边装了插件,但 Spark 的类加载器没看到。Spark 只扫$SPARK_HOME/jars/和自己的 classpath,Hadoop 的share/hadoop/common/lib/不在它的扫描范围里。

解决:把 hadoop-huaweicloud 的 jar 复制一份到$SPARK_HOME/jars/,三个 Worker 节点也都要放,因为任务真正执行是在 Worker 上。放完重启 Spark 集群,注意是重启,热加载不生效。

5.6 一张自查表,省掉一半的来回翻日志

症状第一眼看哪大概率原因
SSH 要密码ssh -vvv输出权限 600/700 没设对
DataNode 起不来VERSION文件里的 clusterID重复 format
obs 403fs.obs.endpoint区域和桶不一致
任务卡 ACCEPTEDyarn node -list的可用内存内存上限设太满
Spark 认不出 obs$SPARK_HOME/jars/插件 jar 没复制过去

这张表里的五条,基本上覆盖了从零搭这套集群会遇到的八成问题。剩下的两成,去$HADOOP_HOME/logs/和$SPARK_HOME/logs/里按时间戳找最新的那个文件,前 50 行通常就有答案。

6. 交付前的全链路验证:四个检查点与两个我一直在用的提效习惯

实验报告交上去之前,我会从零把整条链路走一遍,只留四个检查点,每个检查点对应一个可观测的输出,不靠感觉判断“应该没问题了”。

检查点命令通过标准
集群进程四台分别jpsnode0001 有 NameNode 和 ResourceManager,其余有 DataNode 和 NodeManager
HDFS 可用hdfs dfsadmin -reportLive datanodes 为 3,无 under-replicated 告警
OBS 连通hadoop fs -ls obs://bucket/正常列出对象,不报 403
交互查询spark-sql里跑一条带WHERE的聚合返回结果,且 Web UI 的 Executors 页能看到三个 Worker

这四个点里,第三个和第四个是最容易翻车的,因为它们依赖前面所有配置的叠加:AK/SK、endpoint、插件位置、HADOOP_CONF_DIR、$SPARK_HOME/jars/,任何一环没对上都会在这里暴露。所以我的习惯是把这两个检查写成一条脚本,每次改完配置就跑一遍,比翻日志快:

#!/bin/bash # check_all.sh:一条命令跑完两个关键连通性检查 set -e BUCKET="obs://your-bucket-name" echo "[1/3] HDFS 状态" hdfs dfsadmin -report | grep -E "Live datanodes|Under replicated" echo "[2/3] OBS 连通性" hadoop fs -ls "$BUCKET/" > /dev/null && echo "OBS OK" echo "[3/3] Spark 读 OBS" spark-sql --master spark://node0001:7077 -e \ "SELECT count(*) FROM parquet.\`$BUCKET/demo/wordcount\`;" \ > /dev/null && echo "Spark on OBS OK"

set -e让脚本在第一步失败时就退出,不会带着错误状态往下跑。最后一条-e参数是 spark-sql 的非交互模式,用来跑单条 SQL 做冒烟测试,比进交互界面手敲快。parquet.\路径`` 这种写法是直接对目录做临时查询,不用建表,适合验证阶段。

另一个习惯是给每套配置打快照。core-site.xml、hdfs-site.xml、yarn-site.xml、spark-env.sh这四个文件,每次改之前先cp一份带时间戳的副本到/opt/backup/。血泪经验是:调 OBS 参数的时候改错一个值,集群起不来,日志里又只有一句笼统的初始化失败,这时候能一键回滚到上一个能跑的版本,比对着几十行 XML 逐行比对省半小时。快照不用多,留最近三份就够。

从那以后我每次动集群配置,都先把这四个文件备份一遍再动手,改完立刻跑check_all.sh,两个动作连在一起,中间不插入任何“顺便再改一个试试”的念头。希望帮到你。

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

返回列表