Hadoop 3.x单机伪分布式安装指南:从环境配置到WordCount跑通
2026/9/18 9:26:24 网站建设 项目流程

1. 写在前面:为什么要折腾这个“老古董”

如果你是刚接触大数据方向,或者正在被学校课程、面试题里的Hadoop折磨,那我猜你十有八九卡在了第一步:环境装不上,代码跑不起来,网上教程东一篇西一篇,看着热闹,照着做却总能踩出几个新坑。这篇就是冲着这个痛点来的,目标是让你按着步骤走完一遍,Hadoop单机环境能老老实实跑起来,NameNode、DataNode、YARN这些进程全部在线,WordCount样例能够顺利出结果。

注意标题里有“官方手册版”几个字,意思是我不瞎写,所有安装方式、配置参数、启动命令都以Apache Hadoop官方文档为基础,不是网上那些复制粘贴改了又改的旧教程。Hadoop现在最新稳定版已经到3.3.x了,和老的2.x在很多配置项上有差别,网上大量教程还停留在2.x时代,照抄很容易出问题。所以这篇会把3.x版本官方推荐的方式讲透,同时提到2.x和3.x的关键差异,让你遇到旧教程时知道哪里可能是坑。

这篇适合谁看?刚接触Hadoop的学生、准备大数据岗面试的开发者、想在自己笔记本上搭一套完整大数据实验环境的人,以及被公司分配了“把大数据基础环境搞一下”这个任务又没头绪的运维新人。不管你是Windows本子装虚拟机,还是手里有一台闲置Linux服务器或者云主机,都能照着弄。

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

2.1 单机版和“伪分布式”不是一个东西

很多人一提Hadoop安装就想到伪分布式,但严格来说,单机安装配置可以分成两种模式,官方文档里区分得很清楚:

  • 本地模式(Local/Standalone Mode):所有组件跑在同一个JVM里,不启动HDFS守护进程,不配置任何分布式文件系统,主要用于调试MapReduce程序本身。
  • 伪分布式模式(Pseudo-Distributed Mode):在一台机器上分别启动NameNode、DataNode、ResourceManager、NodeManager等独立进程,每个组件是独立JVM,但都跑在同一台机器上。这种模式能完整走通HDFS和YARN的调用链路,适合学习、开发和测试。

这篇教程覆盖后者,也就是完整配置HDFS和YARN的伪分布式环境。这种模式是单机学习最实用的形态,既能体验完整的Hadoop读写流程和提交作业流程,又不用真的凑几台服务器。它和真集群的区别只在于节点数量和物理分布,配置和启动流程几乎完全一致,后面去搭多节点集群,需要改的只是少量配置项。

2.2 别再被“Java版本随便装”坑了

Hadoop本身是Java写的,所以JDK是硬依赖。Hadoop 3.x官方文档明确要求Java 8或Java 11(3.3.x之后对Java 11的支持更完善),Java 17目前不被官方正式支持,装了可能会出现各种奇怪的兼容问题。网上有些教程让你装最新版JDK 17甚至21,我劝你直接跳过这种坑,老老实实装OpenJDK 8。

这里解释一下为什么不能随便用新版:Hadoop底层的HDFS、YARN和MapReduce框架经过多年演进,很多代码依赖的Java API在JDK 9之后被模块化或移除,比如JMX相关的内部接口,用新版JDK跑经常报ClassNotFoundException或者模块访问错误。不是新版本不好,是企业级软件追求稳定,迭代速度天然落后于语言版本更新,这个取舍你理解了就不会再纠结了。

还要注意一个细节:Hadoop 3.x已经不再支持Java 7,如果你还在用很老的CentOS 6加JDK 7的组合,趁早换掉,折腾老环境的成本远高于重装一台新系统。

2.3 系统选择和用户规划:每个坑都是前人趟出来的

Hadoop官方文档主要面向Linux环境,虽然Windows也能跑(需要额外装Winutils),但如果你是第一次装,我强烈建议直接在Linux上操作。最省心的方案是装一台CentOS 7/8、Rocky Linux、Ubuntu 20.04/22.04系统的虚拟机或云主机,2核4G内存起步,硬盘20G以上。实际跑起来你会发现,Hadoop各组件启动后内存占用轻松超过2G,1G内存的机器连格式化这步都会卡死给你看。

