ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

华为云ECS上搭建Hadoop与Spark集群:全流程与避坑指南

华为云ECS上搭建Hadoop与Spark集群:全流程与避坑指南

简介:这份华为云大数据实验报告包含云主机实现大数据、云服务实现大数据、BigData Pro综合实验与大数据交互式查询四个实验,完整再现了在华为云上搭建并验证大数据处理平台的过程,对每一环节的关键操作与结果都做了记录。报告以docx格式提供,整包仅1个文件,大小4.36MB,覆盖ECS弹性云服务器创建、OBS对象存储桶与访问密钥配置、OpenJDK安装、关闭防火墙、节点SSH免密互联、Hadoop与Spark集群部署测试以及与OBS连通性验证等关键环节。内容还包含Spark SQL交互式查询的建表、分析及查看结果的操作记录。目前已吸引2448人学习,适合正在修读云计算课程、准备华为云认证或需要提交实验报告的高校学生与初级开发者。按照文档步骤即可复现实验,并为解决云主机配置、集群联调等常见问题提供参考。

1. 华为云 big data 实验:先从一台 ECS 开始的大数据集群搭建

在华为云上做大数据的同学,大概率绕不开这套实验:买几台弹性云服务器 ECS,配一个对象存储服务 OBS,然后手动把 Hadoop 集群搭起来。这个流程看着不复杂,但真做起来全是细节——版本选错、hosts 写错、SSH 互信没配好、防火墙没关,每一步都能让集群起不来。最让人头疼的是报错信息往往不直接,比如节点间连不上,日志里只给你一个 Connection refused,你根本不知道是网络不通还是服务没起来。我这次把整个实验过程完整跑了一遍,从购买 ECS 到创建 OBS 桶,从四节点 Hadoop 集群到 Spark 集群搭建,最后用 WordCount 和 OBS 互联把整条链路验证通过。这篇文章适合正在做华为云大数据实验、或者想从零手动搭一套 Hadoop 环境的开发者,我会按实际操作顺序,把每个命令、每个配置项、每个容易踩的坑都写清楚。

2. 准备华为云环境:ECS 购买、OBS 创建与 AK/SK 获取

2.1 购买弹性云服务器 ECS:规格选择和网络配置

实验的第一步是买 ECS。华为云的弹性云服务器购买入口在控制台首页,点「购买弹性云服务器」后进入配置页。这里有几个关键选项需要注意:计费模式选「按需计费」就行,实验做完直接删除,不用包年包月;地域选择「华北-北京四」,因为这个区域对应 OBS 的 Endpoint 是obs.cn-north-4.myhuaweicloud.com,后面配置core-site.xml时要和 OBS 区域保持一致,选错区域会导致 OBS 地址访问不通。

镜像我用的是 CentOS 7.6 64位,系统盘默认 40G 够用。规格方面,因为是四节点集群,每台建议至少 2 核 4G,不然 NameNode 和 DataNode 同时启动时内存很容易吃紧。网络选择默认的 VPC 和子网即可,安全组要放通 SSH(端口 22)和 Hadoop 所需端口,最省事的方式是实验期间暂时放通所有端口,或者把 8020、9870、8088、9000 这些 Hadoop 常用端口都加上规则。

购买时系统会要求设置 root 密码,这个密码要记好,后面登录 ECS 全靠它。购买完成后,在 ECS 列表可以看到每台实例的内网 IP 和弹性公网 IP。四台机器我习惯命名为 ecs-ca89-0001 到 ecs-ca89-0004,对应后面 hosts 文件里的 Node1 到 Node4。这里有个经验:在购买时就规划好节点角色,比如 0001 作为 NameNode 和 ResourceManager,其余三台作为 DataNode 和 NodeManager,后面配置会省很多事。

2.2 创建 OBS 桶与并行文件系统:存储层准备

OBS 对象存储服务的入口在控制台的「存储」分类下。进入 OBS 后,第一步是创建桶,桶名称要全局唯一,我用的名称格式是hadoop-data-<随机后缀>。区域选择和 ECS 一样选「华北-北京四」,存储类别选「标准」,访问权限建议选「私有」,因为数据不对外公开,后面通过 AK/SK 认证访问。创建完成后再创建一个并行文件系统,并行文件系统(PFS)和普通 OBS 桶的区别在于它支持文件语义,Hadoop 的obs://协议访问时性能更好,实验里推荐用并行文件系统。

