☰
Hadoop单机非分布式安装教程:本地模式配置与WordCount运行
2026/10/8 20:01:47 网站建设 项目流程

1. 安装前必须想清楚的几件事

1.1 单机非分布式到底是哪种模式

我把标题里的“Hadoop单机(非分布式)”先跟新手说透。Hadoop不是只有一个安装模式,官方文档里一共给了三种:本地模式(Local/Standalone)、伪分布式(Pseudo-Distributed)、完全分布式(Fully-Distributed)。很多人一搜教程,上来就让你改 core-site.xml、hdfs-site.xml、启动 NameNode 和 DataNode,那是伪分布式的玩法。单机非分布式,指的是最朴素的本地模式:所有进程都跑在一台机器、一个 JVM 里,不使用 HDFS 做存储,也不启动 YARN 调度,MapReduce 任务直接通过本地文件系统读写数据。

这个模式最核心的价值,不是让你搭出一个能对外提供服务的“大数据平台”,而是让你用最小的成本理解 MapReduce 的运行逻辑、验证自己的代码逻辑、跑通官方自带的示例程序。对企业里的真实业务来说,单机模式当然跑不动海量数据,但对课程设计、源码学习、环境验证、以及第一次接触 Hadoop 的人来说,这是效率最高的起步方式。

我见过不少新手一上来就照着“集群搭建”的教程折腾,踩了两个小时 SSH 免密、配置了一堆 XML,最后卡在 DataNode 起不来,连 Hadoop 长什么样都没见到,信心直接被打没了。这篇文章就把单机模式怎么装、怎么配、怎么验证、怎么跑通第一个任务讲完,你再决定要不要往伪分布式和集群走。

1.2 装之前先对号入座,看看你要装什么

安装前需要明确自己的用途,因为用途直接决定了版本选型。如果你是做课程设计,只需要跑通 WordCount 示例、验证 Mapper 和 Reducer 的写法,那当前最新的稳定版 Hadoop 就可以。如果你跟着某些老教材走,教材里用的是 2.x,那建议还是装 2.x 的对应大版本,否则教材里的配置路径、端口号、命令都会对不上。

官方下载页面里有两个发行线:3.3.x 和 3.4.x。我个人的建议是优先选择 3.3.x 系列,原因有两个:一是 3.3.x 经过了更长时间的生产验证,社区反馈的问题、修复的补丁都沉淀得比较充分;二是很多第三方工具和教程还停留在这条版本线上。3.4.x 也不是不行,只是它相对较新,在某些配套生态上可能还没完全跟上。

还有一个很重要的前置依赖:JDK。Hadoop 3.x 要求 JDK 8 或 JDK 11,千万不用急着上 JDK 17。虽然 Hadoop 在后续版本里也做了 JDK 17 的适配尝试,但官方推荐的稳定组合仍然是 JDK 8。我踩过这个坑:用 JDK 17 跑 Hadoop 3.3.x,启动时直接报“Unsupported class file major version”错误,折腾半天才反应过来是编译字节码版本不兼容。所以听话,老老实实装 OpenJDK 8,这是最省心的选择。

Linux 发行版方面,CentOS 7、CentOS 8 Stream、Ubuntu 20.04、Ubuntu 22.04 我都实测过,都可以顺利装上。具体命令会有区别(比如 CentOS 用 yum,Ubuntu 用 apt),但核心步骤完全一致。本文主要以 CentOS 系列的命名习惯来讲,Ubuntu 用户把包管理器命令对应替换就行。

1.3 准备工作清单,缺一个后面都要返工

安装之前,把下面这几样东西准备好,比直接动手敲命令重要得多。

  • 一台干净的 Linux 虚拟机或云主机,配置不用高,2 核 4G 内存就够了,磁盘留 30G 以上。
  • JDK 8(OpenJDK 8),提前装好并确认java -version能正常输出。
  • Hadoop 3.3.x 的二进制压缩包,官方下载地址是 archive.apache.org,文件名类似hadoop-3.3.6.tar.gz。
  • 一个非 root 用户。这个非常关键,很多人习惯直接用 root 操作,后面启动 Hadoop 时会遇到权限告警或者进程起不来的问题,所以我后面专门用一节讲这个。
  • 一个合理的目录规划,比如统一放在/opt或者~/app下面,不要东一个目录西一个目录。