用户规划上,很多人习惯用root直接装和启动Hadoop,这能省去一些权限问题,但我不推荐。Hadoop官方文档建议用独立用户来运行,好处很实在:一是避免误操作删掉系统关键文件(Hadoop的脚本里有很多rm -rf逻辑,以root运行一旦路径变量有问题,后果不堪设想),二是避免和系统环境变量互相干扰。我一般创建一个叫hadoop的用户,单独给它建一个/home/hadoop目录,所有安装和运行都在这下面完成,干净又安全。

3. 下载和安装:从官网到本机的完整链路

3.1 去哪下载、下载哪个版本?

Hadoop的官方下载页面是Apache官网的hadoop.apache.org,进去之后找到Downloads入口,里面会有最近的release版本供选择。国内访问Apache官网速度可能不太理想,这种情况推荐用清华大学开源软件镜像站(mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/)或者阿里云镜像站,上面有完整的历史版本目录,下载速度快很多,文件内容和官方完全一致。

版本选择上,我建议选当前最新的稳定版本,截至这篇教程写作时,3.3.x系列是主流稳定版。具体选择哪个小版本,可以看看发行日期和已知问题列表,不要选太旧的(比如3.2.x之前的版本有些安全漏洞没有修复),也不要盲目追刚发布几天的新版本。稳妥起见选择一个已经发布超过两个月的版本,社区反馈比较充分,坑基本都被踩平了。

下载时要认准.tar.gz结尾的二进制发行包,文件名格式类似hadoop-3.3.6.tar.gz,不要下src源码包,那个是给二次开发用的,编译一次能折腾掉你半天时间。

3.2 解压和目录规划:为什么我坚持用固定路径

拿到tar包之后,解压和路径规划是有讲究的。很多人随手解压到哪算哪,后面配置时各种找不到路径,我建议固定使用一个标准路径。下面是我习惯的做法:

# 先切到hadoop用户(如果没有就创建) sudo useradd -m hadoop sudo passwd hadoop su - hadoop # 创建安装目录 sudo mkdir -p /opt/hadoop sudo chown -R hadoop:hadoop /opt/hadoop # 解压安装包到指定目录 tar -zxvf hadoop-3.3.6.tar.gz -C /opt/hadoop cd /opt/hadoop # 创建软链接,方便以后切换版本 ln -s hadoop-3.3.6 hadoop

软链接这个技巧是我个人比较喜欢的操作,它让/opt/hadoop/hadoop这个路径永远指向当前使用的版本。以后升级Hadoop,只需要解压新版本、改一下软链接指向就行,所有配置文件路径都不用变。对于要在这个环境上反复做实验、写作业的人来说,省下的时间相当可观。

另外,数据目录我习惯单独规划,比如把NameNode的数据放在/opt/hadoop/data/namenode,DataNode的数据放在/opt/hadoop/data/datanode,日志单独放/opt/hadoop/logs。这样以后清理数据、排查日志,不用在安装目录里翻来翻去。官方默认的临时目录和日志目录都放在/tmp下,一旦系统重启被清空,HDFS元数据丢失,轻则要重新格式化,重则集群起不来,这是新人最常踩的暗坑之一。

3.3 JDK安装:别在这步省时间

JDK安装的过程本身不复杂,但有几个小细节值得注意。以Ubuntu为例,直接:

sudo apt update sudo apt install openjdk-8-jdk

CentOS/Rocky Linux则用:

sudo yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel

安装完成后一定要确认JAVA_HOME环境变量,Hadoop启动脚本会去读这个变量。很多人配了JAVA_HOME但路径写错,或者只配了PATH,导致Hadoop启动时报“JAVA_HOME is not set”之类的错误。检查方式:

which java # 比如输出 /usr/lib/jvm/java-8-openjdk-amd64/bin/java ls -l /usr/lib/jvm/java-8-openjdk-amd64

