# node1 做完后 rsync 到 node2/node3(示意) tar -xf hadoop...
Criado em: 23 de dezembro de 2025
Criado em: 23 de dezembro de 2025
tar -xf hadoop-2.7.3.tar.gz -C /opt/hadoop-fs1 --strip-components=1
tar -xf hadoop-2.7.3.tar.gz -C /opt/hadoop-fs2 --strip-components=1
具体是怎么rsync? hadoop 需要三个节点上都有 hadoop-fs1,2文件夹吗
下面一步步给你说明 rsync 的具体用法,以及 Hadoop 目录在 3 个节点上的要求,按你现在的场景来讲。
👉 结论先说:需要。
如果你是一个标准的 Hadoop 集群(NameNode + DataNode):
也就是说,在 每个节点上都应该有:
bash/opt/hadoop-fs1 /opt/hadoop-fs2
这些目录用于:
dfs.data.dir✔ 即使 node2 / node3 只是 DataNode,也 必须有 Hadoop 程序本身 + 数据目录
bashmkdir -p /opt/hadoop-fs1 /opt/hadoop-fs2 tar -xf hadoop-2.7.3.tar.gz -C /opt/hadoop-fs1 --strip-components=1 tar -xf hadoop-2.7.3.tar.gz -C /opt/hadoop-fs2 --strip-components=1
一般只需要 一个 Hadoop 安装目录(例如 /opt/hadoop),
hadoop-fs1 / fs2 更多是 数据目录,但你既然这么分,就保持一致即可。
在 node1 上测试:
bashssh node2 hostname ssh node3 hostname
如果还要输密码,先做:
bashssh-keygen ssh-copy-id node2 ssh-copy-id node3
bashrsync -av /opt/hadoop-fs1/ node2:/opt/hadoop-fs1/ rsync -av /opt/hadoop-fs1/ node3:/opt/hadoop-fs1/
bashrsync -av /opt/hadoop-fs2/ node2:/opt/hadoop-fs2/ rsync -av /opt/hadoop-fs2/ node3:/opt/hadoop-fs2/
📌 注意两个关键点:
/ 不能少
bash/opt/hadoop-fs1/ ✅ /opt/hadoop-fs1 ❌(会多套一层目录)
在 node1 上:
bashfor host in node2 node3 do rsync -av /opt/hadoop-fs1/ $host:/opt/hadoop-fs1/ rsync -av /opt/hadoop-fs2/ $host:/opt/hadoop-fs2/ done
Hadoop 运行用户(比如 hadoop)在所有节点上必须一致。
bashchown -R hadoop:hadoop /opt/hadoop-fs1 /opt/hadoop-fs2
如果你用的是 root 启动 Hadoop,后期会踩坑,强烈建议用普通用户。
在 node2 / node3 上检查:
bashls /opt/hadoop-fs1 ls /opt/hadoop-fs2 /opt/hadoop-fs1/bin/hadoop version
能正常输出版本,说明同步成功 ✅
❌ 只在 NameNode 上装 Hadoop
❌ 三个节点 Hadoop 路径不一致
❌ rsync 少了尾部 /
❌ 没做 SSH 免密
如果你愿意,可以把你现在的 角色分配(哪台是 NN / DN)
或者 hdfs-site.xml 的配置贴出来,我可以帮你对着目录结构检查一遍是否合理。
sending incremental file list
rsync: mkdir "/export/jcloud-hadoop/hadoop-2.7.3-fs2" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(664) [Receiver=3.1.3]
为什么?
报错的原因很直接:目标端要创建的目录的“父目录”不存在。
你这句报错:
rsync: mkdir "/export/jcloud-hadoop/hadoop-2.7.3-fs2" failed: No such file or directory (2)
说明在 接收端(node2/node3) 上,/export/jcloud-hadoop 这个目录不存在(或路径写错/没挂载成功),所以 rsync 没法在里面 mkdir hadoop-2.7.3-fs2。
在 node2(node3 同理)执行:
bashls -ld /export ls -ld /export/jcloud-hadoop
如果第二条不存在,就需要先建父目录:
bashsudo mkdir -p /export/jcloud-hadoop
然后再 rsync。
在 node1 上对 node2/node3 执行:
bashssh node2 "sudo mkdir -p /export/jcloud-hadoop/hadoop-2.7.3-fs2" ssh node3 "sudo mkdir -p /export/jcloud-hadoop/hadoop-2.7.3-fs2" rsync -av /opt/hadoop-fs2/ node2:/export/jcloud-hadoop/hadoop-2.7.3-fs2/ rsync -av /opt/hadoop-fs2/ node3:/export/jcloud-hadoop/hadoop-2.7.3-fs2/
关键点:rsync 可以创建最后一层目录,但父目录必须存在(你这里缺的是父目录)。
如果 /export/jcloud-hadoop 存在但你不是 root,可能会因为权限失败(一般会报 Permission denied,不过也建议检查):
bashls -ld /export/jcloud-hadoop
需要的话:
bashsudo chown -R $USER:$USER /export/jcloud-hadoop
或者 rsync 用 sudo(常见做法是远端 sudo):
bashrsync -av --rsync-path="sudo rsync" /opt/hadoop-fs2/ node2:/export/jcloud-hadoop/hadoop-2.7.3-fs2/
如果你们的 /export 是 NFS/磁盘挂载点,目标机没挂上也会导致目录不存在。
在 node2 上:
bashmount | grep " /export " df -h /export
如果没输出/显示不对,先把挂载问题处理好。
把你执行的那条 rsync 原命令贴一下(包含源路径和目标路径),我可以直接指出你需要在哪一端 mkdir -p,以及路径尾部 / 要怎么写才不会多套一层目录。
jdk1.8.0_60.tar.gz 这个怎么解压
jdk1.8.0_60.tar.gz 是 tar + gzip 压缩包,用一条命令就能解压 👍
我分 最常见 / 指定目录 / 常见坑 给你说明。
bashtar -zxvf jdk1.8.0_60.tar.gz
参数含义(记一下就不容易忘):
z:gzip(.gz)x:解压v:显示过程(可选)f:指定文件解压后一般会得到:
bashjdk1.8.0_60/
比如你想放到 /export/jcloud-jdk 或 /opt/java:
bashmkdir -p /export/jcloud-jdk tar -zxvf jdk1.8.0_60.tar.gz -C /export/jcloud-jdk
解压后路径会是:
bash/export/jcloud-jdk/jdk1.8.0_60
如果你 不想要 jdk1.8.0_60 这一层目录,可以用:
bashmkdir -p /export/jcloud-jdk tar -zxvf jdk1.8.0_60.tar.gz -C /export/jcloud-jdk --strip-components=1
⚠️ 一般 不建议 JDK 用 --strip-components,保留版本目录更安全。
bashtar -ztvf jdk1.8.0_60.tar.gz | head
确认是不是 jdk1.8.0_60/ 开头。
bashvi /etc/profile
加上:
bashexport JAVA_HOME=/export/jcloud-jdk/jdk1.8.0_60 export PATH=$JAVA_HOME/bin:$PATH
生效:
bashsource /etc/profile
bashjava -version
应该看到:
textjava version "1.8.0_60"
👉 JDK 必须在每个 Hadoop 节点都安装,路径保持一致
推荐做法(和你刚才 rsync 思路一样):
bashrsync -av /export/jcloud-jdk/jdk1.8.0_60/ node2:/export/jcloud-jdk/jdk1.8.0_60/ rsync -av /export/jcloud-jdk/jdk1.8.0_60/ node3:/export/jcloud-jdk/jdk1.8.0_60/
如果你愿意,下一步我可以帮你:
你现在是 root 还是普通用户装 JDK?
3个 fs1 的node 是否都需要 改动 hdfs.xml 与 core-site.xml? fs2 因为3个节点都是重复的所以 端口需要和fs1 完全不一样吧?
node1:NN(fs1) + RM(YARN) + DN1/DN2 + NM
node2:NN(fs2) + DN1/DN2 + NM
node3:DN1/DN2 + NM + RM
你这个拓扑其实是 同一套物理 3 台机器上跑两套 HDFS(fs1 / fs2)+ 一套或两套 YARN 的典型“多实例/多集群”做法。问题你问得非常关键,我按你列的角色逐条把 hdfs-site.xml / core-site.xml 是否都要改、端口是否要不同、哪些能一样、哪些必须不同 讲清楚。
✅ 3 个节点上运行 fs1 的那些角色 → 都必须使用 fs1 的 core-site.xml + hdfs-site.xml
✅ 3 个节点上运行 fs2 的那些角色 → 都必须使用 fs2 的 core-site.xml + hdfs-site.xml
也就是说:不是只改 NameNode 那台,凡是这个集群的 DN/NM/Client 所在机器,都要用对应集群的配置。
你的 fs1 参与节点是:
✅ 只要 node2 / node3 上跑 fs1 的 DataNode,它们就必须拥有 fs1 的配置文件,因为 DataNode 需要知道:
📌 所以 fs1 的 core-site.xml & hdfs-site.xml 必须分发到 node1 node2 node3。
fs2 参与节点是:
✅ 同样,fs2 的 core-site.xml / hdfs-site.xml 也必须在 node1 node2 node3 都存在(只要这些节点上跑 fs2 的 DataNode)。
✅ 结论:HDFS 端口必须不同(至少涉及 NameNode/Secondary/HTTP/RPC…)
原因:同一台机器上如果你要同时跑:
那么这两个 DataNode 默认都会用同样的端口(例如 DataNode 的 IPC、数据传输端口、http端口),必冲突!
fs1 默认:
8020(RPC)9870(Web UI,2.x 常见是 50070/9870)
fs2 你必须改成:8021 或 9000 等9871 或 50071 等同一台机器上跑两个 DataNode(fs1 和 fs2)时,以下端口必须不同:
dfs.datanode.address(数据传输端口,默认 9866/50010)dfs.datanode.ipc.address(IPC 端口,默认 9867/50020)dfs.datanode.http.address(HTTP,默认 9864/50075)dfs.datanode.https.address(如果启用 https)✅ 所以在 fs2 的 hdfs-site.xml 里要改成另一套端口,例如:
fs1:
9866/9867/9864
fs2:
9966/9967/9964
fs1:
dfs.namenode.name.dir=/opt/hadoop-fs1/nn
fs2:dfs.namenode.name.dir=/opt/hadoop-fs2/nn否则两套 HDFS 写同一个 metadata,直接炸。
fs1:
dfs.datanode.data.dir=/opt/hadoop-fs1/dn1,/opt/hadoop-fs1/dn2
fs2:dfs.datanode.data.dir=/opt/hadoop-fs2/dn1,/opt/hadoop-fs2/dn2因为 fs.defaultFS 一定不同:
fs1:
xml<property> <name>fs.defaultFS</name> <value>hdfs://node1:8020</value> </property>
fs2:
xml<property> <name>fs.defaultFS</name> <value>hdfs://node2:8021</value> </property>
只要你机器上同时作为两个集群的 DataNode/Client,必须通过不同启动脚本/不同 Hadoop_HOME 来加载不同 core-site.xml。
你写的是:
这意味着你准备每台机器跑 2 个 DataNode 进程?
还是你想表达一台机器给 DataNode 配两个数据目录?
这两者完全不同:
例如:
xmldfs.datanode.data.dir=/opt/hadoop-fs1/dn1,/opt/hadoop-fs1/dn2
这样一个 DataNode 管两个盘/目录,不会端口冲突。
这就必须为每个 DataNode 进程配置独立端口、独立 PID 目录、独立日志目录,非常容易乱。
✅ 所以你写 DN1/DN2,我强烈建议理解为“两个数据目录”,而不是“两个 DataNode 进程”。
你写:
⚠️ 如果你是想做 YARN HA(双RM),可以,但需要配置 RM HA(ZKFC/自动切换等); 如果不是 HA,而是你想 两套 YARN 分别对应 fs1 / fs2,那也行,但必须端口不同。
✅ 你得明确:
你到底是:
✅ 必须做两套完整 Hadoop 配置和目录 建议目录结构:
text/opt/hadoop-fs1 (跑 fs1 的 HDFS + 可能也跑 yarn1) /opt/hadoop-fs2 (跑 fs2 的 HDFS + 可能也跑 yarn2)
每套里面都有自己的:
并且端口不冲突。
✅ HDFS 所有会监听的端口必须不同
也就是说:
不然一启动就报 Address already in use。
我可以帮你直接生成:
✅ 一套 fs1/fs2 完整端口规划表
✅ 两套 最小差异配置模板(只改必要项)
✅ node1/node2/node3 的启动顺序、脚本命令(含格式化、启动、验证)
你要不要按 “两套 HDFS + 一套 YARN” 还是 “两套 HDFS + 两套 YARN” 来做?我可以按你选的方案给你完整配置。
[root@vhost-52-multi hadoop]# cat core-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. See accompanying LICENSE file. --> <!-- Put site-specific property overrides in this file. --> <configuration> </configuration> [root@vhost-52-multi hadoop]# cat hdfs-site.xml <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. See accompanying LICENSE file.
-->
新解压出来的hadoop 两个配置文件就是这样的吗? 改怎么修改呢? 他有模版吗
对的:刚解压出来的 Hadoop,core-site.xml 和 hdfs-site.xml 默认就是几乎空的(只有 XML 头和 <configuration></configuration>)。需要你自己把集群参数填进去。
Hadoop 的“模板”不在这两个 *-site.xml 里,而是在同目录的:
core-default.xmlhdfs-default.xml它们包含所有可用参数 + 默认值(很长),你可以用它当“参数字典”。真正生效的是你写在 core-site.xml / hdfs-site.xml 里的覆盖项。
最稳的做法是:两套 Hadoop_HOME(你现在就是 /opt/hadoop-fs1、/opt/hadoop-fs2),每套各自一份 etc/hadoop/*.xml,端口/目录互不冲突。
下面给你一套可以直接抄的最小配置(按你角色:node1=NN(fs1),node2=NN(fs2),三台都有 DN)。
假设 Hadoop 2.7.3,且每台机器每套 HDFS 只跑 1 个 DataNode 进程(但 DataNode 用两个数据目录 dn1/dn2,这样不会搞多进程端口地狱)。
/opt/hadoop-fs1/etc/hadoop/core-site.xmlxml<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node1:8020</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/hadoop-fs1/tmp</value> </property> </configuration>
/opt/hadoop-fs1/etc/hadoop/hdfs-site.xmlxml<configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <!-- NameNode 元数据目录:只在 node1 上真正用到,但配置可以分发到所有节点 --> <property> <name>dfs.namenode.name.dir</name> <value>file:/opt/hadoop-fs1/nn</value> </property> <!-- DataNode 数据目录:三台机器都要有 --> <property> <name>dfs.datanode.data.dir</name> <value>file:/opt/hadoop-fs1/dn1,file:/opt/hadoop-fs1/dn2</value> </property> <!-- fs1 DataNode 端口(整套 HDFS1 用这一组) --> <property> <name>dfs.datanode.address</name> <value>0.0.0.0:9866</value> </property> <property> <name>dfs.datanode.ipc.address</name> <value>0.0.0.0:9867</value> </property> <property> <name>dfs.datanode.http.address</name> <value>0.0.0.0:9864</value> </property> <!-- fs1 NameNode Web UI(2.7 常见默认是 50070;你可固定一个避免冲突) --> <property> <name>dfs.namenode.http-address</name> <value>node1:50070</value> </property> </configuration>
/opt/hadoop-fs2/etc/hadoop/core-site.xmlxml<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node2:8021</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/hadoop-fs2/tmp</value> </property> </configuration>
/opt/hadoop-fs2/etc/hadoop/hdfs-site.xmlxml<configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:/opt/hadoop-fs2/nn</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:/opt/hadoop-fs2/dn1,file:/opt/hadoop-fs2/dn2</value> </property> <!-- fs2 DataNode 端口必须和 fs1 不同(同机两套 DN 必然冲突) --> <property> <name>dfs.datanode.address</name> <value>0.0.0.0:9966</value> </property> <property> <name>dfs.datanode.ipc.address</name> <value>0.0.0.0:9967</value> </property> <property> <name>dfs.datanode.http.address</name> <value>0.0.0.0:9964</value> </property> <property> <name>dfs.namenode.http-address</name> <value>node2:50071</value> </property> </configuration>
在 node1/node2/node3 都执行(或 rsync 前先 mkdir):
bashmkdir -p /opt/hadoop-fs1/{tmp,dn1,dn2,nn,logs} mkdir -p /opt/hadoop-fs2/{tmp,dn1,dn2,nn,logs}
注意:
nn目录只有 NN 那台会真正写,但目录存在不碍事;或者你也可以只在 NN 上建nn。
你可以这样看默认模板(就是参数说明书):
bashcd /opt/hadoop-fs1/etc/hadoop ls *default.xml # core-default.xml / hdfs-default.xml grep -n "fs.defaultFS" core-default.xml | head grep -n "dfs.datanode.address" hdfs-default.xml | head
真实修改就是:*把你需要覆盖的 property 写进 -site.xml。
你现在这套架构如果要在同一台机器上同时跑 fs1 的 DN + fs2 的 DN:
hadoop.tmp.dir 分开(上面已做)另外:你写的 “DN1/DN2” 我强烈建议理解为“两个数据目录”,不要搞成“两进程 DataNode”。
如果你把三台机器的主机名/IP(node1/node2/node3 对应哪个)和你准备的启动方式(用哪个 sbin/start-dfs.sh、是否同时启动两套)发我一眼,我可以再给你一份启动顺序(fs1 format -> start fs1 -> fs2 format -> start fs2)以及一份检查端口冲突的命令清单。
[root@vhost-52-multi hadoop]# cat core-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. See accompanying LICENSE file. --> <!-- Put site-specific property overrides in this file. --> <configuration> </configuration>在原始文件上我没看见模版
对,刚开始最小可用的 core-site.xml 基本就这两项就能跑起来(fs.defaultFS + hadoop.tmp.dir)。其他的都可以先不写,等你需要 HA、安全、压缩、回收站、NFS/S3 等再加。
你没在“原始文件”里看到模板,是因为:
core-site.xml / hdfs-site.xml 这些 *-site.xml 本来就是空壳(给你覆盖配置用)core-default.xml / hdfs-default.xml
最小可用:是的。(尤其你现在只是让 HDFS 跑起来)
fs1 的 core-site 最小示例(你写的没问题):
xml<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node1:8020</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop-2.7.3-fs1/tmp</value> </property> </configuration>
fs2 也同理,只是改 fs.defaultFS 和 tmp 路径:
xml<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node2:8021</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop-2.7.3-fs2/tmp</value> </property> </configuration>
关键点:fs1 / fs2 的
hadoop.tmp.dir必须不同(你已经分开了 👍)
在 etc/hadoop/ 目录下执行:
bashls -1 /data/hadoop-2.7.3-fs1/etc/hadoop/*default.xml # 会看到 core-default.xml hdfs-default.xml yarn-default.xml mapred-default.xml
想查某个参数默认值/说明:
bashgrep -n "fs.defaultFS" /data/hadoop-2.7.3-fs1/etc/hadoop/core-default.xml | head grep -n "hadoop.tmp.dir" /data/hadoop-2.7.3-fs1/etc/hadoop/core-default.xml | head
因为你是同一批机器上跑两套 HDFS(fs1/fs2),core-site.xml 虽然最小两项够,但你必须确保:
否则后面一启动就会 Address already in use 或数据目录混了。
如果你把 fs1 的 hdfs-site.xml 你打算怎么写(至少贴:dfs.namenode.name.dir、dfs.datanode.data.dir、以及你准备的 DN 端口设置)发出来,我可以直接帮你把 fs2 那份按“不冲突”的端口/目录一键改好。
我下的 2.73 原始的 压缩包 并没有[root@vhost-52-multi etc]# ls -1 /data/hadoop-2.7.3-fs1/etc/hadoop/*default.xml
ls: cannot access '/data/hadoop-2.7.3-fs1/etc/hadoop/*default.xml': No such file or directory
正常的:Hadoop 2.7.3 的二进制发行包里,很多情况下不会把 core-default.xml / hdfs-default.xml 以“文件”的形式放在 etc/hadoop/ 下面。这些“默认参数全集”经常是打包在 jar 里作为资源文件 的,所以你 ls /etc/hadoop/*default.xml 会找不到。
下面给你 3 种最靠谱的找法(按顺序来):
在你的 Hadoop_HOME(例如 /data/hadoop-2.7.3-fs1)里:
bashcd /data/hadoop-2.7.3-fs1 find . -name "*default.xml" -maxdepth 6
如果发行包里有独立文件,就会直接搜到。
jar tf 查(最常见)Hadoop 2.7.3 一般在这些 jar 里能找到默认配置资源:
share/hadoop/common/hadoop-common-2.7.3.jarshare/hadoop/hdfs/hadoop-hdfs-2.7.3.jar先定位 jar:
bashcd /data/hadoop-2.7.3-fs1 ls share/hadoop/common/hadoop-common-*.jar ls share/hadoop/hdfs/hadoop-hdfs-*.jar
然后查里面有没有 core-default.xml:
bashjar tf share/hadoop/common/hadoop-common-*.jar | grep -E "core-default.xml|core-site.xml" | head jar tf share/hadoop/hdfs/hadoop-hdfs-*.jar | grep -E "hdfs-default.xml|hdfs-site.xml" | head
一般你会看到类似:
core-default.xmlhdfs-default.xml在 Hadoop 目录下建个地方放出来:
bashcd /data/hadoop-2.7.3-fs1 mkdir -p default-xml # 解 core-default.xml jar xf share/hadoop/common/hadoop-common-*.jar core-default.xml mv core-default.xml default-xml/ # 解 hdfs-default.xml jar xf share/hadoop/hdfs/hadoop-hdfs-*.jar hdfs-default.xml mv hdfs-default.xml default-xml/ ls -l default-xml/
这样你就有“模板/参数全集”可以 grep 了,例如:
bashgrep -n "fs.defaultFS" default-xml/core-default.xml | head grep -n "dfs.datanode.address" default-xml/hdfs-default.xml | head
你刚才是在 /data/hadoop-2.7.3-fs1/etc 下执行的 ls,建议确认你确实解压到了这个目录,并且目录结构完整:
bashls -l /data/hadoop-2.7.3-fs1 ls -l /data/hadoop-2.7.3-fs1/share/hadoop/common ls -l /data/hadoop-2.7.3-fs1/share/hadoop/hdfs
只要 share/ 目录存在,上面 jar 方法就一定可用。
如果你把下面两条命令的输出贴出来(不用全贴,贴文件名那几行即可):
bashls share/hadoop/common/hadoop-common-*.jar ls share/hadoop/hdfs/hadoop-hdfs-*.jar
我就能直接告诉你应该从哪个 jar 解 core-default.xml / hdfs-default.xml,以及你现在这份发行包是不是“精简包/缺组件”。
整体思路对:你把 fs1 / fs2 的 NameNode 存储目录、DataNode 数据目录分开了,并且把 DataNode 的 3 个端口也分开,这是“同机两套 HDFS”必须做的事情 👍
但你现在还缺/需要确认 2 个关键点,不补的话后面大概率会启动异常或互相串配置。
hdfs-site.xml 里缺了 NameNode 的 RPC 地址(非常关键)只配 dfs.namenode.http-address 只是 Web UI 端口(50070/50071),DataNode/Client 连接 NameNode 走的是 RPC,通常由 core-site.xml 的 fs.defaultFS 指定:
hdfs://node1:8020hdfs://node2:8021(或别的端口)✅ 所以你必须确认你两套 core-site.xml 是这样的(最少要有这个):
fs1 core-site.xml
xml<property> <name>fs.defaultFS</name> <value>hdfs://192.168.0.29:8020</value> </property>
fs2 core-site.xml
xml<property> <name>fs.defaultFS</name> <value>hdfs://192.168.0.21:8021</value> </property>
并且:如果同一台机器同时跑 fs1 与 fs2 的 NameNode(或你不确定默认端口),建议你把 NN RPC 也显式写在 hdfs-site.xml,避免隐式端口导致误判:
xml<property> <name>dfs.namenode.rpc-address</name> <value>192.168.0.29:8020</value> </property>
xml<property> <name>dfs.namenode.rpc-address</name> <value>192.168.0.21:8021</value> </property>
8020/8021 只是示例,你用别的也行,但 fs1/fs2 必须不同。
dfs.datanode.data.dir 目前每套只有一个目录 .../dn这没问题(可跑),但你之前说 DN1/DN2,如果你是“一个 DN 进程 + 两块盘/两个目录”,建议改成:
fs1:
xml<name>dfs.datanode.data.dir</name> <value>file:/data/hadoop-2.7.3-fs1/dn1,file:/data/hadoop-2.7.3-fs1/dn2</value>
fs2:
xml<name>dfs.datanode.data.dir</name> <value>file:/data/hadoop-2.7.3-fs2/dn1,file:/data/hadoop-2.7.3-fs2/dn2</value>
不要搞成“一台机器跑两个 DataNode 进程”,那会复杂很多。
✅ 这样同机跑两套 DN 不会端口冲突(前提是你没有再起第二个 DN 进程)。
NN Web:
✅ 也没冲突。
⚠️ 但再次强调:RPC 端口(fs.defaultFS 指向的那个)必须确保 fs1/fs2 不同。
你现在写了 IP(192.168.0.29 / 192.168.0.21),这可以,但要保证:
/etc/hosts 或 DNS 解析一致在每台机器上,分别检查 fs1/fs2 启动后端口是否都在:
bash# 看 NN / DN 端口是否监听 ss -lntp | egrep "8020|8021|50070|50071|50010|50011|50020|50021|50075|50076"
以及分别用两套客户端检查:
bash# 用 fs1 的 hadoop 执行 /data/hadoop-2.7.3-fs1/bin/hdfs dfs -ls / # 用 fs2 的 hadoop 执行 /data/hadoop-2.7.3-fs2/bin/hdfs dfs -ls /
✅ 你这两份 hdfs-site.xml 目录隔离 + DN 端口隔离 做对了。
⚠️ 但要确认/补齐 两套 core-site.xml 的 fs.defaultFS(RPC 端口)必须不同(必要时加 dfs.namenode.rpc-address 明确化)。
如果你把 fs1/fs2 的 core-site.xml 也贴出来(尤其 fs.defaultFS),我就能直接给你判定:现在是否会串到同一个 NN,端口有没有隐性冲突。
mkdir -p /export/App && cd /export/App
JAVA_HOME=/export/App/jdk1.8.0_60/bin/java 配置环境变量没搞。
该怎么给三个节点 都设置JAVA_HOME? 并且能让 yarn 顺利使用到?
可以,按你现在的目录(JDK 放在 /export/App/jdk1.8.0_60)来做,三台节点都要做同样的两件事:
下面给你一套最稳的做法。
你写的是:
JAVA_HOME=/export/App/jdk1.8.0_60/bin/java
❌ 这是 java 可执行文件路径,不是 JAVA_HOME。
✅ 正确应该是 JDK 目录:
bashexport JAVA_HOME=/export/App/jdk1.8.0_60 export PATH=$JAVA_HOME/bin:$PATH
验证:
bash$JAVA_HOME/bin/java -version java -version echo $JAVA_HOME
假设 node1 已经有 /export/App/jdk1.8.0_60:
bashssh node2 "mkdir -p /export/App" ssh node3 "mkdir -p /export/App" rsync -av /export/App/jdk1.8.0_60/ node2:/export/App/jdk1.8.0_60/ rsync -av /export/App/jdk1.8.0_60/ node3:/export/App/jdk1.8.0_60/
注意源路径结尾的
/,避免多套一层目录。
在 每台机器 执行(或你用 ssh 批量执行):
bashcat >/etc/profile.d/java.sh <<'EOF' export JAVA_HOME=/export/App/jdk1.8.0_60 export PATH=$JAVA_HOME/bin:$PATH EOF chmod +x /etc/profile.d/java.sh source /etc/profile.d/java.sh java -version
bashfor h in node1 node2 node3; do ssh $h "cat >/etc/profile.d/java.sh <<'EOF' export JAVA_HOME=/export/App/jdk1.8.0_60 export PATH=\$JAVA_HOME/bin:\$PATH EOF chmod +x /etc/profile.d/java.sh source /etc/profile.d/java.sh java -version " done
因为 start-dfs.sh / start-yarn.sh 这类脚本经常不是登录 shell,有时不会加载 /etc/profile,所以最稳是直接写到 Hadoop 配置里。
假设:
/data/hadoop-2.7.3-fs1/data/hadoop-2.7.3-fs2在每台机器上:
bashecho 'export JAVA_HOME=/export/App/jdk1.8.0_60' >> /data/hadoop-2.7.3-fs1/etc/hadoop/hadoop-env.sh echo 'export JAVA_HOME=/export/App/jdk1.8.0_60' >> /data/hadoop-2.7.3-fs2/etc/hadoop/hadoop-env.sh
bashecho 'export JAVA_HOME=/export/App/jdk1.8.0_60' >> /data/hadoop-2.7.3-fs1/etc/hadoop/yarn-env.sh echo 'export JAVA_HOME=/export/App/jdk1.8.0_60' >> /data/hadoop-2.7.3-fs2/etc/hadoop/yarn-env.sh
如果你的
yarn-env.sh不存在,先ls etc/hadoop/看一下;2.7.3 一般是有的。
在你跑 YARN 的那一套配置目录里(你如果只跑一套 YARN,就只改那套)加:
xml<property> <name>yarn.app.mapreduce.am.env</name> <value>JAVA_HOME=/export/App/jdk1.8.0_60</value> </property> <property> <name>yarn.nodemanager.env-whitelist</name> <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME,PATH,LANG,LC_ALL</value> </property>
这能避免 容器环境里拿不到 JAVA_HOME。
在每台节点上(尤其 node3 是 NM/RM):
bashsource /etc/profile.d/java.sh echo $JAVA_HOME java -version
启动 YARN 后看日志是否报 Java 相关错误:
$HADOOP_HOME/logs/yarn-*-resourcemanager-*.log$HADOOP_HOME/logs/yarn-*-nodemanager-*.logJAVA_HOME 必须是 JDK 目录不是 .../bin/java如果你告诉我你最终到底是“只跑一套 YARN”还是“fs1/fs2 各跑一套 YARN”,我可以把你应该改哪一套的配置路径、以及 RM/NM 分布对应的最小配置列出来,避免你两套互相串。
profile.d 是什么文件 我之前用过 bashrc 和 bash_profile
这个问题问得非常好 👍
/etc/profile.d 正好就是用来解决你现在这种「三台节点统一环境变量」场景的。
我用你已经熟悉的 bashrc / bash_profile 来对照讲,一看你就明白。
~/.bashrc / ~/.bash_profile 👉 某一个用户/etc/profile 👉 系统所有用户/etc/profile.d/*.sh 👉 系统所有用户(模块化、推荐做法) ✅👉 在集群里(Hadoop / Yarn / Java),强烈推荐用 /etc/profile.d。
执行顺序大致是:
text/etc/profile └── 会自动 source /etc/profile.d/*.sh ~/.bash_profile └── 通常会 source ~/.bashrc
text~/.bashrc (不一定加载 /etc/profile)
⚠️ 重点来了:
Hadoop / Yarn 的启动脚本很多不是登录 shell 👉 你只写在
~/.bashrc里,经常会失效
/etc/profile.d/ 是一个目录,不是单个文件。
系统会在 /etc/profile 里自动执行:
bashfor i in /etc/profile.d/*.sh; do source "$i" done
所以:
java.sh| 方式 | 作用范围 | 适合场景 |
|---|---|---|
~/.bashrc | 单个用户 | 临时/个人 |
~/.bash_profile | 单个用户 | 登录时 |
/etc/profile | 所有用户 | 老式,不好维护 |
✅ /etc/profile.d/java.sh | 所有用户 | 集群/服务/生产推荐 |
因为:
start-dfs.shstart-yarn.shyarn-daemon.shhadoop-daemon.sh这些脚本 不一定加载你的用户 bashrc
👉 结果就是经典报错:
textJAVA_HOME is not set and could not be found
解决方案:
/etc/profile.d/java.shhadoop-env.sh / yarn-env.shbashcat >/etc/profile.d/java.sh <<'EOF' export JAVA_HOME=/export/App/jdk1.8.0_60 export PATH=$JAVA_HOME/bin:$PATH EOF chmod +x /etc/profile.d/java.sh
立即生效(当前 shell):
bashsource /etc/profile.d/java.sh java -version
重新登录后自动生效。
你以前可能这样写过:
bashecho 'export JAVA_HOME=...' >> ~/.bashrc
问题是:
而 /etc/profile.d/java.sh:
✔ /etc/profile.d/java.sh(系统级)
✔ hadoop-env.sh(HDFS 启动脚本)
✔ yarn-env.sh(YARN 启动脚本)
这三层一起,几乎不可能再遇到 JAVA_HOME 问题。
hadoop-env.sh / yarn-env.sh 是否写对你现在是 root 用户启动 Hadoop 还是 hadoop 普通用户启动?这会影响一个细节,我可以顺手帮你优化。
[root@vhost-52-multi hadoop-2.7.3-fs1]# ./sbin/start-dfs.sh
Incorrect configuration: namenode address dfs.namenode.servicerpc-address or dfs.namenode.rpc-address is not configured.
Starting namenodes on []
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:VRxquRdbBtn6IIICZcOhxuh3WkwL5ybosjtFlk1Qzzg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? ^Clocalhost: Host key verification failed.
这是什么情况?
此外 我启动了 ./bin/hdfs namenode -format -force 这个命令 然后shell就卡住了? 这是为啥
root 49415 44787 2 20:44 pts/0 00:00:01 /export/App/jdk1.8.0_60/bin/java -Dproc_namenode -Xmx1000m -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/export/jcloud-hadoop/hadoop-2.7.3-fs1/logs -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=/export/jcloud-hadoop/hadoop-2.7.3-fs1 -Dhadoop.id.str=root -Dhadoop.root.logger=INFO,console -Djava.library.path=/export/jcloud-hadoop/hadoop-2.7.3-fs1/lib/native -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender -Dhadoop.security.logger=INFO,NullAppender org.apache.hadoop.hdfs.server.namenode.NameNode -format -force
你现在遇到的是 两类问题叠加:
start-dfs.sh 报 NameNode RPC 地址没配start-dfs.sh 通过 ssh 启动进程时,连 localhost 都没通过 host key 校验/免密另外你说 hdfs namenode -format “卡住”,其实format 本来就是前台运行(不返回就像卡住),但也可能被交互/ssh/配置问题拖住;先按下面步骤修正后再 format 一次最稳。
start-dfs.sh 内部会调用类似 hdfs getconf -namenodes 去取 NN 地址。你只配了 fs.defaultFS,但它在你的场景下仍要求显式配置 NN RPC 地址。
在 fs1 的 hdfs-site.xml 里加上(fs1 的 NN 在 192.168.0.29,RPC 端口 8020):
xml<property> <name>dfs.namenode.rpc-address</name> <value>192.168.0.29:8020</value> </property>
(可选但建议)再把 web 也用同类 key 固定一下:
xml<property> <name>dfs.namenode.http-address</name> <value>192.168.0.29:50070</value> </property>
fs2 同理(192.168.0.21:8021 / 50071)。
你现在
core-site.xml里的fs.defaultFS=hdfs://192.168.0.29:8020没问题,但 start-dfs 这套脚本更依赖 hdfs-site 的 rpc-address 配置,加上就不报了。
start-dfs.sh 是用 ssh 去各节点(包含本机)拉起 NameNode/DataNode 的,所以你必须保证 root 这个用户(你现在是 root 在跑):
ssh localhost 不提示 yes/nossh node1/node2/node3 不要密码(免密)在 node1 上执行:
bashssh -o StrictHostKeyChecking=accept-new localhost "hostname" ssh -o StrictHostKeyChecking=accept-new 127.0.0.1 "hostname"
如果你机器会优先走 IPv6 的 ::1,也做一下:
bashssh -o StrictHostKeyChecking=accept-new ::1 "hostname"
或者更简单粗暴(不推荐长期,但排障可用):
bashssh-keygen -R localhost ssh-keygen -R 127.0.0.1
在 node1:
bashssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa ssh-copy-id node1 ssh-copy-id node2 ssh-copy-id node3
并测试:
bashssh node1 "hostname" ssh node2 "hostname" ssh node3 "hostname" ssh localhost "hostname"
只要这里任何一个还要你输入 yes/no 或密码,
start-dfs.sh就会卡/失败。
hdfs namenode -format -force 卡住是为什么?所以看起来像“卡住”。一般它会输出一堆格式化信息然后退出。
这时别猜,直接看日志(最关键):
bashls -ltr /export/jcloud-hadoop/hadoop-2.7.3-fs1/logs | tail tail -n 200 /export/jcloud-hadoop/hadoop-2.7.3-fs1/logs/hadoop-*-namenode-*.log
另外你进程里显示 -Dhadoop.id.str=root,说明你是 root 在 format。确认目录权限也没问题:
bashls -ld /data/hadoop-2.7.3-fs1/nn /data/hadoop-2.7.3-fs1/tmp
Hadoop 2.7 支持 -nonInteractive,用这个更稳:
bash/export/jcloud-hadoop/hadoop-2.7.3-fs1/bin/hdfs namenode -format -force -nonInteractive
注意:format 只在第一次做一次。以后再 format 会把 NN 元数据清掉。
如果你现在已经有这个 format 进程在跑,想停掉可以:
bashkill 49415
(或 kill -9 49415 作为最后手段)
dfs.namenode.rpc-addressssh localhost/node1/node2/node3 都不提示也不要密码start-dfs.sh如果你把 fs1 的 hdfs-site.xml(含你刚才那段 + 我让你加的 rpc-address) 和你 fs1 的 workers/slaves 文件内容(列了哪些主机名)贴一下,我可以直接告诉你:start-dfs.sh 为啥显示 Starting namenodes on [](这通常是“没读到 namenode 列表/配置不完整/主机名解析不一致”导致的)。
[root@vhost-52-multi ~]# /export/jcloud-hadoop/hadoop-2.7.3-fs2/sbin/mr-jobhistory-daemon.sh start historyserver
historyserver running as process 50106. Stop it first.
我启动了 fs1的 history. 那我应该在fs2 的namenode 也就是 node2 上启动 history 是吧?
结论先给你:不是必须在 fs2 的 NameNode(node2)上再启动一个 HistoryServer。
你现在看到的提示,其实是在告诉你:这台机器上已经有一个 HistoryServer 在跑了。
下面把 为什么、什么时候要两个、你现在该怎么做 讲清楚。
MapReduce JobHistoryServer 的职责只有一个:
👉 保存和展示已经完成的 MapReduce 作业历史
它和:
没有强绑定关系,而是和 YARN / MapReduce 绑定。
你在 fs2 的 Hadoop_HOME 下执行:
bash/export/jcloud-hadoop/hadoop-2.7.3-fs2/sbin/mr-jobhistory-daemon.sh start historyserver
返回:
texthistoryserver running as process 50106. Stop it first.
说明:
👉 同一台机器上不能启动两个 HistoryServer(端口会冲突)
👉 一套 YARN + 一套 MapReduce
✔ 这是最简单、最稳定、最常见的做法
✔ 你现在的现象正好符合这个模式
那个 HistoryServer 很可能是你用 fs1 的 Hadoop_HOME 启的
👉 fs1 / fs2 各一套 YARN + 各一套 MapReduce
这种情况下才需要:
⚠️ 但必须:
mapreduce.jobhistory.* 配置你现在明显还没走到这一步,也不建议你现在就这么搞。
在那台机器上(比如 node1 / node3):
bashjps | grep -i history
应该看到类似:
text50106 JobHistoryServer
再看看是用哪套 Hadoop 启的:
bashps -fp 50106
你会看到类似:
text... /export/jcloud-hadoop/hadoop-2.7.3-fs1/...
或 fs2,但不重要 —— 只要 YARN / MapReduce 指向它即可。
在你跑 YARN 的那一套 Hadoop 配置目录里(例如 fs1 那套),确认:
mapred-site.xml 至少有这些:xml<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>nodeX:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>nodeX:19888</value> </property> </configuration>
其中 nodeX 就是你实际跑 HistoryServer 的那台机器。
“那我应该在 fs2 的 namenode 也就是 node2 上启动 history 是吧?”
❌ 不一定,也通常不需要。
✅ 只要你是一套 YARN / MapReduce → 只要 1 个 HistoryServer 就够。
你现在这个提示反而说明:你已经启动过了,而且是正确的。
如果你愿意,下一步我可以帮你做两件很有价值的事之一:
1️⃣ 帮你确认现在到底是哪一套 Hadoop 在跑 YARN / HistoryServer
2️⃣ 帮你核对 mapred-site.xml / yarn-site.xml,确保 MR 作业跑 fs1 或 fs2 都不会串
你现在是打算 只用一套 YARN 调度 fs1 / fs2 上的 MR 作业,对吗?
node1 :
cd /export/jcloud-hadoop/hadoop-2.7.3-fs1
./bin/hdfs namenode -format -force
./sbin/start-dfs.sh
./sbin/start-yarn.sh
node2 :
cd /export/jcloud-hadoop/hadoop-2.7.3-fs2
./bin/hdfs namenode -format -force
./sbin/start-dfs.sh
怎么验证成功启动了呢? fs2 需要怎么绑定到 yarn 上?
下面按你现在的启动顺序,给你一套可操作的“验证清单”,以及 fs2 怎么“绑定”到 YARN 的正确理解与做法。
在 node1/node2/node3 分别执行:
bashjps
你应该看到:
node1(fs1 NN + YARN RM):
NameNodeDataNode(如果 node1 也跑 DN)ResourceManagerNodeManagernode2(fs2 NN):
NameNodeDataNodeNodeManagernode3(DN + NM + 你说还有 RM)
DataNodeNodeManagerResourceManager,一般先别搞双 RM)重点:fs1 和 fs2 在同一台机器上如果都跑 DN,会看到 2 个 DataNode 进程(分别从两个 Hadoop_HOME 启动);如果你只跑一套 DN,那只会有一个。
http://192.168.0.29:50070
http://192.168.0.21:50071YARN:
http://<RM所在机器>:8088JobHistory(如果你启了):
http://<historyserver机器>:19888在任意机器上分别用两套 hdfs client 测:
验证 fs1:
bash/export/jcloud-hadoop/hadoop-2.7.3-fs1/bin/hdfs dfs -ls / /export/jcloud-hadoop/hadoop-2.7.3-fs1/bin/hdfs dfsadmin -report | head -n 50
验证 fs2:
bash/export/jcloud-hadoop/hadoop-2.7.3-fs2/bin/hdfs dfs -ls / /export/jcloud-hadoop/hadoop-2.7.3-fs2/bin/hdfs dfsadmin -report | head -n 50
如果 -ls / 能返回(就算是空),dfsadmin -report 能看到 DataNodes,说明 HDFS 起来了。
这里要先纠正一个概念:
YARN 是计算/资源调度,HDFS 是存储。
YARN 跑的作业(MapReduce/Spark)用哪个 HDFS,取决于:
fs.defaultFS(也就是你用 fs1 还是 fs2 的配置)hdfs://... 还是默认 hdfs:///...也就是:
你需要在 fs2 的 Hadoop_HOME 也准备好 yarn-site.xml / mapred-site.xml,让它能连到 同一个 RM。
/export/jcloud-hadoop/hadoop-2.7.3-fs2/etc/hadoop/yarn-site.xml 里(最少这些)把 RM 指向 node1(假设 node1 是 RM):
xml<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>192.168.0.29</value> </property> </configuration>
如果你用的是更细的 address 配置(scheduler/address等),也行,但最少 hostname 要对。
mapred-site.xml(没有就从 mapred-site.xml.template 拷贝)/export/jcloud-hadoop/hadoop-2.7.3-fs2/etc/hadoop/mapred-site.xml:
xml<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
在 node1(或任意节点)用 fs2 的环境 提交一个例子:
bashcd /export/jcloud-hadoop/hadoop-2.7.3-fs2 # 先看能不能连到 RM ./bin/yarn node -list # 跑个简单 MR 示例(pi) ./bin/yarn jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar pi 2 10
同时打开 RM UI(8088),看 Applications 里是否出现该任务。
如果:
yarn node -list 能列出节点pi 能跑起来并完成
说明:fs2 这套配置已经能用同一套 YARN 调度了。你 node2 注释里写了“启动fs1”,实际是启动 fs2 的 dfs:
bashcd /export/jcloud-hadoop/hadoop-2.7.3-fs2 ./sbin/start-dfs.sh # 这是启动 fs2(以 fs2 的配置)
✅ 逻辑没问题。
同一台机器上同时跑 fs1 和 fs2 的 DataNode 时:
dfs.datanode.data.dir 不能指向同一目录(你也分开了)一旦端口或目录冲突,jps 可能看得到进程但 UI 里 Live Nodes 不会全绿。
如果你把以下两样贴出来(不用全贴,关键行即可):
yarn-site.xml(RM 配置)yarn-site.xml(你准备怎么写)我可以直接告诉你:/bin/yarn node -list 为什么可能连不上,以及 RM 到底该指向 node1 还是你想做双 RM。
The authenticity of host 'vhost-52-multi (fe80::f816:3eff:fe1e:39fa%eth0)' can't be established.
ECDSA key fingerprint is SHA256:VRxquRdbBtn6IIICZcOhxuh3WkwL5ybosjtFlk1Qzzg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
vhost-52-multi: Warning: Permanently added 'vhost-52-multi,fe80::f816:3eff:fe1e:39fa%eth0' (ECDSA) to the list of known hosts.
启动服务的时候 这个是什么原因导致的?
这是 SSH 的主机指纹确认提示,不是 Hadoop 的错误,本质原因是:
Hadoop 启动脚本通过
ssh连接节点(包括本机),而 SSH 第一次连接某个“主机名/IP”时,需要你确认它的身份。
下面把 为什么会出现、为什么是 IPv6、会有什么影响、怎么彻底解决 一次讲清楚。
textThe authenticity of host 'vhost-52-multi (fe80::f816:3eff:fe1e:39fa%eth0)' can't be established. ECDSA key fingerprint is SHA256:... Are you sure you want to continue connecting (yes/no/[fingerprint])?
逐条翻译:
~/.ssh/known_hosts后面这句说明已经写进去了:
textPermanently added ... to the list of known hosts
start-dfs.sh / start-yarn.sh 内部逻辑是:
textssh node1 启 NameNode ssh node2 启 DataNode ssh node3 启 DataNode
哪怕是本机,也会 ssh localhost / hostname。
所以只要出现以下情况之一,就会弹这个提示:
这是非常典型的现象,原因是:
hostname → DNS / /etc/hosts → 优先解析到 IPv6所以你看到的是:
textvhost-52-multi (fe80::xxxx%eth0)
而不是:
text192.168.x.x
你输 yes,服务还能继续启动。
Hadoop 脚本是非交互式的:
yes/noStarting namenodes on []Host key verification failed👉 根因基本都是这个
在 每个节点(用 root) 执行:
bash# 本机 ssh -o StrictHostKeyChecking=accept-new localhost hostname ssh -o StrictHostKeyChecking=accept-new $(hostname) hostname # 所有节点 ssh -o StrictHostKeyChecking=accept-new node1 hostname ssh -o StrictHostKeyChecking=accept-new node2 hostname ssh -o StrictHostKeyChecking=accept-new node3 hostname
如果你机器会走 IPv6,再补一条:
bashssh -o StrictHostKeyChecking=accept-new ::1 hostname
这样 known_hosts 就全齐了。
编辑 /etc/ssh/ssh_config:
bashHost * AddressFamily inet
然后:
bashsystemctl restart sshd
这会强制 SSH 只用 IPv4。
在 hadoop-env.sh 和 yarn-env.sh 里确认有:
bashexport HADOOP_OPTS="$HADOOP_OPTS -Djava.net.preferIPv4Stack=true"
(你之前的进程参数里已经看到这个 👍)
做完上面处理后,检查这 4 条都必须 无提示直接返回:
bashssh localhost hostname ssh $(hostname) hostname ssh node2 hostname ssh node3 hostname
然后再启动:
bash./sbin/start-dfs.sh ./sbin/start-yarn.sh
如果还有任何 SSH 提示,说明还有遗漏的主机名/IP。
这不是 Hadoop 问题,是 SSH 第一次连接 + IPv6 优先导致的。
Hadoop 启动依赖 SSH,必须提前打通所有节点(含 localhost)的免密 + known_hosts,否则一定会卡。
如果你愿意,下一步我可以帮你做一件很实用的事:
👉 给你一份“启动 Hadoop 前的 SSH 自检清单(5 条命令)”
跑完它,基本可以保证 start-dfs.sh / start-yarn.sh 不再出幺蛾子。
你现在是 每台都用 root 启 Hadoop 对吧?我可以按 root 用户给你一份最终版检查表。