先说明一个可能让不少人意外的事实:Hadoop部署本身并不难,真正劝退大部分新手的,是网上教程里那种“既讲集群、又讲高可用、还顺带塞了一堆优化参数”的大而全写法。你把伪分布式和完全分布式的内容混在一起看,自然越看越乱。本文只做一件事:在一台Linux机器上,把Hadoop跑起来,走完单机(非分布式)模式的全流程。单机模式意味着所有进程都在本机,不涉及跨节点通信,配置量也最小,适合用来理解Hadoop的基本运行机制、跑通HDFS命令、为后续学习伪分布式和集群搭建打底。
文章会从环境准备、JDK安装、核心配置、启动验证到踩坑排查一条龙讲完,所有命令都给出完整可复制版本,所有配置文件都贴出最终内容。跟着敲完,你能得到一个真正能用的Hadoop单机环境,而不是一个“配置了但启动报错”的烂摊子。
1. 单机模式到底是什么,和伪分布式、集群有什么区别
在动手之前,先花两分钟把概念理清。很多人第一次搜Hadoop安装,看到“单机”“伪分布式”“完全分布式”三个词就懵了,不知道自己要装哪一种,于是稀里糊涂复制了一份集群配置,结果在本机上各种报错。
1.1 三种模式的本质差异
Hadoop的三种运行模式,区别不在于“装了多少台机器”,而在于核心进程(NameNode、DataNode、ResourceManager、NodeManager)怎么部署、以什么方式通信。
| 模式 | 进程部署方式 | 适用场景 | 配置复杂度 |
|---|---|---|---|
| 单机模式(本地模式) | 所有组件运行在同一个JVM中,不使用HDFS,直接读写本地文件系统 | 快速跑通MapReduce程序、调试代码 | 极低,几乎不用改配置 |
| 伪分布式模式 | 每个守护进程单独启动,但全部运行在同一台机器上,使用HDFS | 学习Hadoop原理、本地开发测试 | 中等,需要配置HDFS和YARN |
| 完全分布式模式 | 各守护进程分布在多台机器上 | 生产环境、真实数据处理 | 高,需要配置节点间SSH、网络、参数调优 |
你可能会问:标题明明写的是“单机(非分布式)配置”,为什么我还要提伪分布式?因为网上大量教程把单机模式和伪分布式混在一起写,说“单机模式就是所有东西装在一台机器上”,这个说法其实是错的。严格意义上的Hadoop单机模式,默认配置下根本不启动NameNode、DataNode这些守护进程,它更像是一个“本地跑MapReduce的框架”,输入输出都走本地文件系统。而伪分布式才是“一台机器模拟分布式集群”。
1.2 本文要搭建的是哪一种
标题写的是“单机(非分布式)配置”,结合搜索场景来看,大多数人实际想要的是:在一台机器上把Hadoop装好、能启动HDFS、能执行hdfs命令、能跑简单的MapReduce任务。这其实是标准的伪分布式配置,只是运行规模是单机而已。
为了让教程真正可用,我按“单机上的非集群配置”来落地,即:
- 不配置多台节点,所有组件都在本机
- 配置HDFS,启动NameNode和DataNode
- 配置YARN,启动ResourceManager和NodeManager
- 不配置ZooKeeper、不配置HA、不配置Federation
换句话说,这是单节点上的完整Hadoop功能环境,既能练手HDFS,又能跑MapReduce,是性价比最高的学习配置。
1.3 为什么建议新手从单机配置入手
我见过不少新手一上来就照着“三节点集群搭建”教程操作,结果折腾一周,卡在各种匪夷所思的问题上:节点间网络不通、SSH免密失败、防火墙拦截端口、数据目录权限不对……最后连Hadoop最基本的样子都没见到。
单机配置的价值在于把变量降到最少。你不需要考虑节点间通信,不需要面对分布式环境下才有的网络超时、脑裂、副本放置等问题,所有排错都集中在一台机器上,日志也都在本地,排查链路短,非常利于理解Hadoop底层的工作机制。把单机跑通之后,再去看集群搭建,你会发现自己已经懂了80%的核心概念,剩下的无非是“多配几台机器+配置SSH互信+调整参数”。
2. 安装前的准备清单:版本选型、JDK依赖、操作系统要求
Hadoop不像普通软件那样解压就能跑,它对环境有硬性要求,而且版本匹配是个大坑。我见过无数人栽在JDK版本和Hadoop版本不兼容上,所以这部分单独拿出来详细讲。
2.1 操作系统选择
Hadoop官方支持Linux和macOS,不支持Windows(Windows下需要借助Cygwin或WSL,非常折腾,不建议新手尝试)。如果你只有Windows电脑,两个解决方案:
- 装VMware或VirtualBox虚拟机,里面跑一个CentOS 7或Ubuntu Server
- 用Windows自带的WSL2(Windows Subsystem for Linux)
我个人建议直接上虚拟机。虽然WSL2更轻量,但部分Hadoop版本在WSL2上有网络和文件系统的小毛病,排查起来比虚拟机更费劲。虚拟机里的Linux网络模式选桥接或NAT都行,单机配置对网络要求不高。
操作系统版本方面,CentOS 7和Ubuntu 20.04/22.04 LTS是社区里最常见的,教程最多,遇到问题最容易搜到答案。下面命令以CentOS 7为例(因为服务器场景用得最多),Ubuntu用户把yum换成apt-get即可,核心配置完全一样。
2.2 版本选型:别用最新的,用最稳的
Hadoop版本选型有个原则:不要追求最新版。最新版往往意味着社区踩坑解决方案最少,很多第三方组件(如Hive、Spark)的兼容版本还没跟上。
目前线上使用最广、教程最全的两个大版本:
| 版本系列 | 常见具体版本 | 特点 |
|---|---|---|
| Hadoop 2.x | 2.7.7、2.10.x | 经典稳定,老教程多,适合学习 |
| Hadoop 3.x | 3.1.4、3.2.4、3.3.x | 支持GPU、支持多个NameNode,新特性多 |
JDK版本匹配关系是关键中的关键:
- Hadoop 2.x 要求 JDK 8
- Hadoop 3.1.x 要求 JDK 8
- Hadoop 3.2.x 及以上可以配合 JDK 8 或 JDK 11
下面演示用Hadoop 3.2.4 + JDK 8,这是目前学习性价比最高的组合:既能体验Hadoop 3.x的新特性,JDK 8又是最稳定、最容易获取的版本,两者兼容性极佳。
下载地址给两个:
- 官方下载页:https://hadoop.apache.org/releases.html
- 国内镜像(速度快很多):https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/
一定下载.tar.gz格式的二进制包,不要下载源码包(.src.tar.gz),源码包需要自己编译,新手不碰。以Hadoop 3.2.4为例,在清华镜像下找到目录后,下载hadoop-3.2.4.tar.gz。
2.3 JDK 8安装步骤
如果你机器上已经有JDK,先检查版本:
java -version如果输出类似openjdk version "1.8.0_xxx"或java version "1.8.0_xxx",说明JDK 8没问题。如果输出的是JDK 11或17,建议卸载重装JDK 8,因为Hadoop 3.2.4虽然理论上支持JDK 11,但生产环境大量经验表明JDK 8最省心。
安装JDK 8,CentOS下用yum装OpenJDK即可:
# 检查是否有系统自带的OpenJDK rpm -qa | grep java # 如果自带有其他版本的JDK,先卸载(这里以openjdk为例) yum remove -y java-1.7.0-openjdk java-1.8.0-openjdk # 安装JDK 8 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-develUbuntu系统:
apt-get update apt-get install -y openjdk-8-jdk装完后确认一下:
java -version javac -version两个命令都有输出,说明JDK环境OK。不要漏装java-1.8.0-openjdk-devel,Hadoop编译MapReduce作业时需要javac,只装JRE不够。
2.4 SSH免密登录配置(虽然单机但强烈建议)
严格来说,伪分布式模式下Hadoop会通过SSH连接localhost来启动和停止守护进程。如果不配置免密,每次启动都要输入密码,非常麻烦。
# 检查SSH是否安装 rpm -qa | grep ssh # 没装就装一下 yum install -y openssh-server openssh-clients # 生成密钥对,一路回车,不要设置passphrase ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa # 将公钥加入授权列表 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 修改权限(密钥文件权限不对会导致SSH拒绝使用) chmod 600 ~/.ssh/authorized_keys # 验证免密登录 ssh localhost如果执行ssh localhost后能直接进入shell,不再提示输入密码,说明配好了。注意,当前用户很关键,你以root配置的就用root启动Hadoop,以hadoop用户配置的就用hadoop用户启动,不要混用。
2.5 关闭防火墙和SELinux(避免玄学报错)
CentOS下防火墙和SELinux经常在不经意间拦截Hadoop进程间的通信,虽然单机模式下影响较小,但为了排查问题时不被干扰,建议直接关掉:
# 关闭防火墙 systemctl stop firewalld systemctl disable firewalld # 临时关闭SELinux setenforce 0 # 永久关闭SELinux(修改配置文件) sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config注意:SELinux改完后需要重启机器才能完全生效。但
setenforce 0已经把当前会话的SELinux关了,不影响本次安装流程。
3. 下载解压与环境变量配置:这些细节决定你能不能用起来
这一节内容不复杂,但细节非常多。很多人的Hadoop装上之后hadoop命令能用,start-dfs.sh就是报错,问题往往出在解压目录、用户权限、环境变量这些“不值得写进教程”的小细节上。
3.1 创建专用用户(强烈推荐)
如果你现在用的是root,我建议创建一个专门用户来跑Hadoop。原因很现实:Hadoop生态里很多脚本和组件对root用户不友好,某些版本在root下启动会直接警告或拒绝执行;另外HDFS数据目录如果归属root,后续用别的用户操作会很别扭。
# 创建用户,指定home目录和bash shell useradd -m -d /home/hadoop -s /bin/bash hadoop # 设置密码(虽然SSH免密已配置,但sudo等场景需要密码) passwd hadoop # 给hadoop用户添加sudo权限(学习环境可以直接给,省心) echo 'hadoop ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers后续所有操作都在hadoop用户下执行。切换用户:
su - hadoop此时要重新配置一遍hadoop用户的SSH免密,因为密钥文件是跟着用户走的。刚才在root下生成的密钥对派不上用场:
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys ssh localhost3.2 下载并解压Hadoop
用hadoop用户执行,把安装包放到/home/hadoop下:
cd /home/hadoop # 从清华镜像下载(版本号按需调整) wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.2.4/hadoop-3.2.4.tar.gz # 解压 tar -zxvf hadoop-3.2.4.tar.gz # 改个简单点的名字,方便后续路径输入 mv hadoop-3.2.4 hadoop解压完后可以看一眼目录结构:
ls -l /home/hadoop/hadoop你会看到bin、etc、sbin、lib、share等目录。简单交代一下各自用途:
bin:Hadoop命令行工具(hdfs、yarn、mapred等)sbin:启停脚本(start-dfs.sh、stop-dfs.sh等)etc/hadoop:所有配置文件所在地,后面主要改这里share:各组件运行所需的jar包logs:运行日志目录,排错时主要看这里
3.3 配置环境变量:JAVA_HOME和HADOOP_HOME缺一不可
编辑/home/hadoop/.bashrc:
vim /home/hadoop/.bashrc在文件末尾追加以下内容:
# Java环境变量 export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export PATH=$PATH:$JAVA_HOME/bin # Hadoop环境变量 export HADOOP_HOME=/home/hadoop/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop注意:JAVA_HOME的路径不是固定的,取决于你的JDK装在哪个目录。用以下命令查看真实路径:
# 查看Java可执行文件路径 which java # 输出示例:/usr/bin/java # 顺着软链接找到真实安装目录 ls -l /usr/bin/java # 输出示例:/usr/bin/java -> /etc/alternatives/java ls -l /etc/alternatives/java # 最终会指向类似:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx/bin/java拿到真实路径后,把JAVA_HOME的值设置成/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx(去掉末尾的/bin/java)。
设置好后让配置生效并验证:
source ~/.bashrc # 验证环境变量 echo $JAVA_HOME echo $HADOOP_HOME # 验证Hadoop命令可用 hadoop versionhadoop version能输出版本信息,说明环境变量配置成功。如果提示command not found,大概率是PATH写错了或source没执行,回头检查一下。
3.4 修改hadoop-env.sh中的JAVA_HOME
这里有个隐蔽的坑:即使你在.bashrc里配好了JAVA_HOME,Hadoop的某些脚本仍然可能找不到Java。很多版本的Hadoop启动脚本用的是JAVA_HOME环境变量,但部分脚本直接读取etc/hadoop/hadoop-env.sh里硬编码的JAVA_HOME。所以要做双重保险:
vim /home/hadoop/hadoop/etc/hadoop/hadoop-env.sh找到类似这样的一行(不同版本位置不同,可以按JAVA_HOME搜索):
# The java implementation to use. By default, this will be the java # installation on your PATH. #export JAVA_HOME=${JAVA_HOME}改成:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.xxx也就是把注释符号去掉,填上真实的JDK路径。这一步必须做,省掉它后面启动时极可能报Error: JAVA_HOME is not set and could not be found。
4. 四个核心配置文件逐项拆解:每行参数都是什么意思
Hadoop单机伪分布式配置,核心就是改etc/hadoop目录下的四个文件:core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml。这四个文件管的事分别是:Hadoop核心通用配置、HDFS存储配置、MapReduce计算框架配置、YARN资源调度配置。
很多教程直接让你复制粘贴配置内容,不解释每行含义。但配置这东西,不理解就记不住,改了也不知道会不会出问题。下面逐个拆开讲。
4.1 core-site.xml:Hadoop的“总开关”
core-site.xml是Hadoop的核心配置,其中最重要的两个参数是fs.defaultFS和hadoop.tmp.dir。
fs.defaultFS:指定HDFS的NameNode地址,格式是hdfs://主机名:端口号。伪分布式模式下,端口默认是9000(或9820,不同版本有差异)。hadoop.tmp.dir:指定Hadoop临时文件目录,NameNode的元数据就存在这里。默认值是/tmp/hadoop-${user.name},这个默认值非常坑,因为系统重启会清空/tmp,导致NameNode元数据丢失。务必改成自定义目录。
创建数据目录:
mkdir -p /home/hadoop/hadoop_data/tmp编辑/home/hadoop/hadoop/etc/hadoop/core-site.xml,把<configuration>和</configuration>之间的内容替换为:
<configuration> <!-- 指定NameNode地址和端口 --> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <!-- 指定Hadoop运行时临时数据目录 --> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/hadoop_data/tmp</value> </property> </configuration>4.2 hdfs-site.xml:决定数据怎么存
hdfs-site.xml管的是HDFS本身的行为。单机伪分布式配置下,最关键的是副本数。因为只有一台DataNode,副本数如果保持默认的3,会有两个副本永远找不到地方放,导致各种警告甚至报错。设成1就够用。
另一个可选的配置是dfs.namenode.name.dir和dfs.datanode.data.dir,用于指定NameNode元数据路径和DataNode数据块路径。如果你不在这个文件里配置,Hadoop会沿用hadoop.tmp.dir作为基础目录。为了结构清晰,建议显式指定:
mkdir -p /home/hadoop/hadoop_data/namenode mkdir -p /home/hadoop/hadoop_data/datanode编辑hdfs-site.xml:
<configuration> <!-- 副本数,单机环境配置为1 --> <property> <name>dfs.replication</name> <value>1</value> </property> <!-- NameNode元数据存储路径 --> <property> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/hadoop_data/namenode</value> </property> <!-- DataNode数据块存储路径 --> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadoop/hadoop_data/datanode</value> </property> <!-- 关闭HDFS权限检查,学习环境能省掉很多权限报错 --> <property> <name>dfs.permissions.enabled</name> <value>false</value> </property> </configuration>关于
dfs.permissions.enabled:生产环境强烈建议保持默认的true,但学习环境关掉可以少踩很多权限坑,尤其是当你用不同用户操作HDFS时。先跑通再理解权限机制,是更平滑的学习路径。
4.3 mapred-site.xml:MapReduce跑在什么框架上
在Hadoop 2.x之后,MapReduce作为计算框架需要明确指定运行在YARN上。这个文件原始状态下可能叫mapred-site.xml.template,需要先复制一份:
cp /home/hadoop/hadoop/etc/hadoop/mapred-site.xml.template /home/hadoop/hadoop/etc/hadoop/mapred-site.xml编辑mapred-site.xml:
<configuration> <!-- 指定MapReduce运行在YARN框架上 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>4.4 yarn-site.xml:资源调度器怎么工作
YARN负责集群资源的统一管理和任务调度。单机配置下,最核心的是yarn.nodemanager.aux-services,它的作用是让NodeManager为MapReduce作业提供辅助服务。如果不配置这一项,MapReduce作业会卡在“提交了但永远不执行”的状态。
编辑yarn-site.xml:
<configuration> <!-- NodeManager辅助服务,跑MapReduce必须配成mapreduce_shuffle --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 单机环境下内存资源设置小一点,防止内存不足 --> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>2048</value> </property> <property> <name>yarn.nodemanager.vmem-pmem-ratio</name> <value>4</value> </property> </configuration>这里多说一句内存参数:默认的yarn.nodemanager.resource.memory-mb是8192MB,如果你的机器只分配了2G或4G内存,跑MapReduce时经常会出现Container被kill的情况。把它调小一点,配合yarn.nodemanager.vmem-pmem-ratio把虚拟内存比例调大,能有效减少“虚拟内存超限被误杀”的问题。
5. 格式化NameNode与启动服务:命令顺序不能错
配置写完之后就是最关键的时刻:启动。先说一个反复强调的原则:首次启动必须格式化NameNode,但后续不要重复格式化。
5.1 为什么必须格式化NameNode
NameNode是HDFS的“目录总管家”,它需要维护整个文件系统的元数据(哪些目录、哪些文件、文件被切成了哪些块、块存在哪个DataNode上)。格式化就是初始化这个元数据存储结构,没有它NameNode启动不了。
cd /home/hadoop/hadoop bin/hdfs namenode -format如果一切正常,日志末尾会输出类似Storage directory /home/hadoop/hadoop_data/namenode has been successfully formatted的字样。看到successfully formatted才算成功。
禁忌:重复格式化。每次格式化都会重新生成一个current目录,如果旧元数据和新元数据对不上,启动时会报Storage directory already exists之类的错误。如果你确实需要重新初始化,先把/home/hadoop/hadoop_data目录清空再格式化:
rm -rf /home/hadoop/hadoop_data/namenode/* rm -rf /home/hadoop/hadoop_data/datanode/*5.2 启动HDFS和YARN
格式化完成后,启动HDFS:
cd /home/hadoop/hadoop sbin/start-dfs.sh启动过程中会提示输入密码(如果你配好了SSH免密就不会问),然后分别启动NameNode和DataNode。日志没有报错的情况下,再启动YARN:
sbin/start-yarn.sh如果你觉得分开启动麻烦,也可以直接用sbin/start-all.sh(Hadoop 3.x里这个方法已标记为deprecated,但它仍然有效,一条命令同时启动HDFS和YARN)。
5.3 用jps验证:进程全不全
jps是JDK自带的命令,专门查看当前用户启动了哪些Java进程,是验证Hadoop启动状态的第一利器:
jps单机伪分布式正常状态下,应该看到以下5个进程:
| 进程名 | 角色 |
|---|---|
| NameNode | HDFS元数据管理 |
| DataNode | HDFS数据存储 |
| ResourceManager | YARN资源管理 |
| NodeManager | YARN节点管理 |
| SecondaryNameNode | 辅助NameNode合并元数据日志 |
如果你看到了这5个进程,恭喜,核心组件已经全部起来了。最常见的异常是少一两个进程,比如只有NameNode没有DataNode,或者ResourceManager没起来。这种情况先别急着重启,大概率是配置问题或数据目录冲突,参考下一节排查。
5.4 通过Web UI进一步验证
Hadoop自带Web管理界面,看到界面基本等于确认服务在正常工作:
- HDFS管理界面:浏览器访问
http://localhost:9870(Hadoop 3.x;2.x是50070) - YARN管理界面:浏览器访问
http://localhost:8088
进入HDFS管理界面后,你能看到NameNode状态、DataNode列表、HDFS存储容量等。如果DataNode列表里有你启动的节点,说明HDFS数据节点注册成功,这一步走完你的Hadoop单机环境已经建成一大半了。
5.5 跑一道HDFS命令和WordCount示例
Web界面只能证明服务活着,要证明“能用”,还得实际操作一下HDFS,再跑一个MapReduce作业。
先在HDFS上建目录、传文件:
# 在HDFS根目录下创建测试目录 hdfs dfs -mkdir -p /test/input # 查看HDFS根目录 hdfs dfs -ls / # 创建一个本地测试文件 echo "hello hadoop hello world" > /home/hadoop/test.txt # 上传到HDFS hdfs dfs -put /home/hadoop/test.txt /test/input/ # 查看HDFS上的文件 hdfs dfs -ls /test/input # 读取文件内容验证 hdfs dfs -cat /test/input/test.txt如果上面命令都正常输出,说明HDFS读写没问题。然后再跑一个最简单的MapReduce作业验证计算能力。Hadoop自带示例jar包,路径在:
ls /home/hadoop/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.4.jar执行WordCount统计:
hadoop jar /home/hadoop/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.4.jar wordcount /test/input /test/output跑完后查看统计结果:
hdfs dfs -cat /test/output/part-r-00000你会看到类似这样的输出(词汇和出现次数的统计结果):
hadoop 2 hello 2 world 1到这一步,你的Hadoop单机环境彻底打通了:HDFS能存数据,YARN能调度任务,MapReduce能计算。后面所有版本的问题,都可以从这套环境开始演进。
6. 常见启动失败问题排查:把报错彻底讲透
Hadoop部署过程中,绝大多数人的崩溃点不在安装本身,而在启动时遇到的各种玄学报错。我把这几年带新手时遇到的高频问题整理出来,做成了“症状—原因—解法”对照表。
| 症状 | 常见原因 | 解决方案 |
|---|---|---|
Error: JAVA_HOME is not set | hadoop-env.sh里的JAVA_HOME没配置或配置错误 | 按3.4节重新配置 |
NameNode启动失败,日志报Incompatible clusterIDs | 格式化多次导致clusterID不一致 | 删掉namenode和datanode目录内容,重新格式化 |
DataNode进程起不来 | 数据目录权限不对,或clusterID与NameNode不一致 | 检查datanode目录权限,必要时重新格式化 |
localhost: ERROR: Cannot connect to the NameNode | NameNode根本没起来 | 先看NameNode日志,核心配置是否正确 |
| 访问Web UI无响应 | 防火墙没关,或服务端口未监听 | 检查netstat -tlnp端口监听,关闭防火墙 |
| MapReduce作业提交后卡住不动 | yarn-site.xml中aux-services没配置 | 确认已配置mapreduce_shuffle并重启YARN |
| Container被kill,报内存不足 | 物理内存或虚拟内存超限 | 调小memory参数,调大vmem-pmem-ratio |
6.1 问题排查顺序:日志是唯一可信的实话
遇到问题,第一反应不应该是盲目重启,而是看日志。Hadoop的日志目录在:
ls /home/hadoop/hadoop/logs/你会看到hadoop-hadoop-namenode-xxx.log、hadoop-hadoop-datanode-xxx.log等文件。启动失败时,对应的.log文件末尾就是最真实的错误原因。相应地,启动时的即时输出在.out文件里。
另外一个有用命令是看端口监听:
netstat -tlnp | grep java正常情况下,你会看到9000/9820(NameNode RPC)、9870(NameNode HTTP)、8088(ResourceManager HTTP)、9864(DataNode HTTP)等端口都在监听。哪个端口没出来,就是指明了哪个组件有问题。
6.2 经典案例一:重复格式化导致的Incompatible clusterIDs
这是新手最容易踩的坑。第一次格式化后启动NameNode失败,你查了下说“格式化可以解决问题”,于是又跑了一次hdfs namenode -format,然后重启,结果报:
Incompatible clusterIDs in /home/hadoop/hadoop_data/namenode: namenode clusterID = CID-xxx, datanode clusterID = CID-yyy原因:NameNode和DataNode的clusterID不一致。格式化NameNode会生成一个新的clusterID,但DataNode数据目录里还保留着旧clusterID。两边对不上,DataNode拒绝注册。
解法:清空所有数据目录,重新走一遍“格式化→启动”流程:
rm -rf /home/hadoop/hadoop_data/namenode/* rm -rf /home/hadoop/hadoop_data/datanode/* bin/hdfs namenode -format sbin/start-dfs.sh6.3 经典案例二:MapReduce任务一直Pending不执行
HDFS正常、YARN管理界面能看到ResourceManager和NodeManager,但提交WordCount作业后,任务就一直挂在那边,进度0%,也不报错。
这种“半死不活”的状态,90%是这个原因:yarn-site.xml里没有配置yarn.nodemanager.aux-services。没有这个mapreduce_shuffle辅助服务,NodeManager就不知道怎么执行MapReduce的Shuffle阶段,作业提交后被晾在一边。
解法:
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>修改后重启YARN:
sbin/stop-yarn.sh sbin/start-yarn.sh另一个隐藏原因:NodeManager可用内存不足。如果你在4G内存的机器上跑,YARN默认会觉得自己有8G可用,分配给MapReduce作业的Container需要的内存超了物理内存,直接被系统kill。只调配置不换硬件的情况下,把yarn.nodemanager.resource.memory-mb调到2048甚至1024,vmem比例调到4,能明显缓解。
6.4 经典案例三:启动时卡在SSH密码验证
如果你是手动启动(没有配好hadoop用户SSH免密),start-dfs.sh每次启动到每个节点都会提示输入密码,让你怀疑人生。这种情况有两种解法:
- 按2.4节配置当前用户的SSH免密
- 每次启动输入密码(不推荐,单机尚可忍受,学集群时绝对痛苦)
还有一个经典误区:在root下配了免密,切到hadoop用户后又失效。密钥是跟着用户走的,切换用户后必须重配,这个前面反复强调过。
6.5 最后的手段:日志清空重来
如果你的环境已经被改得乱七八糟,与其一行行排查,不如推倒重来,20分钟内能搞定。按顺序执行:
# 停掉所有服务 sbin/stop-all.sh # 删除所有数据目录 rm -rf /home/hadoop/hadoop_data/* rm -rf /home/hadoop/hadoop/logs/* # 重新格式化(只需格式化NameNode) bin/hdfs namenode -format # 重启 sbin/start-dfs.sh sbin/start-yarn.sh # 检查进程 jps80%的“改了配置但没生效”问题,都是配置文件改了以后没有重启对应的服务。Hadoop不会热加载配置,stop-dfs.sh之后必须start-dfs.sh,YARN同理。改配置后顺手重启,能规避大部分灵异事件。
7. 单机环境日常使用和养好的操作习惯
Hadoop装好之后不是终点,日常使用中有几个操作习惯如果不养好,后面学集群时还得二次踩坑。
日常启停别用kill,用脚本。有些新手发现进程有问题,直接kill -9干掉NameNode或ResourceManager的进程。这是大忌。HDFS写了一半的数据、元数据日志可能还没落盘,强杀轻则丢数据,重则下次启动直接崩溃。正确做法永远是用Hadoop自带的脚本来停:
sbin/stop-dfs.sh sbin/stop-yarn.sh启动顺序别搞反。先启动HDFS再启动YARN,停止时反过来,先停YARN再停HDFS。虽然顺序反了不一定会报错,但按规范操作能少遇到很多不稳定性。
在HDFS上查看文件,不要把hdfs命令和linux命令搞混。经常有人问我为什么ls /test/input在HDFS上看不到文件——那是当然的,ls查的是Linux本地目录。HDFS里查文件要用hdfs dfs -ls /test/input。记住一个原则:操作HDFS的命令都以hdfs dfs开头,操作本地文件系统的命令才用Linux原生命令。两者之间的数据流动通过-put(本地上传HDFS)和-get(HDFS下载到本地)完成。
设置HDFS回收站。在core-site.xml里加以下配置,可以让你误删文件时有后悔药:
<property> <name>fs.trash.interval</name> <value>1440</value> </property>1440表示回收站文件保留1440分钟(一天)。加了这行之后,用hdfs dfs -rm删除文件不会立刻物理消失,而是进.Trash目录。这对新手来说太重要了,你很可能在练习时手滑删掉自己的测试数据。
规划好数据目录备份。单机环境虽然不涉及高可用,但hadoop_data/namenode里的元数据是你HDFS上所有文件的“目录音箱”,丢了就相当于整个文件系统目录结构全丢了。建议定期把/home/hadoop/hadoop_data/namenode打包备份到独立磁盘或云存储上:
tar -zcvf namenode_backup_$(date +%Y%m%d).tar.gz /home/hadoop/hadoop_data/namenode遇到报错先看日志,再看网络上的教程。搜索报错信息时,直接搜日志里最后一行错误描述的中文翻译或英文原文,比搜“Hadoop启动失败”这种大而泛的关键词有效得多。日志信息永远是第一手真相,教程只能给你提供参考。
8. 给新手的几句实在话
按完整流程走下来的你,现在已经拥有了一套能正常工作的Hadoop单机环境。回顾整个部署过程,你会发现真正核心的东西其实就几项:JDK配置、核心配置参数、格式化、启停顺序。这套流程熟练之后,你完全可以做到30分钟内从零到一装好一套环境。
顺着这个环境往下学习,建议按这个顺序走:
- 先多用HDFS命令,对文件的增删改查玩熟,理解块、副本、NameNode、DataNode这些概念的实际表现
- 然后跑几个示例的程序(如WordCount、排序示例),跑通MapReduce的输入输出流程
- 熟悉基础之后,再看伪分布式基础上加一台机器扩展成完全分布式集群,此时你会发现自己已经理解了大半内容
- 最后再考虑Hive、Spark这些上层组件,它们依赖Hadoop环境,但学习曲线相对平缓,你可以按需求逐步引入
Hadoop的部署只是起点,真正值钱的是你对分布式存储与计算心智模型的理解。这套单机环境就是你实验中最重要的实验田,几乎所有Hadoop特性,从HDFS的高级命令到YARN的资源池配置,都能在这台机器上先演练再上生产环境。
最后再强调一下:配置出错不是你的错,是必备的历练。Hadoop传统意义上的“复杂”,不完全是技术难度,更多是版本兼容、环境差异、文档不全这些工程现实。我把最典型的坑都摆在明面上了,剩下的就交给你动手了。装好了,你的大数据学习旅程才算真正按下启动键。