然后把这个路径配置到环境变量里。我一般会把JAVA_HOME和HADOOP_HOME都写进/etc/profile.d/hadoop.sh这个文件(Ubuntu/CentOS都认这个目录),而不是直接改/etc/profile,这样以后清理配置时目标明确,不会在几百行的profile文件里找半天。

4. 配置文件逐项拆解:每个参数我都告诉你为什么

4.1 环境变量配置:Hadoop找到JDK的第一步

Hadoop启动时需要通过bin目录下的脚本找到Java和自身安装路径。官方推荐在etc/hadoop/hadoop-env.sh里设置JAVA_HOME,原因很简单:这个文件是Hadoop原生读取的,不依赖系统级环境变量是否生效。不同的发行版,JDK路径差别很大,务必用自己机器上实际查询到的路径来填。

# 编辑 $HADOOP_HOME/etc/hadoop/hadoop-env.sh export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 export HADOOP_HOME=/opt/hadoop/hadoop export HADOOP_CONF_DIR=/opt/hadoop/hadoop/etc/hadoop export HADOOP_LOG_DIR=/opt/hadoop/logs # 注意:不要手动设置HDFS_NAMENODE_USER等变量 # Hadoop 3.x的sbin脚本会根据实际组件自动处理用户身份

说到HDFS_NAMENODE_USER这个变量,网上很多教程会让你在hadoop-env.sh里手动设置成“root”或“hadoop”,其实是旧版本(2.x和3.0-3.3早期)留下的习惯。新版本对sbin下的启动脚本做了修正,不需要手动指定这些变量了,如果照搬旧教程设置反而可能和启动脚本逻辑冲突,导致启动失败。判断一个教程是不是够新,看这一条就够了。

环境变量配置完成后,建议先执行source /etc/profile.d/hadoop.sh刷新环境,然后运行hadoop version验证一下,看到图1类似的版本信息输出,说明Java环境和Hadoop本身已经打通了。

Hadoop 3.3.6 Source code repository https://github.com/apache/hadoop -r abcdef123456 Compiled by ubuntu on 2023-04-18T12:00:00Z Compiled with protoc 3.7.1 This command was run using /opt/hadoop/hadoop-3.3.6/share/hadoop/common/hadoop-common-3.3.6.jar

4.2 core-site.xml:集群的“公共配置中心”

core-site.xml里面存放的是所有组件共享的配置项,最重要的就是fs.defaultFS,它决定了Hadoop的默认文件系统地址和端口。伪分布式模式下,我们把它配成hdfs://localhost:9000,意思是让HDFS运行在本机的9000端口。

<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/hadoop/data/tmp</value> </property> <property> <name>hadoop.http.staticuser.user</name> <value>hadoop</value> </property> </configuration>

hadoop.tmp.dir这个参数很关键,官方文档里说它默认指向/tmp/hadoop-${user.name},这是所有需要临时存储的组件(如NameNode的EditLog、DataNode的数据块、MapReduce中间结果)的默认根目录。系统重启后/tmp会被清空,所以一定要改成持久化目录。我把它指向/opt/hadoop/data/tmp,并且在data目录下手动创建好子目录,权限保持hadoop用户可读写。

hadoop.http.staticuser.user这个参数估计很多人没注意过,它决定你访问HDFS Web界面时默认的身份名称。如果不设置,默认是dr.who,你在HDFS页面上新建目录时会遇到权限不足的报错,折腾半天不知道问题在哪。把它改成hadoop,再配合稍后说的权限设置,可以省掉很多麻烦。

4.3 hdfs-site.xml:数据存储和副本策略的调整

hdfs-site.xml是HDFS的核心配置,单机伪分布式模式下需要关注几个参数。官方文档示例中伪分布式模式把副本数设置为1,这是有道理的:只有一台DataNode,如果副本数默认是3,数据写入时会因为找不到足够的DataNode而一直处于等待状态,最终超时报错。

<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///opt/hadoop/data/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///opt/hadoop/data/datanode</value> </property> <property> <name>dfs.namenode.http-address</name> <value>localhost:9870</value> </property> <property> <name>dfs.permissions.enabled</name> <value>true</value> </property> </configuration>

