简介:面向大数据与云计算方向的实验学习者,这份docx实验报告记录了在鲲鹏云/华为云环境中从零搭建Hadoop集群的完整流程,适合课程实验、云平台实训以及刚接触集群部署的读者对照练习。内容覆盖ECS与OBS服务准备、AK/SK认证信息获取、多节点SSH免密互信、core-site与hdfs-site等核心配置文件调整、slaves工作节点定义、NameNode初始化及HDFS启动,并保留了Java家目录配置错误后重新分发安装包、逐节点修正环境变量的排错过程。实验以Node0001至Node0003多节点协同为主线,对OBS接入Hadoop、目录结构创建、软件包同步等环节均有记录,可帮助读者理解云上大数据基础设施的部署顺序与常见故障定位方法。包内仅含1个docx文件,压缩包约2.52MB,内容集中、便于按步骤查阅。已有893人学习,可作为实验报告模板和操作对照材料。
1. 鲲鹏云上跑大数据实验,最先翻车的往往不是 Hadoop 参数
三台 ECS 的java -version全都正常输出,hdfs namenode -format一跑却报 JAVA_HOME not found——这个场景在鲲鹏云的大数据实验里出现频率高得离谱。原因不复杂:鲲鹏是 aarch64 架构,OpenJDK 装出来的目录是java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64这一长串,照着 x86 教程抄成.x86_64结尾,或者顺手简写成/usr/lib/jvm/jre,路径差一个后缀,Hadoop 整条链路就起不来,而且报错信息不会告诉你是路径问题。
这套「三节点 ECS + OBS 当底层存储 + Hadoop 2.8.3」的环境,是很多课程实验的标配:装顺了能从 HDFS 一路跑到 YARN 作业,装不顺会在同一个报错上耗掉半天。下面按我实际走通的顺序记一遍——先备云资源,再打系统层,然后落 Hadoop 配置,最后分发启动和排错。
2. 云上资源先备齐:ECS 规格、OBS 并行文件系统与 AK/SK 的获取顺序
动手装之前,先把三台机器和一个桶准备好。这一步看着是点点鼠标,但选错架构、选错桶类型,后面全白干。
2.1 三台 ECS 的架构、规格与角色划分
集群规划先定死,别装到一半改主机名:
| 节点 | 承担角色 | 规格建议 | 备注 |
|---|---|---|---|
| node-0001 | NameNode / SecondaryNameNode / ResourceManager | 4 核 8G | 格式化、启动都在这台 |
| node-0002 | DataNode / NodeManager | 4 核 8G | 从节点 |
| node-0003 | DataNode / NodeManager | 4 核 8G | 从节点 |
购买时三个选项要注意。第一是架构,选鲲鹏(ARM/aarch64)就别再装 x86 的 rpm 包,后面所有 JDK 包名都带aarch64后缀,镜像优先选 openEuler 这类能直接yum到对应包的。第二是网络,三台必须放同一个 VPC、同一个子网、同一个安全组,安全组入方向放行 22 端口,内网互通全开——跨可用区虽然也能通,但内网延迟上来之后scp分发和 SSH 互信都会变慢,排查时容易被误判成配置问题。第三是主机名,创建完就在控制台或系统里改成node-0001这种统一格式,hostnamectl set-hostname node-0001执行完重新登录一次确认生效。
公网 IP 按带宽计费就够,这套环境只用来 SSH,不对外提供服务。系统盘 40G 起步,Hadoop 安装包解压加上本地临时目录,20G 会紧张。
2.2 创建 OBS 并行文件系统,把 credentials.csv 拿到手
进对象存储服务创建桶,这里有个关键取舍:要选并行文件系统类型,不是普通对象桶。普通桶只能按对象读写,没法直接当 Hadoop 的fs.defaultFS用;并行文件系统提供 POSIX 兼容语义,Hadoop 才能把它挂成文件系统。桶名全局唯一,区域必须和 ECS 在同一个,跨区域的访问延迟会让hdfs dfs -ls卡到怀疑人生。
创建完成后在桶概览页能看到两个 endpoint:
| 类型 | 地址形式 | 什么时候用 |
|---|---|---|
| IPv4 | obs.cn-north-4.<域名后缀> | 默认,绝大多数情况 |
| 双栈 | obs.dualstack.cn-north-4.<域名后缀> | 子网确实开了 IPv6 才用 |
然后是创建访问密钥,下载credentials.csv。文件三列:User Name、Access Key Id、Secret Access Key,后面写core-site.xml全靠这三个值。
提示:credentials.csv 只在创建时能下载一次,页面关掉就再也拿不到 Secret Access Key,只能重建密钥对。我第一次做实验把 csv 存在了 ECS 的
/root下,重装系统时一起没了,只能重建。
拿到之后先在 shell 里存成变量,别急着往 XML 里抄:
# 在 node-0001 上执行,把三件套存成变量,后面写 xml 时直接替换 export OBS_AK='S8RS****************' # credentials.csv 的 Access Key Id,20 位 export OBS_SK='gjGN************************' # credentials.csv 的 Secret Access Key,40 位 export OBS_ENDPOINT='obs.cn-north-4.<域名后缀>' # 桶概览页的 IPv4 地址 export OBS_BUCKET='<并行文件系统名>' echo "${#OBS_AK} ${#OBS_SK} $OBS_ENDPOINT" # 核对长度,AK 20 位、SK 40 位先存变量再写配置的理由很实际:AK 是 20 位、SK 是 40 位大小写混排,手抄进 XML 极容易漏字符,而认证失败不会给你「密钥错了」这种直白提示,只会抛连接超时或者 403。先用echo ${#OBS_SK}核对长度,比事后翻日志省事得多。另外 csv 复制出来的值经常带双引号,粘进 XML 前务必删干净。
3. 三节点系统层打底:hosts 映射、SSH 互信与 aarch64 版 OpenJDK 1.8.0-242
Hadoop 集群跑不起来,八成问题出在这一层。hosts 写错、互信没通、JAVA_HOME 指偏,症状都会拖到启动阶段才暴露,那时候排查成本翻倍。
3.1 /etc/hosts 三行映射,三台必须写成一样
# 三台都执行,内容完全一致 cat >> /etc/hosts <<'EOF' 10.0.0.11 node-0001 10.0.0.12 node-0002 10.0.0.13 node-0003 EOF hostnamectl set-hostname node-0001 # 各台改成自己的名字 hostname # 确认生效,输出 node-0001几个细节值得说清楚。IP 用内网地址,别用公网 IP,实验文档里有时会写公网 IP,但同一 VPC 内走公网等于绕一圈 NAT,而且 ECS 重启后公网 IP 可能变,hosts 就失效了;内网 IP 在实例生命周期内固定。用 here-doc 追加而不是>覆盖,是为了不把系统自带的127.0.0.1 localhost那几行冲掉,冲掉之后很多本地服务会起不来。主机名和 hosts 里的名字必须一一对应,hostname输出node-0002,hosts 里就必须有一行解析到它,否则 SSH 互信时连到别的机器上,报的是Host key verification failed,看着像密钥问题,其实是解析问题。
三台配完互相ping node-0002验证一次,能通再往下走。
3.2 SSH 免密互信:公钥收集与 authorized_keys 权限
# 三台各自生成密钥,已有就跳过,不要覆盖 ssh-keygen -t rsa -b 2048 -N '' -f /root/.ssh/id_rsa # 把三台的公钥都打印出来,收集成一份 cat /root/.ssh/id_rsa.pub收集齐之后,三台的authorized_keys写入同样的三行:
cat >> /root/.ssh/authorized_keys <<'EOF' ssh-rsa AAAAB3NzaC1yc2E...== root@node-0001 ssh-rsa AAAAB3NzaC1yc2E...== root@node-0002 ssh-rsa AAAAB3NzaC1yc2E...== root@node-0003 EOF chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys验证用非交互命令,能返回主机名才算真通:
ssh node-0002 'hostname' # 期望输出 node-0002 ssh node-0003 'hostname'第一次连接会问 yes/no,选 yes 写进known_hosts。如果这台机器之前连过旧实例,先ssh-keygen -R node-0002清掉旧指纹,否则一直卡在指纹校验。
权限这块是玄学高发区:.ssh目录是 755、authorized_keys是 644,sshd 会直接拒绝使用密钥,日志里只有一句Permission denied (publickey),根本不提权限。三台内容必须一样,也就是互相都能免密,不能只做单向——start-dfs.sh和stop-dfs.sh会从 node-0001 往两个从节点发指令,反向不通的话停集群时会留下僵尸进程。
3.3 OpenJDK 1.8.0-242 装在 aarch64 上,JAVA_HOME 怎么推导出来
# 三台都装,包名带 aarch64 后缀,注意跟 x86_64 区分 rpm -ivh java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64.rpm rpm -ivh java-1.8.0-openjdk-devel-1.8.0.242.b08-1.h5.oe1.aarch64.rpm装完别猜路径,用readlink反查:
readlink -f "$(command -v java)" # 典型输出: # /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64/jre/bin/java把末尾的/jre/bin/java剥掉,剩下的就是 JAVA_HOME。写进/etc/profile:
cat >> /etc/profile <<'EOF' export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64 export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH EOF source /etc/profile java -version # 期望 1.8.0_242,输出里带 aarch64两个参数取舍要讲明白。JAVA_HOME 必须指到 JDK 根目录,不是jre子目录——Hadoop 的脚本自己会拼$JAVA_HOME/bin/java,你写成 jre,java命令照样能找到,但javac找不到,等到编译 MapReduce 作业才报错,那时候已经排了半天别的方向。CLASSPATH 里那两个dt.jar、tools.jar是 Oracle JDK 的布局,OpenJDK 里通常没有这两个文件,照抄进去不会报错,但确实是无效路径,知道这一点就行,别为它折腾。
三台的路径必须一字不差。这是后面分发配置时最常见的「0001 能起、0002 起不来」的根因。
4. Hadoop 2.8.3 配置落地:core-site.xml 里的 OBS 三件套与四份 XML 的最小集
配置这一层,改错一个值就要重新分发一轮。所以顺序是:一台改对、本地验证、再推给另外两台。
4.1 目录规划与解压:buf 和 localdir 别指到同一个地方
# 三台都执行,目录先建好,别等 format 时才报错 mkdir -p /home/modules/data/buf mkdir -p /home/nm/localdir# node-0001 上解压 cp /root/hadoop-2.8.3.tar.gz /home/modules/ cd /home/modules tar -zxvf hadoop-2.8.3.tar.gz ls -ld /home/modules/hadoop-2.8.3buf给hadoop.tmp.dir用,localdir给 YARN 的本地化目录用,故意分开是有原因的:YARN 往 localdir 里疯狂写容器临时文件,跑满磁盘是常事,分开之后打满只影响作业,不会连带把 NameNode 的元数据目录一起拖死。图省事把两个指到同一个父目录,磁盘满的时候 HDFS 和 YARN 一起挂,恢复起来很麻烦。
4.2 core-site.xml:OBS 的 AK/SK/endpoint 三个值怎么填
<?xml version="1.0"?> <configuration> <!-- 默认文件系统直接指向 OBS 并行文件系统,数据不落本地盘 --> <property> <name>fs.defaultFS</name> <value>obs://<并行文件系统名></value> </property> <!-- HDFS/YARN 的本地临时目录 --> <property> <name>hadoop.tmp.dir</name> <value>/home/modules/data/buf</value> </property> <!-- OBS 认证三件套,值来自 credentials.csv 与桶概览页 --> <property> <name>fs.obs.access.key</name> <value>S8RS****************</value> </property> <property> <name>fs.obs.secret.key</name> <value>gjGN************************</value> </property> <property> <name>fs.obs.endpoint</name> <value>obs.cn-north-4.<域名后缀></value> </property> </configuration>参数逐个说清楚。fs.defaultFS用obs://开头而不是hdfs://node-0001:9000,这是这套实验和普通 Hadoop 教程最大的区别,写成 hdfs 就退化成单机伪分布式,OBS 白买了,实验报告里的对象存储部分也没法验证。fs.obs.access.key和fs.obs.secret.key就是 AK/SK,明文写在 XML 里,实验环境这么干没问题,但只要这台机器不止你一个人用,就该换成临时凭证或者从配置中心读。fs.obs.endpoint用 IPv4 那个地址,别顺手填双栈——节点没开 IPv6 的话,Hadoop 会在建连阶段卡很久再超时,报错里完全看不出跟 IPv6 有关。
值不带引号、不带空格、不带行尾\r。csv 复制出来是"roy_yuki",S8RS...这种带引号的格式,粘进 XML 前必须删干净,这是个纯手工引入的坑。
4.3 hdfs-site.xml、yarn-site.xml、mapred-site.xml 的最小可用集
<!-- hdfs-site.xml --> <configuration> <!-- 数据实际落在 OBS,副本数 2 够实验用,也省对象存储流量 --> <property> <name>dfs.replication</name> <value>2</value> </property> <!-- 元数据落本地盘,目录要提前建好 --> <property> <name>dfs.namenode.name.dir</name> <value>file:///home/modules/data/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///home/modules/data/datanode</value> </property> </configuration>dfs.namenode.name.dir指向的目录必须先mkdir出来,format 时才不会报Cannot create directory。接了 OBS 之后,数据主体由对象存储承载,本地 datanode 目录更多是元数据和缓冲,但目录照样要有。
<!-- yarn-site.xml --> <configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>node-0001</value> </property> <!-- 不写这条,MapReduce 作业能提交但一直卡在 ACCEPTED --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.local-dirs</name> <value>/home/nm/localdir</value> </property> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>2048</value> </property> </configuration>yarn.resourcemanager.hostname写主机名而不是 IP,前提是 hosts 已经配好,这也是前面那一步必须先做的原因。aux-services漏写是最隐蔽的一类问题:作业提交成功、状态一直是 ACCEPTED,日志里没有任何错误,新手会以为集群卡住了。
# 2.8.3 自带的是模板文件,先改名再改 cd /home/modules/hadoop-2.8.3/etc/hadoop cp mapred-site.xml.template mapred-site.xml<!-- mapred-site.xml --> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>最后是 slaves,只写从节点:
cat > /home/modules/hadoop-2.8.3/etc/hadoop/slaves <<'EOF' node-0002 node-0003 EOF不要把 node-0001 写进去,主节点本身已经扛了 NameNode 和 ResourceManager,小规格机器上再跑一个 NodeManager,内存抢得厉害,作业一多就 OOM。
4.4 JAVA_HOME 要写两处,漏一处就是「命令行能跑、集群起不来」
# hadoop-env.sh 里写死绝对路径,守护进程只认这里 vim /home/modules/hadoop-2.8.3/etc/hadoop/hadoop-env.sh export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64# /etc/profile 里再写一份,供命令行直接调 hdfs / hadoop cat >> /etc/profile <<'EOF' export HADOOP_HOME=/home/modules/hadoop-2.8.3 export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH EOF source /etc/profile hadoop version这两处的分工必须搞清楚:/etc/profile是登录 shell 读的,你 ssh 上去敲hdfs命令走的是它;start-dfs.sh会 ssh 到远端节点起 java
本文还有配套的精品资源,点击获取