☰
Hadoop单机与伪分布式模式实战:从零搭建到跑通WordCount
2026/10/7 3:18:43 网站建设 项目流程

刚接触大数据的人,十有八九第一关就卡在 Hadoop 环境搭建上。网上教程要么直接甩一堆命令让你复制粘贴,要么就默认你已经是什么运维老手,结果照着敲完,JPS 一看少了进程,日志翻半天找不到问题在哪,心态直接崩掉。这篇东西不聊那些虚的,就聚焦在 Hadoop 的单机模式和伪分布式模式上,把两种模式到底是怎么回事、每一步为什么这么配、哪些地方特别容易踩坑,用实际操作经验给你捋清楚。你只要能跟着走一遍,装完不仅能跑起来,还能知道它为什么能跑起来。

这套环境是我这几年反复搭建过几十次之后的完整落地流程,适用于 Hadoop 2.x 和 3.x 的常见版本,也是当前课程实验、毕业设计、个人练手最通用的组合。我尽量把配置原理也讲明白,保证你下次换台机器,或者换一个版本,也能独立搞定,而不是只会复制命令。

1. 动手之前,先把单机和伪分布式这两件事搞清楚

1.1 单机模式(本地模式):别小看它,这是跑通代码最快的路

Hadoop 的所谓单机模式,英文叫 Standalone Operation 或者 Local Mode,这是最基础的运行模式。它的特点非常极端:不用启动任何守护进程,不用配 HDFS,就连 HDFS 都不存在,整个 Hadoop 就像一个普通的 Java 库一样运行在你本机的文件系统上。

这种模式主要用途是本地开发和调试 MapReduce 程序的逻辑。你写了一个 WordCount,想验证一下代码里有没有低级错误,直接跑就行,数据输入、输出都在本地磁盘。我第一次接触 Hadoop 的时候也觉得这种模式有点“过于简陋”,但后来踩过坑才发现,这种模式其实是最适合学习 MapReduce 计算模型底层的。因为当你把中间过程打出来看的时候,没有分布式那一堆调度开销,每一行逻辑都非常清晰。

单机模式的好处就是绝对简单,但缺点也很致命:它完全不能体现 HDFS 分布式存储和 YARN 资源调度的工作方式。如果你只是跑通了 WordCount,就以为学会了 Hadoop 分布式,那后面基本会露怯。所以单机模式一般被认为是环境准备阶段的第一级台阶,真正要感受 Hadoop 的“分布式味道”,还得靠伪分布式。

1.2 伪分布式:一台电脑硬要演一出集群的戏

伪分布式(Pseudo-Distributed Mode)是学习 Hadoop 最核心的阶段。所谓“伪”,是指它只在一台物理机器上运行,但通过配置,让 NameNode、DataNode、ResourceManager、NodeManager 这些角色都以独立进程的方式启动,各自监听不同的端口,模拟出一个“最小集群”。

我习惯打个比方:单机模式就像你一个人在家自言自语,伪分布式就相当于你一个人分饰三角,在家里演一出对手戏。虽然演员都是你自己,但角色分开了,台词的你来我往、调度逻辑都和真实剧组一样。理解了这句话,你就掌握了伪分布式设计的初衷——让学习者在没有多台服务器的情况下,仍然能完整体验 HDFS 读写、MapReduce 提交、YARN 资源调度这些分布式核心流程。

这也是为什么很多高校的实验、课程设计、毕设系统,都要求用伪分布式来跑的原因。它占用的资源很少(内存控制在 1GB 内的机器也能勉强跑),但是功能上是完整闭环的。

1.3 为什么网上一搜 Hadoop 安装教程,十篇有九篇版本都对不上

这个我必须单独拿出来说,因为太容易把人带沟里了。网上教程五花八门,有的教 Hadoop 1.x,有的教 2.x,有的直接上 3.x,每个版本的配置项名称、默认端口、默认文件目录都有差异。更麻烦的是,很多教程是基于某个特定 Linux 发行版、特定 JDK 版本写的,你换个环境就是各种看不懂的报错。