注意:Hadoop 虽然有 Windows 版本的支持说明,但原生 Linux 环境下的稳定性远好于 Windows。如果你是 Windows 本机用户,要么装 WSL,要么在 VMware 里装一个 Linux 虚拟机,不要在 Windows 原生环境里硬磕。

2. 环境准备与安装实操

2.1 创建专用用户,避免权限牵制

这一步是很多教程忽略但实际极其重要的。Hadoop 的启动脚本、运行日志、临时文件服务都涉及大量文件读写,如果用 root 跑,虽然大多数功能能硬跑起来,但会出现两个典型问题:一是 HDFS 会把安全模式异常、启动失败这类问题抛给你,明明配置没错却找不到原因;二是后续做伪分布式或者集群扩展时,不同节点之间的用户和权限不一致会导致各种奇怪的连接失败。

我通常在虚拟机里执行这样的操作:

useradd -m -s /bin/bash hadoop passwd hadoop mkdir -p /opt/bigdata chown -R hadoop:hadoop /opt/bigdata

创建hadoop用户,把软件统一放到/opt/bigdata下,并把目录所有权交给这个用户。之后所有安装、配置、启动操作都切换到这个用户下完成。这样做的最大好处是,你的操作环境和生产环境的行为一致,root 带来的权限遮蔽效应不会掩盖真正的问题。

2.2 JDK 安装与验证

如果你已经确定系统里没有 JDK,直接安装 OpenJDK 8。CentOS 7 上执行:

yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

Ubuntu 上执行:

apt install -y openjdk-8-jdk

装完之后,验证的关键不是只看java -version,还得看javac -version。因为 Hadoop 某些脚本会检查编译器是否存在,特别是你要自己编译 Java 代码时,只有 JRE 没有 JDK 会导致javac找不到。

然后在/etc/profile或者用户级的~/.bashrc里追加:

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export PATH=$JAVA_HOME/bin:$PATH

注意:不同发行版 JDK 路径不一样,不要照抄上面的路径,先执行which javac和readlink -f $(which javac)找到实际安装路径,再填到 JAVA_HOME 里。

2.3 Hadoop 下载、解压与目录规划

Hadoop 的下载最好到官方 archive 地址,不要随便在第三方网盘下,一来版本可能被改过,二来解压后跑出莫名奇妙的错误很难溯源。下载命令:

cd /opt/bigdata wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -zxvf hadoop-3.3.6.tar.gz ls -lh hadoop-3.3.6/

解压完成后,建议做两件事。第一,目录改个短一点的名字,方便环境变量书写和记忆。第二,确认解压出来的目录结构包含bin、etc、share、lib这几个关键目录,尤其是share/hadoop/mapreduce/下有没有示例 jar 包,后面验证单机模式跑 WordCount 就靠它。

mv hadoop-3.3.6 hadoop

我习惯把最终目录放在/opt/bigdata/hadoop。这个路径要保持稳定,不要装完再频繁移动,否则环境变量、脚本里写死的绝对路径会让你追错到怀疑人生。

2.4 环境变量配置,最容易出错的细节

单机模式下,Hadoop 对环境变量的依赖比很多人想象的要高。打开~/.bashrc,把下面几行加进去:

export HADOOP_HOME=/opt/bigdata/hadoop export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop

然后执行:

source ~/.bashrc hadoop version

正常情况下你会看到类似这样的输出:

Hadoop 3.3.6 Source code repository ... Compiled by ... Compiled with protoc 3.7.1

这里有一个新手极其容易忽略的点:Hadoop 内部的脚本,尤其是start-dfs.sh、hadoop-daemon.sh这类,是通过$HADOOP_HOME去找配置和依赖的。如果这个变量没生效,哪怕你在终端里敲hadoop有反应,启动守护进程时也一样会报“找不到 HADOOP_HOME”的错误。所以配置完环境变量后,最好新开一个终端窗口测试,不要只在当前窗口里 source 就认为万事大吉。

2.5 目录规划、日志目录与临时文件目录

虽然不是强制的,但我强烈建议在安装后手动创建数据目录和日志目录,并把所有权切给 hadoop 用户:

mkdir -p /opt/bigdata/hadoop/tmp mkdir -p /opt/bigdata/hadoop/logs chown -R hadoop:hadoop /opt/bigdata/hadoop

单机模式默认不需要专门配置 HDFS 的 name 和 data 目录,但日志目录总是有用的。后面跑 MapReduce 任务如果出异常,日志里的堆栈信息是你唯一的排查线索。