dfs.namenode.name.dir和dfs.datanode.data.dir指定元数据和数据块的存储位置,这就是前面说的把数据从/tmp迁走的落地操作。注意这里用的是file://前缀,表示本地文件系统路径,Hadoop 3.x对这个前缀要求比较严格,有的版本不加file://也能跑,但加上更保险。

dfs.namenode.http-address是NameNode Web界面的监听地址,Hadoop 3.x默认端口是9870,和2.x时代的50070端口不同。如果你照抄2.x教程,访问50070必然失败。这个差别很容易被忽略,我专门列出来,避免你在验证结果时卡住。

dfs.permissions.enabled控制HDFS的权限检查开关。默认是true,对于学习环境其实可以,但如果你只是本地写写MapReduce,想省事一些,也可以显式设置为false跳过权限问题。不过我不建议这么做,学习阶段还是保留真实环境的权限行为比较好,不然连着开发环境里的Hive、Spark时,权限问题暴露出来你又得回头折腾。

4.4 yarn-site.xml:资源调度器的关键配置

YARN负责集群资源的管理和任务调度,伪分布式模式下需要确保ResourceManager和NodeManager都启在同一台机器上,并且能相互通信。yarn-site.xml里最关键的配置是ResourceManager的地址和辅助服务。

<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>localhost</value> </property> <property> <name>yarn.nodemanager.vmem-check-enabled</name> <value>false</value> </property> <property> <name>yarn.nodemanager.pmem-check-enabled</name> <value>false</value> </property> </configuration>

yarn.nodemanager.aux-services是YARN NodeManager的辅助服务列表,MapReduce作业运行依赖shuffle过程来传输Map阶段输出到Reduce阶段,所以必须配置为mapreduce_shuffle。旧教程里会让你同时配置mapreduce_shuffle.class这个类名,在新版本上其实只配aux-services也能运行,但显式指定类名更可靠。

vmem-check-enabled和pmem-check-enabled这两个参数是内存检测开关,默认开启,虚拟内存和物理内存占用超过容器申请额度就杀掉任务。个人电脑上跑实验,可用的物理内存本来就有限,YARN计算虚拟内存时还会乘一个比例因子,经常出现明明机器还有空闲内存,任务却被误杀的情况。关掉这两个检测是最省心的做法,学习环境里不涉及生产安全的取舍判断。很多人跑WordCount报错“Container killed on request. Exit code is 143”,多半就是被这个机制误杀了,排查半天找不到原因。

4.5 mapred-site.xml:让MapReduce跑在YARN上

mapred-site.xml控制MapReduce框架的运行模式。这个文件在Hadoop 3.x中可能不存在,需要自己复制模板创建:

cp $HADOOP_HOME/etc/hadoop/mapred-site.xml.template $HADOOP_HOME/etc/hadoop/mapred-site.xml

然后编辑其中的配置:

<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>localhost:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>localhost:19888</value> </property> </configuration>

mapreduce.framework.name必须设置成yarn,表示作业提交给YARN调度执行。如果忘了配置这一项,MapReduce默认在本地运行(local),你提交作业后看不出问题,但YARN监控页面里永远看不到任何作业,会让人觉得环境没装好。这个值和yarn-site.xml是配合使用的,少了谁后面都会出现诡异现象。

JobHistory相关配置是给后续看历史作业用的,本地实验可以先不管,但配上不影响,以后调试作业历史记录时不用再改配置重启。

4.6 workers文件:告诉Hadoop“节点们在哪”

Hadoop 3.x里没有slaves文件了,改名为workers,别被旧教程带偏了。这个文件用来列出所有DataNode和NodeManager的节点地址,伪分布式模式下只需要一行:

localhost

如果你改成真实集群部署,这里每行写一个主机名或IP即可。这个文件的格式要特别注意:Hadoop脚本读取时按行列出行,不支持像普通配置文件那样的#注释行后尾随空格之类的格式错误,容易导致加载到空节点名导致启动异常。我习惯在里面只写地址,不写任何多余内容。

4.7 SSH免密登录:少一次输入,省一堆麻烦