我的建议是:装之前先确定一个版本组合,然后死死锁住它,所有组件(JDK、Hadoop)都用配套的版本,不要混搭。本文以当前最主流的Hadoop 3.3.6 + OpenJDK 8组合为例。这个组合经过了大量生产环境和课程实验验证,兼容性最好,网上报错帖子也最多,出问题容易搜到解决方案。如果非要追求新奇用 JDK 11 或 17,也不是不行,但你会遇到一些模块权限和编译问题,属于自己给自己加难度。

注意:Hadoop 3.x 版本中,默认端口、部分配置项名称(例如mapreduce.framework.name)位置有所变化,以你解压的 Hadoop 版本官方文档为准。但我下面给的配置是通用的,直接能跑。

2. 环境准备:装之前把这四件事看清楚,省得后面折腾

2.1 Java 版本别乱选:JDK 8 是 Hadoop 3.x 的“最佳稳定搭档”

Hadoop 底层是 Java 写的,所以 JDK 是第一依赖。很多人死在第一步就是因为 JDK 版本不对。Hadoop 3.3.x 官方文档明确要求Java 8 或 Java 11,但我要跟你说的实话是:生产环境用 Java 8 最多,社区支持最广泛,遇到问题也最容易被检索到。OpenJDK 8 无论在兼容性还是资源占用上,对学习和实验场景都是最优选择。

装 JDK 的方式很简单,这里只说 Linux 环境(CentOS 7/8、Ubuntu 20.04/22.04 均可),个人强烈建议用tar.gz包手动安装,而不是用yum install java-1.8.0。为什么?因为很多发行版自带的 openjdk 是简化版,某些环境变量路径跟 Hadoop 启动脚本预期的不一致,容易引发奇怪的找不到类错误。手动解压放在/usr/local/java下,路径完全可控。

# 以 OpenJDK 8 为例(x86_64 架构) tar -zxf jdk-8u202-linux-x64.tar.gz -C /usr/local/ mv /usr/local/jdk1.8.0_202 /usr/local/java

然后配置环境变量:

# /etc/profile 末尾追加 export JAVA_HOME=/usr/local/java export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

改完执行source /etc/profile,java -version能看出是 1.8 开头的版本就对了。这里有个常见误区:CLASSPATH 这个变量在 Hadoop 3.x 里不是必须的,但留着也无妨。因为 Hadoop 启动脚本内部会自己拼 classpath,你手动设的那些反而可能在个别命令下产生干扰。如果后面出现奇怪的类加载问题,可以先把 CLASSPATH 注掉再试试。

2.2 伪分布式必须配 SSH 免密登录:这是启动集群的前置条件

伪分布式虽然所有进程都在本机,但 Hadoop 的脚本设计是按“集群”思路走的。NameNode 要通过 SSH 连接到 localhost 去启动 DataNode,ResourceManager 也要通过 SSH 连到 NodeManager。如果 SSH 登录每次都要输密码,那集群压根起不来。所以必须配置 SSH localhost 免密登录。

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys

这里注意两个坑:

  • ssh-keygen生成秘钥时,-P ''表示空密码,如果你敲了回车没写这个参数,它会默认让你设密码,就免密不了了。
  • authorized_keys的权限必须是 600,~/.ssh目录权限最好是 700。权限过宽的话,SSH 出于安全策略会直接拒绝读取这个文件,表现为“明明公钥加进去了,还是要密码”。

配置完可以验证一下:

ssh localhost

如果不需要密码直接进入,并且exit能退出回来,这一步就算过关了。我之前带过很多人,这一步没验证就直接往下走,最后start-dfs.sh报 “Permission denied (publickey,password)” 错误,还以为 Hadoop 装错了,其实全是 SSH 没配好的锅。

2.3 用户和目录规划:别用 root 跑 Hadoop,这是给自己埋雷