3. 单机模式的关键配置与验证

3.1 本地模式的配置文件到底改哪些

这是整个安装过程里最容易让人迷惑的部分。网上大量教程会引导你修改core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml四个文件,配置 fs.defaultFS、namenode 地址、副本数、yarn 节点信息等——那是伪分布式的做法。真正的本地模式,也就是单机非分布式,这些文件都可以保持默认状态,不需要做任何修改。

我见过最惨痛的案例:一个读者按照集群教程,把 fs.defaultFS 配成了hdfs://localhost:9000,然后单机模式跑示例,结果任务报“Connection refused”,因为他根本没有启动任何 HDFS 进程。这就是配置不对应的典型错误。

所以这里需要记住一个重要原则:本地模式要求 Hadoop 不依赖任何外部守护进程。所有输入输出都通过本地文件系统完成,MapReduce 框架在单个 JVM 内运行。你在本地模式下要做的最小配置,其实是让 Hadoop 找到你的 JDK。

3.2 编辑 hadoop-env.sh,把 JAVA_HOME 写死

在$HADOOP_HOME/etc/hadoop/hadoop-env.sh这个文件里,Hadoop 会去读取 JAVA_HOME 来启动 JVM。虽然你在~/.bashrc里已经配置了 JAVA_HOME,但 Hadoop 某些启动脚本在特殊环境下可能读不到用户级环境变量,最稳妥的做法是直接把这个文件里的 JAVA_HOME 写死。

打开文件找到 JAVA_HOME 那一行(通常在文件前半部分),改成:

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk

注意:这里不要加$()或者反引号去动态获取路径,直接写绝对路径。原因很简单:启动 Hadoop 守护进程时,脚本运行环境有时并不继承你交互式 shell 的 PATH,靠命令动态找 javac 不可靠。这是个用血的教训换来的经验,因为start-dfs.sh那种脚本在 PATH 不完整时,动态获取路径往往会得到空值,然后报JAVA_HOME is not set。

3.3 验证安装正确性:hadoop version 与 which hadoop

配置完成后,第一波验证分成两步:表层验证和环境变量验证。

hadoop version which hadoop

hadoop version能正确输出版本信息,说明主程序本身可用;which hadoop输出/opt/bigdata/hadoop/bin/hadoop(而不是 aliase 或者别的目录),说明环境变量生效。这两条都通过,整个安装环节就结束了。

别小看这个动作。我接手过不少“装好了但是跑不起来”的求助,一半以上是环境变量存在两个 Hadoop:系统自带的旧版本和手动安装的新版本混在一起,shell 里输入hadoop命中的根本不是你想用的那个路径。

3.4 使用 hadoop classpath 检查依赖完整性

还有一个容易被忽略的命令:

hadoop classpath

这个命令输出一大堆 jar 包路径。本地模式下,如果你需要编译并运行自定义的 Mapper/Reducer 程序,就需要把这些 classpath 全部抄到javac和java命令里。常见错误是只把hadoop-core的 jar 放进去,结果编译时报Error: package org.apache.hadoop.fs does not exist。

建议把hadoop classpath的输出保存到一个文件里,之后写脚本时会非常方便:

hadoop classpath > /tmp/hadoop_classpath.txt

这是本地模式跑自写 Java 程序的关键动作,等你自己写 MapReduce 的时候会体会到这个文件有多省事。

4. 跑通第一个 MapReduce 任务

4.1 官方示例 WordCount 的运行过程

安装配置完成后,拿官方自带示例做一次完整的端到端验证。Hadoop 安装包自带了示例 jar,路径在:

$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar

先准备一个输入文件:

mkdir -p /tmp/input echo "hello world hadoop hadoop hello" > /tmp/input/words.txt

然后执行:

hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /tmp/input /tmp/output

执行过程会在终端刷出一大堆日志。这里有个很多人会误判的点:日志里出现Map 100% Reduce 100%不代表任务成功,只是进度条跑完了,真正的成功标志是最后一句:

Job Complete: job_XXXX_0001

只有出现Job Complete字样才说明整个任务跑通。之后查看输出:

cat /tmp/output/part-r-00000

输出应该有:

hadoop 2 hello 2 world 1

4.2 本地模式下的执行流程解密