创建桶的时候很容易忽略一个细节:桶的 Endpoint 地址。华北-北京四的 OBS 提供了两种地址,IPv4 地址是obs.cn-north-4.myhuaweicloud.com,双栈地址是obs.dualstack.cn-north-4.myhuaweicloud.com。如果 ECS 只用 IPv4,就配 IPv4 地址;如果 ECS 开了 IPv6,可以配双栈地址。建议直接用 IPv4 地址,避免双栈环境下解析出 IPv6 地址导致连接慢或超时。

2.3 获取 AK/SK:创建访问密钥并保存 credentials.csv

OBS 的访问认证用的是 AK/SK 密钥对。在控制台右上角点击用户名,选择「我的凭证」,切到「访问密钥」页签,点击「新增访问密钥」。创建后系统会生成一个credentials.csv文件下载到本地,打开后里面有 User Name、Access Key Id、Secret Access Key 三列。实验中我用到的 AK 是S8RSFKYBTOSPA9YX92XB这种格式的字符串,SK 是一串更长的密钥。这两个值要妥善保管,后面配置 Hadoop 连接 OBS 时,fs.obs.access.key和fs.obs.secret.key参数就填这两个值。

这里有个血泪经验:credentials.csv 只会下载一次,如果弄丢了,只能重新创建密钥。而重新创建意味着旧密钥失效,已经配置好的 Hadoop 集群里的 OBS 连接参数也要同步更新。所以下载后第一时间改名备份,别放在桌面随手删掉。

3. 搭建 Hadoop 集群:从 OpenJDK 到四节点互信与配置分发

3.1 安装 OpenJDK 与关闭防火墙:环境初始化的两件套

四台 ECS 登录后,先做两件基础操作:装 JDK、关防火墙。集群节点之间需要频繁通信,防火墙默认规则会拦截 Hadoop 的内部端口,虽然可以一条条放行,但实验环境直接关闭最省心。

# 在 node1 ~ node4 每台节点上分别执行 systemctl stop firewalld # 停止防火墙服务 systemctl disable firewalld # 禁用防火墙开机自启 setenforce 0 # 临时关闭 SELinux # 安装 OpenJDK 8 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

关闭防火墙用systemctl stop firewalld只是临时生效,disable才是彻底禁用。SELinux 在生产环境不建议关,但实验环境不关的话,后面 HDFS 的 DataNode 注册经常会报权限错误,玄学问题居多,直接关掉省事。JDK 我选 OpenJDK 8,Hadoop 2.x 和 3.x 官方文档都明确支持 JDK 8,如果你用 JDK 11 去跑老版本 Hadoop,NameNode 启动时可能直接报UnsupportedClassVersionError。

验证 JDK 安装是否成功,执行java -version,看到 openjdk version 1.8.0 的输出即为正常。接着确认JAVA_HOME环境变量。CentOS 用 yum 安装的 OpenJDK 路径通常在/usr/lib/jvm/java-1.8.0-openjdk,但每台机器的具体版本号子目录可能不同,建议用readlink -f $(which java)反解出真实路径,再写入/etc/profile。这一步配错,启动 Hadoop 时会报JAVA_HOME is not set,非常典型。

3.2 配置 hosts 文件与 SSH 免密互信:集群通信的地基

四节点集群要通信,最基础的是/etc/hosts域名映射。实验里四台机器的内网 IP 分配如下:node1 是 192.168.0.10,node2 是 192.168.0.53,node3 是 192.168.0.169,node4 是 192.168.0.77。把这几行写进每台节点的/etc/hosts:

cat >> /etc/hosts <<EOF 192.168.0.10 ecs-ca89-0001 node1 192.168.0.53 ecs-ca89-0002 node2 192.168.0.169 ecs-ca89-0003 node3 192.168.0.77 ecs-ca89-0004 node4 EOF

hosts 文件里 IP 后面可以跟多个主机名,第一个是规范名,后面的都是别名。我建议同时写上 ecs-ca89-000X 和 nodeX 两层名字,因为华为云控制台显示的是 ecs-ca89-0001 这种实例名,而 Hadoop 配置里用 node1 这种短名更清爽。如果 hosts 只写了短名,而 SSH 登录时用了云实例名,解析会失败,这是新手常踩的坑。

接下来是 SSH 免密互信。每个节点先用自己的 root 账号生成密钥对,然后把公钥汇总到一个authorized_keys文件里,分发到所有节点。实验中 node1 到 node4 都执行了cat /root/.ssh/id_rsa.pub查看公钥,最后把所有公钥合并:

# 1. 每台节点执行 ssh-keygen -t rsa -P '' -f /root/.ssh/id_rsa # 2. 在 node1 上汇总所有公钥并分发 ssh-copy-id node2 ssh-copy-id node3 ssh-copy-id node4

生成密钥对时-P ''表示空口令,省去每次输入 passphrase 的麻烦。作为合格做法,我一般先在一台节点生成,然后通过ssh-copy-id依次拷贝到其他节点,这个命令会自动把本机公钥追加到目标机的authorized_keys。验证方式很简单:从 node1 执行ssh node2,第一次可能提示确认主机指纹,输入 yes 后如果直接跳到 node2 的 shell 而不要求密码,说明免密配置成功。四节点需要确保两两互通,node1 到 node2、node3、node4 都要测一遍。

3.3 下载 Hadoop 安装包与配置核心文件:core-site、hdfs-site、yarn-site

Hadoop 版本我选用 3.3.x 系列,下载地址用清华镜像源,比 Apache 官方快很多。每台节点都下载一份安装包并解压到/usr/local/hadoop:

# 在 node1 上执行,下载并解压 cd /opt wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -zxvf hadoop-3.3.6.tar.gz mv hadoop-3.3.6 /usr/local/hadoop

这里我要说明一下为什么选 3.3.6 而不是 2.x 或最新的 3.4.x。华为云 OBS 的 Hadoop 适配插件(hadoop-huaweicloud)对 3.x 支持更完善,而 3.3.6 是当前稳定性和生态兼容性都比较均衡的版本。如果你选 Hadoop 2.x,虽然也可以跑,但 OBS 的obs://协议访问要额外适配,且 YARN 的资源调度能力差异明显。设置环境变量也要在/etc/profile里加 Hadoop 相关配置:

cat >> /etc/profile <<EOF export HADOOP_HOME=/usr/local/hadoop export PATH=\$PATH:\$HADOOP_HOME/bin:\$HADOOP_HOME/sbin export HADOOP_CONF_DIR=\$HADOOP_HOME/etc/hadoop EOF source /etc/profile

核心配置文件有四个需要手动改:

core-site.xml里指定 NameNode 地址和 OBS 访问参数:

<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node1:9000</value> </property> <property> <name>fs.obs.access.key</name> <value>你的AK</value> </property> <property> <name>fs.obs.secret.key</name> <value>你的SK</value> </property> <property> <name>fs.obs.endpoint</name> <value>obs.cn-north-4.myhuaweicloud.com</value> </property> <property> <name>fs.obs.impl</name> <value>org.apache.hadoop.fs.obs.OBSFileSystem</value> </property> </configuration>

fs.defaultFS决定了 HDFS 的入口,写hdfs://node1:9000然后必须保证 node1 能解析为实际 IP,否则客户端连接会失败。fs.obs.endpoint必须和 OBS 桶区域一致,这里用的是华北-北京四的 Endpoint。

hdfs-site.xml设置副本数和 NameNode/DataNode 的存储路径:

<configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///usr/local/hadoop/tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///usr/local/hadoop/tmp/dfs/data</value> </property> </configuration>

副本数设 3 是和四节点集群匹配的,保证任意一台 DataNode 挂掉数据不丢。NameNode 的 name 目录和 DataNode 的 data 目录必须提前创建,否则格式化时直接报目录不存在。

yarn-site.xml配置 ResourceManager 和 NodeManager 的调度方式:

<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>node1</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> </configuration>

yarn.nodemanager.aux-services配成mapreduce_shuffle是 MapReduce 任务跑在 YARN 上的必要条件,漏掉这个配置,提交作业时 Container 会一直起不来,日志刷SHUFFLE_FAILED。

mapred-site.xml(需要从模板复制)指定 MapReduce 的框架为 YARN:

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

四个配置文件改完后,用scp从 node1 分发到其他三台节点,保证配置一致。分发完成后还要改workers文件(3.x 版本叫 workers,2.x 叫 slaves),把 DataNode 和 NodeManager 的节点列表写进去:

cat > /usr/local/hadoop/etc/hadoop/workers <<EOF node1 node2 node3 node4 EOF