我理解很多人拿到一台云服务器或者虚拟机,习惯性就用 root 操作一切。但 Hadoop 的很多脚本对目录权限有要求,而且部分版本在 root 用户下执行会直接警告或者报错(例如 HDFS 的dfs.datanode.data.dir目录权限检查)。更关键的是,用 root 跑分布式服务本身就是安全风险,万一误删了系统目录,后悔都来不及。

所以务必创建一个专用用户,比如叫hadoop:

useradd hadoop passwd hadoop

后续所有安装、配置、启动操作,都在这个用户下进行。这样做的好处还有一条:如果后面 HDFS 数据目录被污染了,直接删除整个临时目录,不会影响系统其他文件。别问我怎么知道这有多重要的,等你 DataNode 起不来需要清空dfs.name.dir和dfs.data.dir的时候,就会回来感谢我这个建议了。

3. 安装配置全过程:从解压到跑起伪分布式

3.1 下载 Hadoop 发行版:从 Apache 镜像站选一个近的就行

Hadoop 的官方下载地址是 Apache 提供的镜像列表,国内一般选择清华源或者华为云镜像,速度快且稳定。下载时注意选.tar.gz二进制包,别下成源码包,源码包还要自己编译,纯属给自己找事。

wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -zxf hadoop-3.3.6.tar.gz -C /usr/local/ mv /usr/local/hadoop-3.3.6 /usr/local/hadoop chown -R hadoop:hadoop /usr/local/hadoop

解压完成后,先别着急配置,把 Hadoop 加入环境变量:

# /etc/profile 追加 export HADOOP_HOME=/usr/local/hadoop export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop

然后你需要改一个关键文件:$HADOOP_HOME/etc/hadoop/hadoop-env.sh,这里面写死了 JVM 启动参数。老版本 Hadoop 会在文件里默认找JAVA_HOME,新版本更智能,但为了确保万无一失,还是手动指定一下:

# 在 hadoop-env.sh 中找到 JAVA_HOME 行 export JAVA_HOME=/usr/local/java

很多教程都不提这一步,导致启动时一直报 “Error: JAVA_HOME is not set and could not be found.” 这种低级错误。提前改了能省半小时排错时间。

3.2 单机模式配置:几乎不用配,跑通就算入门

单机模式是真的简单到“没什么可配的”。因为它是 Hadoop 的默认模式,也就是说,你把环境变量配好之后,什么都不用动,直接跑官方示例就可以了。Hadoop 自带了好几个示例 JAR,最经典的是 WordCount:

mkdir /home/hadoop/input echo "hello hadoop world" > /home/hadoop/input/test.txt hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /home/hadoop/input /home/hadoop/output

跑完去/home/hadoop/output目录下看part-r-00000文件,里面应该能看到每个单词出现了几次。如果这步成功,说明你的 JDK、环境变量、Hadoop 核心库全部没有问题。

有一个值得知道的细节:单机模式下,输出目录/home/hadoop/output必须是不存在的,Hadoop 为了防止覆盖数据,会报Output directory ... already exists的错误。所以每跑一次之前记得删掉旧输出目录。这个小机制在后面的伪分布式、真分布式里也一样生效,是 Hadoop 的一个安全设计。

注意:单机模式下输入路径写的是本地路径(/home/hadoop/input),Hadoop 会直接从本地文件系统读取,完全不涉及 HDFS。这个模式和伪分布式的输入输出路径体系完全不同,别搞混。

3.3 伪分布式配置:四个配置文件,每个参数都值得你搞懂

进入正题。伪分布式的核心配置在$HADOOP_HOME/etc/hadoop/下面的 XML 文件里。很多初学者看到 XML 就头大,其实只需要改四个文件,每个文件里的参数也就三五个,搞清楚就行。

第一个:core-site.xml

这个文件配置 Hadoop 的全局属性,最关键的是默认文件系统地址:

<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/tmp</value> </property> </configuration>