单机模式下,输入目录、输出目录都在本地文件系统,没有 NameNode、没有 DataNode、没有 ResourceManager,也没有 NodeManager。hadoop jar命令直接在本地启动一个 JVM,在 JVM 内部模拟整个 MapReduce 的执行流程。

这也解释了为什么单机模式下 Spark 或 Flink 类框架能把“本地模式”当成开发调试利器,而 Hadoop 生态圈里大多数人更喜欢直接上伪分布式。

本地模式的执行逻辑大致是:框架读取输入文件的分片信息,为每个分片创建 Map 任务;Map 输出的中间结果直接落在本地磁盘;Reduce 任务读取这些中间结果,汇总后写入输出文件。对单机模式来说,这一切都在一个进程里完成,没有网络传输、没有任务调度、也没有数据冗余。它快、简单、容易调试,但也仅此而已。

4.3 复现练习:自己写一个最简 WordCount

作为验证安装的进阶动作,建议你亲手写一个 WordCount。这不仅能验证 JDK 和 Hadoop 的配合,还能为后面的课程设计打基础。

创建一个 Java 文件:

import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.fs.Path; public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, one); } } } public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } public static void main(String[] args) throws Exception { Job job = Job.getInstance(); job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } }

编译和运行:

export CLASSPATH=$(hadoop classpath) javac -cp $CLASSPATH WordCount.java java -cp $CLASSPATH:. WordCount /tmp/input /tmp/output2

这块的操作门槛比前面所有步骤都高,但值得做。因为只有亲手编译过一次,你才能真正理解 Hadoop 的 Java API 是怎么跟框架打交道的,后面再学 Spark 或者其他大数据组件,很多概念都能触类旁通。

4.4 输出目录已存在,这个坑你先记住

运行 MapReduce 任务时,如果输出目录已经存在,不管里面有没有内容,框架都会直接报错:

Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException

这是 Hadoop 故意设计的安全机制:防止任务重跑时把上一次的结果静默覆盖掉,导致你误以为跑出了新结果。所以每次重新运行前,先删掉输出目录:

rm -rf /tmp/output

这条命令值得刻在脑子里,因为后面你自己写代码练习时会无数次遇到这个报错。

5. 常见问题排查与配置避坑记录

5.1 JAVA_HOME 相关报错

报错信息原因解决方案
JAVA_HOME is not sethadoop-env.sh 里没有配置 JAVA_HOME编辑etc/hadoop/hadoop-env.sh,写死 JDK 绝对路径
Unsupported class file major versionJDK 版本过高,字节码版本不兼容更换为 JDK 8
Error: Could not find or load main classclasspath 不完整,或者 jar 包名错误用hadoop classpath配置 CLASSPATH

5.2 任务提交过程中的异常与日志定位

单机模式下任务提交失败,最直接的排查手段就是看终端输出的异常堆栈。它不像是伪分布式环境,错误可能藏在多个进程日志里要到处翻。本地模式的错误输出基本都在控制台,所以别一看到大段 ERROR 就慌,往前翻找到第一行Caused by,那才是问题的根源。

我还遇到过一种情况:wget 下载 Hadoop 压缩包时网络中断,解压时报磁盘空间不足或者压缩包损坏。这个通常在解压阶段就能发现,但有些人会忽略解压日志里的 warning。稳妥做法是解压前用du -sh确认压缩包大小和官方页面标注一致,解压后运行hadoop version验证完整性。

5.3 本地模式下不需要碰的配置项

下面这些配置是伪分布式或集群模式下才会用到的,单机模式如果照抄配置,反而会引入问题:

配置项伪分布式/集群用途本地模式建议
fs.defaultFS指向 HDFS 地址不配置
dfs.replicationHDFS 副本数不配置
yarn.nodemanager.*YARN 资源调度不配置
mapreduce.framework.name指定 yarn 或 local默认 local 即可

5.4 网络搜索热词背后的隐藏需求

我在整理这篇文章时参考了大量相关搜索热词,比如“hadoop 伪分布式搭建”、“hadoop 和 zookeeper 整合实战”、“hadoop 的 docker 镜像”、“如何在虚拟机上安装 hadoop”等。这些热词暴露了两个信息:一是大量学习者装完单机模式后会立刻冲向下一个目标,也就是伪分布式和集群;二是很多人对虚拟机环境里的 Hadoop 安装存在长期疑惑。