这里我踩过一个坑:单机伪分布式时 workers 文件可以写 localhost,但四节点集群必须写完整的主机名列表。如果漏掉某个节点,那个节点既不会启动 DataNode,也不会启动 NodeManager,你在jps里根本看不到对应进程。

3.4 初始化 HDFS 与启动集群:格式化 NameNode 是关键一步

集群配置完成后,第一次启动前必须格式化 NameNode。格式化会在dfs.namenode.name.dir指定的目录下生成命名空间镜像,相当于给 HDFS 建一张「空表」。

hdfs namenode -format

格式化输出里有一行Storage directory ... has been successfully formatted才算成功。这里有个必须注意的规则:格式化只能在第一次启动前执行,如果集群已经跑过、后面又格式化一次,所有 DataNode 的 clusterID 会和 NameNode 不一致,启动后 DataNode 全部报Incompatible clusterIDs。如果你中途重新格式化过,需要把每台节点上tmp/dfs/data目录清空再重启,相当于让 DataNode 重新注册,这是很多人集群起不来的原因。

启动集群分两步,先启 HDFS,再启 YARN:

start-dfs.sh start-yarn.sh

start-dfs.sh会在 node1 启动 NameNode 和 SecondaryNameNode,同时通过 SSH 到 workers 列表里的每台节点启动 DataNode。执行过程会要求输入 SSH 密码——如果前面免密配好了,这里会直接跳过。启动后用jps命令检查进程:

  • node1 上应有 NameNode、SecondaryNameNode、ResourceManager、DataNode、NodeManager
  • node2 ~ node4 上应有 DataNode、NodeManager

如果jps里只有 Jps 本身,说明启动脚本没能远程拉起进程,大概率是 SSH 免密失败或 workers 文件写错了。此时去/usr/local/hadoop/logs目录看hadoop-root-datanode-*.log,最常见的报错是All datanodes are bad,指向网络不通或 storage 目录权限不对。

4. 避坑指南:Hadoop 集群搭建中常见的五个翻车现场

4.1 现象:DataNode 进程反复退出

集群启动后,jps能看到 DataNode 进程,但过几分钟再查,进程已经消失,日志里报java.io.IOException: Incompatible clusterIDs。

原因是 NameNode 格式化后会产生新的 clusterID,而 DataNode 的 data 目录里保留着旧 clusterID。常见于你手动重新执行过hdfs namenode -format,或者从别的集群拷贝了 hadoop 目录。

解决方法是把每台节点/usr/local/hadoop/tmp/dfs/data/current/VERSION里的 clusterID 改成和 NameNode 的 VERSION 文件一致,或者干脆把 data 目录整个删掉,让 DataNode 重新注册。我一般选择删除目录后重启,简单干净。

4.2 现象:SSH 免密配好了,但 start-dfs.sh 还是要密码

ssh-copy-id执行成功,手动ssh node2也能免密登录,但start-dfs.sh远程启动时仍然提示输入密码。

原因是 Hadoop 启动脚本用的是当前系统 root 用户的密钥,但/root/.ssh/authorized_keys权限不对。SSH 对 authorized_keys 文件的权限极其敏感,必须是 600,.ssh目录必须是 700。很多教程没提这点,你从网上复制的公钥直接追加进去后权限是 644,SSH 会忽略这个文件。

解决方式是执行chmod 700 /root/.ssh和chmod 600 /root/.ssh/authorized_keys,然后重新测试免密登录。从那以后我每次配完互信,都会强制检查一遍权限,这已经成了条件反射。

4.3 现象:WordCount 提交后一直卡在 ACCEPTED 状态

任务提交到 YARN 后,状态一直是ACCEPTED,不进入RUNNING,日志里没有明显报错。

原因是 NodeManager 的临时目录权限或磁盘空间不足,导致 Container 无法在节点上创建工作目录。四台 ECS 系统盘默认 40G,如果 HDFS 写入太多测试数据,磁盘很容易打满,NodeManager 的本地目录自然写不进去。

解决方式是用df -h查看磁盘占用,清理掉/tmp和/usr/local/hadoop/tmp下的无用缓存。另外注意 Hadoop 的yarn.nodemanager.local-dirs如果没指定,默认在/tmp下,而/tmp经常被系统自动清理,建议显式改为/data/yarn/nm这样的独立目录。

4.4 现象:访问 OBS 桶时报 Access Denied 或 403

hdfs dfs -ls obs://bucket-name时返回AccessDenied或403 Forbidden。