fs.defaultFS决定了你后面用hdfs dfs -ls /这种命令时,默认连的是哪个 HDFS 集群。伪分布式里就用hdfs://localhost:9000。hadoop.tmp.dir是 NameNode、DataNode 存放元数据和数据块的根目录。如果你不设置,它会默认取/tmp目录,而系统重启后/tmp会被清空,你辛辛苦苦 format 的 NameNode 信息就没了,又得重新来一遍。所以必须改成你自己的永久目录。

第二个:hdfs-site.xml

这个文件配置 HDFS 的相关属性。伪分布式必须设置的是副本数,因为只有一台 DataNode,默认的 3 个副本会一直报资源不足的警告:

<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>

如果你愿意多了解一点,还可以配置 NameNode 和 DataNode 的存储目录。默认它们会放在hadoop.tmp.dir下的dfs/name和dfs/data子目录里。建议显式指定,因为后续排查问题时你心里有底,知道数据到底存在了哪里:

<property> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadoop/tmp/dfs/data</value> </property>

第三个:mapred-site.xml

这个文件配置 MapReduce 的运行框架。伪分布式里必须指定为 YARN,这样提交的任务才会交给 YARN 去调度:

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

在 Hadoop 2.x 及以前,这个文件默认叫mapred-site.xml,但是 Hadoop 3.x 中仍然保留这个文件名。有的教程会让你复制mapred-site.xml.template,在 3.x 版本里已经不自带 template 文件了,直接新建就行。

第四个:yarn-site.xml

YARN 负责资源调度,配置核心是让 ResourceManager 跑在 localhost:

<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>localhost</value> </property> </configuration>

yarn.nodemanager.aux-services这个参数比较容易忽略,但它是 MapReduce 任务在 NodeManager 侧能够正常进行 shuffle 阶段的关键。如果不配置或配错,你的 MapReduce 任务会一直卡在 Map 100% Reduce 0% 的状态,特别气人。

四个文件配完后,建议做一件事:cat一下每个文件,确认 XML 标签闭合、没有把配置写到<configuration>外面。XML 格式一个标签错误,整个文件都会被忽略,而 Hadoop 启动时不一定报错,只会静默用默认值,排查起来一头雾水。

4. 启动、验证和资源管理:你离“跑起来”只差三步

4.1 格式化 NameNode:只有第一次启动前需要做

配置完成后,启动 HDFS 之前,必须先格式化 NameNode。这个操作会初始化 HDFS 的元数据目录:

hdfs namenode -format

看到日志里出现successfully formatted字样就成功了。但这里有几个血泪教训要告诉你:

  • 格式化只做一次。如果你反复格式化,会导致 NameNode 的 clusterId 和 DataNode 的 clusterId 不一致,DataNode 启动后会被拒绝注册,表现为Incompatible clusterIDs错误。
  • 如果实在需要重新格式化(比如数据目录被污染),一定要先删除hadoop.tmp.dir下所有旧数据,再格式化,否则大概率出现刚才说的 clusterID 不匹配问题。
  • 格式化过程会生成一组随机 ID,这些 ID 就是 HDFS 文件系统的“身份证”。DataNode 启动时会带着这个 ID 去和 NameNode 校验,对不上就拒绝服务。

4.2 启动 HDFS 和 YARN:命令就两条,但观察要细致

格式化完成后,依次启动 HDFS 和 YARN:

start-dfs.sh start-yarn.sh

如果是用hadoop用户操作,中间可能还会提示 SSH 确认,因为首次连接 localhost 需要确认 host key,选 yes 就行。

启动完成后,用jps命令检查 Java 进程。这个命令是所有 Hadoop 学习者必须掌握的“体检工具”。正常情况下你应该看到以下 6 个进程:

进程名角色
NameNodeHDFS 主节点,管理元数据
DataNodeHDFS 数据节点,存储数据块
SecondaryNameNode辅助 NameNode 合并编辑日志
ResourceManagerYARN 资源调度主节点
NodeManagerYARN 节点管理器,执行任务