Hadoop启动时通过SSH登录到各个节点(这里是localhost)来拉起守护进程。如果配置了免密,启动脚本跑得又顺又安静;没配置的话,每次start-dfs.sh都会反复问你密码,而且如果是在脚本循环中,有的版本SSH密码输入逻辑还会出岔子,让你误以为卡死了。实际上Hadoop官网单节点配置教程并没有强制要求SSH,但实操时配上能省心很多。

配置步骤很简单:

# 生成密钥对,一路回车即可 ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 把公钥加到authorized_keys中 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 如果是多节点集群,需要拷贝到各台机器的authorized_keys里 # 设置权限,确保ssh能正常读取 chmod 600 ~/.ssh/authorized_keys chmod 700 ~/.ssh # 验证免密 ssh localhost hostname

这里有个细节:如果之前以root或者其他用户生成过SSH密钥,hadoop用户目录下的~/.ssh可能不存在或者权限不对,需要先创建和修正。SSH对~/.ssh目录的权限要求非常严格,权限过宽会导致免密失效,SSH直接拒绝加载密钥,这个坑很多人踩过。

5. 配置文件都明白了?初始化文件系统和启动

5.1 为什么必须格式化NameNode,以及怎么格式化才安全

配置文件改完之后,启动HDFS之前必须先初始化NameNode上的元数据目录。这个操作对应命令:

hdfs namenode -format

格式化的本质是在dfs.namenode.name.dir指定的路径下创建文件系统结构,生成current/VERSION等元数据文件。这个过程会把NameNode上的命名空间清空,相当于把一张空白地图画好等待记录后续目录信息。

操作上有一个必须注意的事项:HDFS集群启动成功后,后续不管是重启还是重新配置,都不应该再对NameNode执行格式化操作。格式化会抹掉所有元数据,导致DataNode上已有的数据块和NameNode记录的映射关系对不上,整个文件系统看起来是空的,极难修复。如果你已经存在重要实验数据,重新格式化等于全没了,而且这种丢失不可恢复。

格式化过程中如果出现下图类似的输出,说明初始化成功:

2024-01-01 12:00:00,123 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = localhost/127.0.0.1 STARTUP_MSG: args = [-format] ... ************************************************************/ 2024-01-01 12:00:05,456 INFO common.Storage: Storage directory /opt/hadoop/data/namenode has been successfully formatted.

如果你看到的是Storage directory already exists且没有格式化的字样,说明之前已经格式化过了。这时候就要停下来判断一下:如果是第一次安装时误操作重复格式化,不影响;如果集群本来就有数据,千万别手贱带-force参数强刷。

5.2 启动HDFS和YARN的完整流程与正常输出

格式化完成后,就能启动HDFS了。Hadoop 3.x的统一启动脚本是:

# 启动HDFS相关守护进程 $HADOOP_HOME/sbin/start-dfs.sh # 启动YARN相关守护进程 $HADOOP_HOME/sbin/start-yarn.sh # 或者用一条命令,依次启动HDFS和YARN $HADOOP_HOME/sbin/start-all.sh

个人习惯是分开执行两个脚本,原因简单:一个问题好定位。如果start-all.sh启动到一半YARN失败,你还得翻日志找是哪个进程的问题,不如自己按顺序启动,多敲一次命令,心里更有数。

启动过程如果配置正确,会出现若干条“Starting NameNode”、“Starting DataNode”等提示,并且伴随着进程被记录的输出。脚本执行完毕之后,用jps命令查看Java进程,一个正常的伪分布式环境应该至少看到以下几个进程:

  • NameNode:HDFS的名称节点
  • DataNode:HDFS的数据节点
  • ResourceManager:YARN的资源管理器
  • NodeManager:YARN的节点管理器

jps输出大致如下:

12345 NameNode 12346 DataNode 12347 ResourceManager 12348 NodeManager 9999 Jps

如果少了哪个进程,不要慌,先看对应日志。日志位置在HADOOP_LOG_DIR(之前我们在hadoop-env.sh里配置过),HDFS相关日志在logs目录下,YARN相关日志也在同一个目录。我用得最多的排查方式是直接tail -n 100 logs/hadoop-hadoop-namenode-localhost.log,看到具体异常信息后再决定怎么处理。