对应的需求我在这里稍微点拨一下:如果你已经掌握了本地模式,下一步做伪分布式会比较顺畅,因为核心变化就是修改四个 XML 配置文件、配置 SSH 免密、然后启动 HDFS 和 YARN 的守护进程。如果你不想在虚拟机里折腾系统环境,用 Docker 镜像也可以,但 Docker 里跑 Hadoop 需要把宿主机的端口映射和数据卷挂载考虑清楚,难度并不比虚拟机低。“Hadoop 和 Zookeeper 整合”则是后期做 HA 高可用才会碰到的需求,本地模式阶段完全不必关心。

6. 单机模式玩熟之后,如何转向伪分布式

6.1 本地模式、伪分布式的区别对照

维度本地模式伪分布式
进程数量单 JVM 进程内完成多守护进程(NameNode、DataNode、ResourceManager、NodeManager)
文件系统本地磁盘HDFS
配置文件无需修改需要修改 core-site.xml 等配置
适用场景学习、开发调试、代码逻辑验证模拟真实集群环境,功能演示
资源消耗极低较高,建议 4G 以上内存

这个表可以当作一个检查清单:如果你从本地模式往伪分布式迁移,对照着逐项确认就可以了。

6.2 迁移需要的三项准备

从本地模式迁移到伪分布式,不需要重新安装 Hadoop,也不用换 JDK,只需要做三件事。

第一,配置 SSH 免密登录。伪分布式要求本机可以通过ssh localhost无密码登录,因为 Hadoop 脚本会通过 SSH 启动守护进程。执行:

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

第二,修改四个配置文件。伪分布式的经典配置网上随处可见,其中最关键的是core-site.xml里的fs.defaultFS指向hdfs://localhost:9000,以及hdfs-site.xml里的dfs.replication设置为 1。

第三,格式化 NameNode。首次启动 HDFS 前必须执行:

hdfs namenode -format

这一步不需要每次重启都做,只在初始化时做一次就行。如果反复格式化,可能导致 DataNode 和 NameNode 的 clusterID 不一致,启动后 DataNode 一直连不上,这是伪分布式最经典的坑之一。

6.3 伪分布式常见的坑

伪分布式看起来和本地模式只差了几步配置,实际跑起来问题多很多。DataNode 起不来的头号原因就是 clusterID 不一致,其次是端口被占用、内存不足、权限不对。我的建议是:如果你只是做课程设计或者学原理,本地模式完全够用;如果你想体验真实的 HDFS 文件操作,展示 NameNode/DataNode 的状态界面,再上伪分布式。

从实践角度来说,本地模式培养的是“程序思维”,伪分布式培养的是“运维思维”。

7. 实际安装过程中记录的几条真话

最后直接说结论。Hadoop 单机非分布式的安装,看似简单——解压、配环境变量、跑个示例——但真正有价值的不是“装好”,而是“装的过程中你理解了 Hadoop 的运行机制”。本地模式下你敲下hadoop jar命令的那一刻,应该能大致想象出 JVM 里发生了什么:输入被读入、Map 方法逐行处理、中间结果落盘、Reduce 拉取聚合、最终写文件。有了这个画面,后面所有分布式概念都有落脚点。

我实际安装过程中积累的几个小经验,供你参考。

第一,不要贪新。Hadoop 不必追求最新的 3.4.x,选 3.3.x 搭配 JDK 8,遇到问题搜得到的解决方案多得多。

第二,目录统一管理。所有大数据相关的软件统一放在一个父目录下,比如/opt/bigdata,后续安装 Spark、Hive、Kafka 时,彼此之间依赖路径清晰,排错省一半时间。

第三,每完成一个步骤,立刻做一次验证,不要攒到最后一起验证。环境变量配置完,马上开新终端跑hadoop version;配置改完,立刻跑一次示例任务。问题出现时离现场越近,定位成本越低。

还有一点我觉得值得专门强调:整个安装过程中那些“报错”,其实才是最有价值的收获。不要害怕它们,反而是那些一路绿灯平滑装完的人,转过头去配伪分布式时会暴露理解上的空缺。因为单机模式能一路绿灯,不代表你真的懂 Hadoop 在干什么。

如果你跟着本文从头到尾走了一遍,现在你的机器上应该已经具备一个能跑 MapReduce 示例的 Hadoop 本地环境了。从命令行上看,它只是一个小工具;但当你往里面写第一个自定义 MapReduce 程序、调第一个参数、解第一个异常时,你才真正开始进入大数据生态的世界。

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

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

立即咨询