如果少了任何一个进程,都说明有问题。比如没有 DataNode,大概率是 clusterID 不匹配;没有 ResourceManager,可能是 yarn-site.xml 没配对;SecondaryNameNode 在伪分布式里也是会启动的,如果你没看到它,检查一下是不是hdfs-site.xml里配置了dfs.namenode.secondary.http-address冲突。

启动后还可以通过浏览器访问 HDFS 和 YARN 的 Web 界面,看到图形化的集群状态:

  • HDFS 管理界面:http://localhost:9870(Hadoop 3.x 默认端口)。这里能看到 NameNode 状态、DataNode 列表、集群存储容量,最实用的是能通过 UI 直接浏览 HDFS 上的文件。
  • YARN 资源管理界面:http://localhost:8088。这里能看到正在运行和已完成的应用列表,是排查任务是否有异常的重要入口。

如果访问http://localhost:9870打不开,先确认防火墙是否放行了端口。很多人前面一切顺利,结果卡在防火墙这一步,建议直接systemctl stop firewalld(仅限学习环境)或者单独放行 9870、8088、9000 这几个端口。

4.3 先用一个 MapReduce 任务验证集群是否真的“通”了

集群起来了,不代表一定能跑通任务。我强烈建议在配置完成后,跑一个稍微复杂点的测试,验证整个链路是通的:

# 创建 HDFS 根目录下的输入目录 hdfs dfs -mkdir -p /input # 把本地文件上传到 HDFS hdfs dfs -put /home/hadoop/input/test.txt /input/ # 跑 WordCount,输入输出都在 HDFS 上 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /input /output

跑完后查看结果:

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

如果看到了单词计数结果,那恭喜你,你的伪分布式集群已经可以正常工作了。这时候你已经在使用一个“五脏俱全”的分布式文件系统和分布式计算框架了。接下来你完全可以在这个基础上,开启你的大数据开发学习之路。

5. 常见问题与排查技巧实录:这五个坑,我全都替你踩过

5.1 DataNode 起不来,日志里疯狂报 Incompatible clusterIDs

这是伪分布式搭建中最高频的错误之一。原因是 NameNode 格式化时生成了一个新的 clusterID,但是 DataNode 数据目录里保留了旧 ID。常见于你上一次搭建失败后没有清理干净数据,又重新格式化了一次。

解决方案很简单:把所有 HDFS 相关数据目录彻底删掉,然后重新格式化。具体来说:

rm -rf /home/hadoop/tmp/dfs hdfs namenode -format

如果是在虚拟机上操作,我还见过一种情况:你克隆了虚拟机,导致两台机器上的 Hadoop 数据目录完全一样,DataNode 注册时直接被拒。解决方法是把克隆机的/home/hadoop/tmp目录删掉重新格式化一次。

5.2 jps 进程都正常,但 Web 界面打不开

这种情况多半是防火墙。CentOS 7 以上默认防火墙是开启的。学习环境下直接:

systemctl stop firewalld systemctl disable firewalld

然后刷新浏览器。如果还是打不开,用ss -lntp | grep 9870确认端口是否在监听,如果没监听,说明 HDFS 进程其实没起来,只是 jps 看到了残留进程名。遇到这种情况,直接stop-all.sh,然后看日志重新启动。

5.3 任务提交后卡在 Running Job,Map 到 100% 后一直不动

这种问题绝大部分出在 YARN 的 shuffle 服务没配对。检查yarn-site.xml里的yarn.nodemanager.aux-services是否配置成了mapreduce_shuffle。注意这个值是下划线,不是连字符。拼错一个字符它不会报错,但任务就是跑不完。

还有一个可能是内存不足。伪分布式在一台只有 2GB 内存的机器上,YARN 和 HDFS 同时跑会比较吃力。可以在yarn-site.xml里显式调低资源:

<property> <name>yarn.nodemanager.resource.memory-mb</name> <value>1024</value> </property> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>256</value> </property>

5.4 执行 hadoop 命令时报错:No such file or directory

这个错误很迷惑,因为完全没有提示是哪个文件找不到。我遇到的情况是HADOOP_HOME配成了解压后的目录,但是 Hadoop 内部有些脚本写死了相对路径。如果你把 Hadoop 放在/usr/local/hadoop但解压时目录名是hadoop-3.3.6,查一下是否创建了软链接或者确实把目录改成了hadoop。

另外如果是用 root 用户下载、解压,然后切换到 hadoop 用户,可能会出现hadoop目录的属主还是 root,导致写不了数据。直接:

chown -R hadoop:hadoop /usr/local/hadoop

5.5 跑完 WordCount 输出乱码或者中文异常

这个多半是编码问题。服务器默认的 locale 不是 UTF-8,中文内容处理后变成乱码。解决方式:

# 临时查看 export LANG=zh_CN.UTF-8 # 永久生效 echo "export LANG=zh_CN.UTF-8" >> /etc/profile

不过说实话,学习阶段我建议都先用英文文本测试,中文编码问题留到后面处理 Hive 或者 Spark 时再专门研究。

6. 安装完成之后,下一步建议做这几件事

6.1 学会看日志:比任何教程都管用的排查手段

Hadoop 的日志默认存放在$HADOOP_HOME/logs/目录下。HDFS 的日志文件叫hadoop-hadoop-namenode-<主机名>.log、hadoop-hadoop-datanode-<主机名>.log,YARN 的日志在userlogs目录下。很多新手遇到问题只会贴报错截图,但排查问题最靠谱的方法是直接看日志文件的尾部:

tail -100 $HADOOP_HOME/logs/hadoop-hadoop-namenode-*.log

日志里面有完整的 Java 堆栈,以及进程启动失败的原因。我总结过一条经验:90% 的 Hadoop 环境问题,日志文件里的最后三行就能告诉你答案。养成这个习惯,你会发现自己解决问题的能力瞬间提升一个档次。

6.2 多租户账号规划:以后写代码不跟 Hadoop 环境混在一起

如果你打算长期在这台机器上学习,建议给普通用户独立目录,把 HDFS 的/user/<用户名>目录也建好:

hdfs dfs -mkdir -p /user/hadoop hdfs dfs -chown hadoop:hadoop /user/hadoop

这样你在 HDFS 上的操作就不会把根目录搞得乱七八糟。HDFS 的根目录/是系统级目录,权限控制很严格,别在里面到处建你自己要用的目录。这是个习惯问题,但可以帮你避开以后权限不足的各种花样报错。

6.3 从伪分布式到真分布式:其实你已经懂了九成

装好伪分布式之后,你其实已经具备搭建真分布式集群的能力了。因为真分布式和伪分布式的配置文件几乎一样,区别仅仅是:

  • 把core-site.xml里的localhost换成 NameNode 的主机名。
  • 把hdfs-site.xml里的dfs.replication改为 2 或 3。
  • 在多台机器的slaves文件里(Hadoop 3.x 是workers文件)添加 DataNode 的机器列表。
  • 保持所有机器的 Hadoop 配置同步。

也就是说,你只需要准备几台能互相 ping 通的虚拟机,重复配置几遍本文中的内容,就能组成一个真正意义上的集群。这也是为什么我一直强调“把伪分布式每个参数都弄懂”的原因。你花两小时把这篇内容消化了,后面搭建集群花半天就够了。

装 Hadoop 这件事,本质上跟装任何中间件都一样,难的不是敲命令,而是不知道“为什么这么配”。只要把单机模式和伪分布式的定位、四份 XML 的含义、启动验证流程这三点搞清楚,你的环境就是一台非常可控的学习机器。后面跑 Hive、Spark、Flink 的时候,至少不会被一个基础环境折磨得怀疑人生。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询