5.3 通过Web界面验证环境是否真的健康

命令行启动成功只是第一步,HDFS和YARN本身是否工作正常,要看Web界面上的指标。Hadoop 3.x版本的访问地址和2.x不同,注意别用老端口。

  • HDFS NameNode Web界面:http://localhost:9870
  • YARN ResourceManager Web界面:http://localhost:8088

浏览器打开HDFS界面后,正常状态下Overview页面会显示Live Nodes为1,说明DataNode已经注册成功。如果Live Nodes显示为0,说明DataNode没有正常连接NameNode,常见原因包括hosts文件解析问题、防火墙未放行端口、DataNode和NameNode的clusterID不一致。

YARN界面打开后,Active Nodes应该显示为1。如果显示0,大概率是NodeManager没起来或没注册成功,查看nodemanager日志。这里的Active Nodes和HDFS的Live Nodes是两套独立体系,一个挂了不影响另一个,新手经常只检查其中一个,结果HDFS能用、YARN提交作业就跑不起来。

另外有本机防火墙的话,至少放行以下端口:9000端口(HDFS RPC)、9870端口(NameNode Web)、9864端口(DataNode Web)、8088端口(YARN Web)、9866端口(DataNode数据传输)。用云服务器的话,安全组规则里也要放行这些端口,不然只能本机访问,外部机器看不到界面。如果你用的是虚拟机,可以把防火墙直接停掉做实验,毕竟学习环境不需要太注重网络安全隔离:

sudo systemctl stop firewalld # CentOS/Rocky Linux sudo ufw disable # Ubuntu

5.4 第一次提交作业:用官方WordCount样例跑通全链路

环境启动成功之后,拿官方自带的WordCount示例做一次完整的“写数据-读数据-提交作业-查看结果”验证。这是整个安装过程中最让人安心的时刻。

首先在HDFS上创建测试目录:

# 创建目录 hdfs dfs -mkdir -p /user/hadoop/input # 查看目录是否创建成功 hdfs dfs -ls /user/hadoop/

然后把一个本地文本文件上传到HDFS。这里建议自己造一个有几句英文的测试文件,比如:

echo "hello hadoop hello world" >> /tmp/test.txt echo "hadoop is useful" >> /tmp/test.txt echo "learn hadoop step by step" >> /tmp/test.txt # 上传到HDFS hdfs dfs -put /tmp/test.txt /user/hadoop/input/

Hadoop官方提供了示例jar包,位于$HADOOP_HOME/share/hadoop/mapreduce/目录下,文件名类似hadoop-mapreduce-examples-3.3.6.jar。使用方法:

# 运行WordCount作业 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /user/hadoop/input /user/hadoop/output

注意:output目录必须是HDFS上不存在的目录,如果它已经存在,作业会直接报错。这个设计是为了防止覆盖已有结果数据,刚开始不熟悉的人经常会在这报“Output directory already exists”的错。解决办法就是换个新名字,或者用hdfs dfs -rm -r删除旧目录。

作业提交后,控制台会滚动输出MapReduce执行进度,从map 0%逐步到map 100%、reduce 0%再到reduce 100%。最终看到类似“Job completed successfully”的输出,就说明整个链路完全通了。

验证结果:

# 查看输出目录的文件列表 hdfs dfs -ls /user/hadoop/output # 查看结果内容 hdfs dfs -cat /user/hadoop/output/part-r-00000

正常会看到类似:

hadoop 3 hello 2 is 1 learn 1 step 1 useful 1 world 1

到这里,你的Hadoop单机伪分布式环境已经真正可用了。

6. 本地模式到伪分布式:两种模式的切换逻辑

很多新手会有个疑问:我配置了这么多东西,如果我突然只想在本地模式跑一个测试,不需要HDFS和YARN那些后台进程,需要怎么做?

答案很简单:本地模式不需要额外配置,Hadoop自带的本地运行能力是默认行为。你把那些XML配置文件里的fs.defaultFS改成file:///,或者干脆用另一套配置文件目录启动,就能切换到本地模式。实际上MapReduce程序不指定框架名时,默认以本地模式运行。

