上篇把 JDK、Hadoop 3 的下载解压、环境变量这些前置工作都处理完了,这篇接着往下走:改配置、格式化 NameNode、启动 HDFS 和 YARN、跑通第一个 MapReduce 任务。我在 CentOS 7 上装 Hadoop 3 的次数自己都记不清了,这篇文章就把最关键的配置逻辑和踩过的坑直接给你捋干净。
这篇默认你的环境已经具备这些条件:一台干净的 CentOS 7 虚拟机,装好了 JDK 8 或 11,Hadoop 3.3.x 已经解压到 /usr/local/hadoop,并且 JAVA_HOME、HADOOP_HOME 等环境变量已经写进了 /etc/profile。如果还没到这一步,先回去把上篇弄完再往下看,否则后面报错你会分不清是配置问题还是环境问题。
1. 动手前先做两件不起眼的小事
1.1 确认 JDK 和 Hadoop 版本真的匹配
Hadoop 3.x 官方要求 Java 8 或者 Java 11,这两个大版本都能用。但是 CentOS 7 上如果你是用 yum 装的 java-1.8.0-openjdk,要注意实际路径通常带版本号,比如 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx,而 /usr/lib/jvm/java-1.8.0-openjdk 这个路径是否真实存在,取决于你有没有装 java-1.8.0-openjdk-devel。很多教程会写死一个版本号路径,你直接抄过来,结果目录对不上,启动时就报 JAVA_HOME 相关错误。
检查的最好方式就是执行两行命令:
bash复制java -version
/usr/local/hadoop/bin/hadoop version
如果 hadoop version 能正常打印出 Hadoop 3.3.x 的版本信息,说明环境变量和 JDK 至少没大问题。如果 hadoop 命令直接提示找不到 JAVA_HOME,那就先别急着改配置文件,大概率是 /etc/profile 里的 export JAVA_HOME 路径写错了,或者你没有 source /etc/profile 让它生效。
1.2 数据目录千万别图省事放 /tmp 下
第一次装 Hadoop 的人最容易图省事,把 hadoop.tmp.dir、dfs.namenode.name.dir、dfs.datanode.data.dir 这些目录都留在默认位置。默认的 hadoop.tmp.dir 是 /tmp/hadoop-${user.name},这在生产环境就是个定时炸弹。CentOS 7 的 /tmp 目录有自动清理机制,系统重启或者临时文件被清理后,你的 NameNode 元数据可能就没了,轻则 DataNode 起不来,重则整个 HDFS 数据没法恢复。
所以动手改配置之前,先把目录结构规划好。我习惯的做法是单独建一个数据目录:
bash复制mkdir -p /data/hadoop/tmp
mkdir -p /data/hadoop/hdfs/name
mkdir -p /data/hadoop/hdfs/data
mkdir -p /data/hadoop/logs
如果你用的是 hadoop 用户而不是 root,记得把目录属主改一下,不然 Hadoop 进程没有权限写数据,启动时一样会报 Permission denied:
bash复制chown -R hadoop:hadoop /data/hadoop
这里多说一句:如果你之后打算把数据目录放在额外挂载的数据盘上,一定先确认分区挂载好了再创建目录。我有一次在云主机上没注意数据盘还没挂载,结果数据全写进了系统盘,后面扩容迁移数据时折腾了半死。提前规划好目录,后面格式化、启动、跑任务都会顺很多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 六个核心配置文件逐个拆解
Hadoop 3 的配置集中在 $HADOOP_HOME/etc/hadoop 目录下。单机伪分布式模式只需要改六个地方:hadoop-env.sh、core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml、workers。每个文件的作用不同,但经常有人把配置项放错文件,比如把 fs.defaultFS 写进 hdfs-site.xml,这种错误启动时不会马上报错,但你会发现访问 HDFS 时行为很奇怪。
2.1 hadoop-env.sh:先把 JAVA_HOME 写死
hadoop-env.sh 里要改的核心就是 JAVA_HOME。虽然你已经在 /etc/profile 里配好了 JAVA_HOME,但 Hadoop 自带的一些脚本在通过 SSH 拉起来的时候,可能不会完整继承你终端里的环境变量,所以最稳妥的办法是在 hadoop-env.sh 里直接写死。
找到文件中 JAVA_HOME 那一行,改成你自己的 JDK 路径:
bash复制export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
如果你是 root 用户装的 JDK,并且 /etc/profile 里已经配置生效,这里基本不会出问题。但我更建议在这里显式写出来,因为后续如果要把 Hadoop 配置成开机自启或者交给 systemd 托管,脚本执行环境不一定能拿到系统级环境变量。
还有一个容易被忽略的项是 HADOOP_HOME,如果 hadoop 命令本身能执行,说明 HADOOP_HOME 已经没问题了,但保险起见也可以顺手在 hadoop-env.sh 里加上,我自己的服务器上就是这么干的,省得后面写 mapreduce.application.classpath 时出现路径变量为空的诡异报错。
2.2 core-site.xml:HDFS 入口和临时目录都在这里
core-site.xml 里必须配置 fs.defaultFS,这个值决定了 Hadoop 集群的默认文件系统地址,也决定了你执行 hdfs dfs 命令时连到哪里。伪分布式模式下填 localhost:9000 就对了:
xml复制<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/tmp</value>
</property>
</configurati