原因是 AK/SK 配置错误,或者 OBS 桶的权限不属于当前 AK 对应的账号。我遇到过把 SK 和 AK 写反的情况,fs.obs.secret.key里填成了 Access Key Id,OBS 服务端校验签名失败,就报 403。

解决方式是重新核对 core-site.xml 里的两个值,注意 AK 和 SK 都是 20 位以上的字符串,长得有点像但要区分。另一个容易忽略的是:如果你用的是临时 AK/SK(比如通过 IAM 角色获取),必须额外配置fs.obs.session.token参数,只填 AK 和 SK 不够。

4.5 现象:Namenode 启动失败,日志报 Name or service not known

执行start-dfs.sh时,NameNode 起不来,日志报java.net.UnknownHostException: node1。

原因是/etc/hosts里没有配 node1 的映射,或者/etc/sysconfig/network里的 HOSTNAME 和 hosts 文件不一致。系统解析node1时找不到对应 IP,自然连接失败。

解决方式是在四台节点的/etc/hosts中都加入192.168.0.10 node1这一行,同时用hostname命令确认当前主机名。另外注意core-site.xml里的fs.defaultFS如果写了hdfs://node1:9000,每台节点能解析 node1 就行,不需要每台的 hostname 都叫 node1。

5. 搭建 Spark 集群:与 Hadoop 协同工作实现高效数据处理

5.1 下载 Spark 安装包并配置环境变量

Spark 是建立在 Hadoop 之上的计算框架,它的安装逻辑和 Hadoop 类似:下载二进制包、配置环境变量、修改配置文件。Spark 版本我选了 3.4.x,这个版本和 Hadoop 3.3.x 配合得很稳定,而且 Spark 官方发行版自带的 Hadoop 客户端版本就是 3.3 系列,不需要额外编译适配。

# 在 node1 上执行 cd /opt wget https://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-3.4.1/spark-3.4.1-bin-hadoop3.tgz tar -zxvf spark-3.4.1-bin-hadoop3.tgz mv spark-3.4.1-bin-hadoop3 /usr/local/spark # 配置环境变量 cat >> /etc/profile <<EOF export SPARK_HOME=/usr/local/spark export PATH=\$PATH:\$SPARK_HOME/bin:\$SPARK_HOME/sbin EOF source /etc/profile

下载包名前缀spark-3.4.1-bin-hadoop3中的hadoop3表示这个发行版已经编译好对 Hadoop 3.x 的支持。如果你用spark-3.4.1-bin-without-hadoop这个包,就得手动指定SPARK_DIST_CLASSPATH,指向 Hadoop 的 classpath,新手不建议碰这种自编译模式。

5.2 配置 Spark 的 workers 与环境变量:spark-env.sh 是关键

Spark 的配置目录在/usr/local/spark/conf,里面有两个文件需要修改。先从模板复制出配置文件:

cd /usr/local/spark/conf cp spark-env.sh.template spark-env.sh cp workers.template workers

编辑spark-env.sh,指定 Hadoop 配置目录和 Master 节点地址:

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HADOOP_HOME=/usr/local/hadoop export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export SPARK_MASTER_HOST=node1 export SPARK_WORKER_CORES=2 export SPARK_WORKER_MEMORY=2g

SPARK_MASTER_HOST决定 Spark Master 绑定在哪台节点,必须写 node1 对应的 IP 或主机名,写localhost会导致 Worker 连不上 Master。SPARK_WORKER_CORES和SPARK_WORKER_MEMORY根据每台 ECS 的规格调整,2 核 4G 的实例配 2 核 2g 比较合适,配多了容易把节点内存耗尽。

workers文件里写入 Spark Worker 的节点列表:

node1 node2 node3 node4

Spark 的workers文件对应 Hadoop 的workers文件,Spark 启动脚本会读取这个文件,通过 SSH 到每个节点启动 Worker 进程。

这里有个参数取舍要说明:spark-env.sh里也可以设置SPARK_MASTER_PORT和SPARK_WORKER_PORT,默认分别是 7077 和 8081,一般不需要改。如果你在云环境碰到端口冲突,才需要换端口,同时安全组也要放行对应端口。

5.3 启动 Spark 集群并验证 Worker 注册状态

Spark 启动前要确保 HDFS 和 YARN 已经在运行,因为 Spark 的 Standalone 模式虽然不强制依赖 YARN,但读写 HDFS 数据需要 HDFS 可用。启动命令:

/usr/local/spark/sbin/start-master.sh /usr/local/spark/sbin/start-workers.sh

start-master.sh在 node1 上启动 Master 进程,start-workers.sh才会根据workers文件远程拉起 Worker。启动后在浏览器访问http://<node1公网IP>:8080,可以看到 Spark Master 的 Web UI,里面会列出所有注册的 Worker 及其内存、核数信息。

如果 Worker 注册不上,去/usr/local/spark/logs文件夹里看spark-root-org.apache.spark.deploy.worker-*.out日志,最常见报错是Failed to connect to master,此时用telnet node1 7077检查端口连通性。安全组没放行 7077 端口是高频原因,放行后重启 Worker 即可。

验证 Spark 和 Hadoop 协同工作的最简单方式是提交一个用 Python 写的 Spark 作业,读取 HDFS 上的文件做词频统计:

/usr/local/spark/bin/spark-submit \ --master spark://node1:7077 \ /usr/local/spark/examples/src/main/python/wordcount.py \ hdfs://node1:9000/input/word.txt

spark-submit的--master参数指定 Spark 集群入口,spark://node1:7077表示用 Standalone 模式连接 Master。作业跑完后,输出信息里会显示每个单词的计数结果。

6. 验证跑通:WordCount、OBS 互联与交互式查询

集群全部搭好的最终检验,是跑通一条完整的数据链路:把数据放到 HDFS 或 OBS,用 MapReduce 或 Spark 做计算,最终拿到结果。我一般按以下三步做验收,每步都过了,这套集群才算真正「能用」。

第一步是 HDFS 的基本读写验证。在 node1 上执行命令向 HDFS 上传一个测试文件,并输出文件内容:

echo "hello hadoop hello spark" > /tmp/test.txt hdfs dfs -mkdir -p /input hdfs dfs -put /tmp/test.txt /input/ hdfs dfs -cat /input/test.txt

看到hello hadoop hello spark输出即说明 HDFS 正常。同时可以打开http://<node1公网IP>:9870查看 NameNode 的 Web UI,确认 DataNode 列表里有 4 个节点且状态为 Live,这比命令行更直观。

第二步是跑 MapReduce 的 WordCount。这是 Hadoop 生态最经典的验证作业,用官方示例包:

hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar \ wordcount /input /output

如果/output目录已经存在,作业会报FileAlreadyExistsException,需要先删除再执行:

hdfs dfs -rm -r /output

作业跑完后,查看结果文件:

hdfs dfs -cat /output/part-r-00000

看到两行结果hadoop 2和spark 1(取决于你测试文件的内容),说明 MapReduce 的整个流程——Map、Shuffle、Reduce——都正常。

第三步是验证与 OBS 的互联。这一步最容易出问题,因为涉及 AK/SK 和 Endpoint 配置,但验证方式反而最简单:

hdfs dfs -ls obs://<你的桶名称> hdfs dfs -put /tmp/test.txt obs://<你的桶名称>/test.txt

如果ls能列出 OBS 桶里的对象、put能上传成功,说明 Hadoop 集群已经通过 OBS 插件打通了对象存储。此时再跑一次 WordCount,输入路径指向 OBS:

hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar \ wordcount obs://<你的桶名称>/test.txt /output-obs

这个作业会把 OBS 上的数据拉取到 HDFS 计算,结果再写回 HDFS。能跑通这一步,意味着你可以把数据放在廉价的 OBS 上进行存储分析,而不必全部塞进 HDFS。

最后用 Spark 做一次交互式查询收尾。启动 Spark Shell:

/usr/local/spark/bin/spark-shell --master spark://node1:7077

在 Spark Shell 里执行:

val df = spark.read.text("hdfs://node1:9000/input/test.txt") df.show()

看到 DataFrame 输出测试文件内容,说明 Spark 能正常从 HDFS 读取数据。如果再执行df.count()返回行数,整个过程就全部验证通过了。

从那以后,我每次搭完集群,都强制自己走一遍这三步流程:HDFS 读写、MapReduce WordCount、OBS 互联测试。看起来步骤简单,但每一步都在验证不同层面的配置,任何一环有问题都能提前暴露,而不是等到正式跑数据时才发现集群是「半瘫」状态。这套实验做完,你对华为云上 ECS、OBS 和 Hadoop 生态的配合关系会有实打实的理解——一个云上大数据平台的底座就是这么堆起来的,希望帮到你。

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

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进