一个实用技巧是维护两套配置文件目录。比如安装目录下自带一套etc/hadoop用于伪分布式模式,再复制一份etc/hadoop-local,里面把mapreduce.framework.name改成local,fs.defaultFS改成file:///。启动程序时指定不同的HADOOP_CONF_DIR即可切换,互不干扰。这个思路对后续学习Spark、Flink部署方式也有借鉴意义,环境隔离永远是减少麻烦的第一原则。

7. 常见问题排查与避坑技巧实录

7.1 Hadoop命令全家桶:你真的会用吗

配置和运行过程中你会频繁使用Hadoop自带的命令行工具。这里整理一下最常用的几组,每一条都是实际项目中反复用到的。

HDFS文件操作:

hdfs dfs -ls / # 查看根目录 hdfs dfs -mkdir -p /user/hadoop # 创建目录 hdfs dfs -put 本地文件 HDFS路径 # 上传文件 hdfs dfs -get HDFS路径 本地目录 # 下载文件 hdfs dfs -cat HDFS路径 # 查看文件内容 hdfs dfs -rm -r HDFS路径 # 递归删除,用前确认路径 hdfs dfs -du -h /user/hadoop # 查看目录占用空间

进程和集群管理:

hdfs dfsadmin -report # 查看DataNode健康状态和数据块情况 hdfs dfsadmin -safemode leave # 手动退出安全模式 hdfs haadmin -getAllServiceState # HA模式查询状态,伪分布式用不上 yarn node -list # 查看YARN上注册的NodeManager yarn application -list # 查看正在运行的作业 yarn application -kill application_id # 杀掉卡死的作业

遇到任何命令报找不到类或者类似NoClassDefFoundError的问题,先确认环境变量HADOOP_CLASSPATH是否配置正确。这在后面整合Hive或者Spark的时候尤为重要,很多整合难题其实根源都在CLASSPATH没包含Hadoop生态的依赖包。

7.2 端口冲突:9000和8088被占用怎么办

Hadoop默认使用一堆端口,如果同一台机器上还跑着其他服务,可能存在冲突。最常见的是8088端口被其他Web服务占用,或者9000端口被某些中间件占用(比如Nacos、Dubbo的默认端口是8848还好,但有些服务确实会把9000作为HTTP服务端口)。

解决思路有两个:

  • 改Hadoop配置,比如把yarn.resourcemanager.webapp.address改成8089等未占用端口。
  • 先停掉占用端口的其他服务,或者把Hadoop调整到其他端口。

排查端口占用:

ss -tlnp | grep 8088 # 或 lsof -i:8088

如果看到进程没有用,那就是端口还没监听起来,问题在进程启动那一步。

7.3 常见错误速查表

错误信息原因解决方式
JAVA_HOME is not set and could not be found没有正确配置JAVA_HOME在hadoop-env.sh中显式设置JAVA_HOME路径
Cannot create directory /user/hadoop. Name node is in safe modeNameNode处于安全模式等待安全模式自动退出,或执行hdfs dfsadmin -safemode leave
Container killed on request. Exit code is 143YARN内存检测误杀容器将yarn.nodemanager.vmem-check-enabled和pmem-check-enabled设为false
There is no more space available in the virtual memory虚拟内存不足调整yarn.nodemanager.vmem-pmem-ratio,或关闭内存检测
Output directory hdfs://localhost:9000/... already exists输出目录已存在换新目录名或用hdfs dfs -rm -r删除旧目录
Operation category READ is not supported in state standby误访问了Standby节点检查是否有多个NameNode配置文件,确保只配了一个
Incompatible clusterIDsDataNode集群ID与NameNode不匹配清理DataNode的current目录,重新格式化,注意数据会丢失
Name or service not knownhosts文件没有主机名映射在/etc/hosts中添加localhost和主机名映射
Could not resolve hostname XX主机名解析失败修正/etc/hosts,确保ssh localhost解析正常

7.4 重新格式化导致的“DataNode起不来”

这是我在教学和答疑过程中遇到频率最高的一个问题。流程通常是:Hadoop第一次跑起来了,隔几天想重新搭一遍,或者照着教程又格式化了一次,结果再启动时NameNode正常、DataNode却一直起不来,日志里报Incompatible clusterIDs。

这是Hadoop的一个自我保护机制:DataNode会记录自己所属集群的clusterID,NameNode重新格式化后生成了新的clusterID,两边对不上,DataNode拒绝提供服务。

解决办法是同时清理两边的数据目录,再重新格式化:

# 停止服务 $HADOOP_HOME/sbin/stop-dfs.sh # 清理元数据和数据 rm -rf /opt/hadoop/data/namenode/* rm -rf /opt/hadoop/data/datanode/* rm -rf /opt/hadoop/data/tmp/* # 重新格式化 hdfs namenode -format # 重新启动 $HADOOP_HOME/sbin/start-dfs.sh

这里再次提醒:如果HDFS上有重要数据,这个操作会把数据全部清空。格式化之前一定要备份或确认不需要保留。线上环境的HDFS元数据是可以通过备份恢复的,但伪分布式没有做备份机制,删了就没了。

7.5 日志文件里的“线索”:怎么定位问题

所有Hadoop守护进程的日志都在HADOOP_LOG_DIR下面,日志文件命名方式遵循hadoop-{user}-{daemon}-{hostname}.log的格式。比如:

  • hadoop-hadoop-namenode-localhost.log:NameNode日志
  • hadoop-hadoop-datanode-localhost.log:DataNode日志
  • hadoop-hadoop-resourcemanager-localhost.log:ResourceManager日志
  • hadoop-hadoop-nodemanager-localhost.log:NodeManager日志

排查问题第一件事是打开对应进程的日志,翻到最后的Exception或者ERROR。很多新手不习惯看日志就直接百度报错,但日志里往往已经写清楚了原因和具体类名,远比搜索引擎里泛泛而谈的答案更精准。看日志的时候重点关注Caused by后面的内容,那才是问题的根因,前面的Exception信息可能只是表象。

8. 最后再分享几个小技巧

走了这一整套流程,Hadoop单机伪分布式环境就算彻底跑通了。但有些经验不在安装教程里,是我实际用了很久之后才体会到的,在这里一并分享给大家。

第一个技巧是关于环境变量管理的。养成把所有大数据组件的环境变量统一放在/etc/profile.d/下的习惯,每装一个组件,新建一个对应的.sh文件,比如hadoop.sh、hive.sh、spark.sh,各管各的,互不干扰。以后环境出了问题排查,或者要换版本,改一处就好,不用在/etc/profile里大海捞针。

第二个技巧是给自己建立一个“启动清单”。Hadoop的启动顺序是HDFS -> YARN,关停顺序反过来,YARN -> HDFS。如果后期还装了Hive、HBase,启动关系会更复杂。把这些依赖关系记在一张表里,每次开实验环境照着执行,能避免很多“为什么Hive连不上”这类低级问题。

第三个技巧和日常使用有关:HDFS命令行工具hdfs dfs与Hadoop 2.x时代的hadoop fs命令在很多教程里混着用,新版里两个都能执行,但hdfs dfs更聚焦于文件系统操作,hadoop fs同时兼容本地文件系统。我习惯用hdfs dfs,语义更清晰。另外,如果你用的是Windows本子远程访问Hadoop,可以通过Web界面操作HDFS文件,不一定非要在Linux终端里敲命令。在NameNode的9870端口界面里,有个Utilities -> Browse the file system入口,可以直接浏览、上传、下载文件和目录,做实验验证非常方便。

最后一个建议关乎长期使用:保持学习环境整洁的另一个重要手段是定期查看/opt/hadoop/logs目录的大小。跑过大量作业后,日志文件增长速度快得超出想象,不清理的话硬盘很快就满了。我一般会保留最近一个月的日志,更早的直接清掉,或者配置脚本定期清理。

Hadoop单机环境的搭建算是大数据实操路上的第一道门槛。这道门槛看起来琐碎,但每踩过一个坑,你对Hadoop整体架构的理解都会加深一层。现在环境已经通了,接下来可以放心去试HDFS命令、写MapReduce程序、整合Hive或者Spark,不用再担心底层环境的干扰。

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

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

立即咨询