如果你已经刷到过一大堆Hadoop安装教程,却总被“伪分布式”“完全分布式”“SSH免密”这些词搞得云里雾里,那这篇Hadoop安装与搭建全流程教学就是冲着你来的。我会从零开始,把前置环境、JDK安装、配置文件改动、启动验证、常见报错全部过一遍,保证每一步都能照着敲,不玩虚的。
这套流程我前前后后在不同机器上装过不下十遍,坑基本都踩熟了,你照着走就行。文章很长,建议先收藏再慢慢看,或者配合虚拟机一起操作,效果最好。内容适用对象很明确:刚接触大数据、学校课程要求搭建Hadoop环境、或者准备面试想自己动手跑通一套集群的人。
1. 装Hadoop前,先把整体思路捋清楚
1.1 三种部署方式怎么选
Hadoop部署方式,常规区分是三种:单机模式、伪分布式、完全分布式。很多时候教程一上来就让人跑完全分布式,结果机器配置不够、网络配置出错,折腾半天连NameNode都起不来,非常打击信心。
- 单机模式:默认配置,不需要任何修改,主要用于跑MapReduce的本地调试。整个过程不涉及HDFS,不对应真实生产场景。
- 伪分布式:在单台机器上,用不同进程模拟出Hadoop集群的角色,NameNode、DataNode、ResourceManager、NodeManager都在同一台机器上跑。学习和开发阶段用这个最合适。
- 完全分布式:至少三台机器,分别部署不同角色,最接近生产环境,但配置复杂度直接翻倍。
对于初学者,我强烈建议先把伪分布式跑通,理解了HDFS读写、YARN任务调度之后,再扩展成完全分布式集群。直接把三台机器的物理机或虚拟机一次配好,经常出问题,而且系统排查难度大,不适合入门。
1.2 版本选型和目录规划
Hadoop版本选择,建议直接用Apache社区版,版本号选3.x以上的稳定版,比如3.3.4、3.3.6都可以。不要用2.x的老版本,很多配置项和命令行为都不一样,网上的资料过于混杂,容易踩坑。
JDK方面,Hadoop 3.x要求Java 8或Java 11。建议直接装JDK 8,因为后续跑Hive、Spark等生态组件时,JDK 8的兼容性目前仍然是最好的。
路径规划很重要,如果一开始随便装,后续配置环境变量、扩展集群都会很乱。我在多台机器上验证过的标准目录如下:
/opt/software # 存放所有安装包,tar.gz、jdk、hadoop压缩包等 /opt/module # 软件实际解压后的安装目录对应命令:
sudo mkdir -p /opt/software /opt/module sudo chown -R $USER:$USER /opt/software /opt/module把目录所有者改成当前用户,后面就不用反复sudo了,操作体验会顺很多。
1.3 系统环境和规划建议
操作系统建议用CentOS 7.x、CentOS 8.x或者Ubuntu 20.04以上版本,内存至少4GB。伪分布式对内存要求不高,但如果还要跑Zookeeper、Hive之类的组件,建议内存分配8GB以上。
主机名建议提前改好,不要用localhost去搭建集群场景。单机伪分布式可以不改,但后面扩展集群时必须先养成规划主机名的习惯。例如:
sudo hostnamectl set-hostname hadoop01然后编辑/etc/hosts,加上IP和主机名的映射关系。很多坑都出在hostname解析上,后面会细说。
2. 前置环境准备:JDK和SSH免密登录
2.1 JDK安装与环境变量配置
JDK安装没有太多技术含量,但环境变量一旦PATH写错,后续java命令无法生效,会浪费大量时间。先用tar命令解压JDK:
tar -zxvf jdk-8u202-linux-x64.tar.gz -C /opt/module/建议将解压后的目录重命名为方便记忆的名字:
cd /opt/module/ mv jdk1.8.0_202 jdk8然后配置环境变量,编辑vi /etc/profile,在文件末尾追加:
export JAVA_HOME=/opt/module/jdk8 export PATH=$PATH:$JAVA_HOME/bin刷新配置并验证:
source /etc/profile java -version如果输出类似java version "1.8.0_202",说明JDK安装成功。这里有个细节:source /etc/profile只对当前会话生效,重新连接SSH或者重启机器后,通常也能正常读取系统级profile,但如果不生效,检查一下是否在~/.bashrc里也补了同样的export。
2.2 SSH免密登录的原理解析
Hadoop进程之间通信依赖SSH,尤其是NameNode需要通过SSH远程启动或停止各节点的DataNode进程。如果频繁输入密码,集群脚本根本无法运行。
免密登录的原理可以这样理解:A机器生成一对密钥(公钥和私钥),把公钥放到B机器的授权列表里。之后A访问B时,B用公钥验证A持有的私钥,验证通过就直接放行。这和我们用门禁卡刷办公楼的逻辑几乎一样,卡面信息(公钥)是公开的,但刷卡时门禁要确认物理卡本身(私钥)是真实的。
操作如下:
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys-P ''表示不设置密码短语,这样免密登录就完全静默执行。然后测试:
ssh localhost第一次SSH的时候会提示确认指纹,输入yes回车。之后再次连接就不需要密码了。
2.3 其他系统基础配置
需要提前关闭防火墙和安全策略,否则后面访问Hadoop的Web界面时可能被拦,排查起来又麻烦。CentOS下的操作:
systemctl stop firewalld systemctl disable firewalld如果你是Ubuntu系统,检查ufw状态:
sudo ufw disable另外如果用的是云服务器,还要确认安全组放行相关端口,比如NameNode的9870、YARN的8088等。本地虚拟机的话,关闭防火墙就足够。
3. 核心安装:Hadoop解压与配置文件逐个拆解
3.1 Hadoop解压与目录结构
下载Hadoop安装包,推荐从清华或阿里镜像站下载,速度比官网稳定得多。拿到tar.gz包后:
tar -zxvf hadoop-3.3.6.tar.gz -C /opt/module/ cd /opt/module/ mv hadoop-3.3.6 hadoop解压完成后进入hadoop目录,用ll可以看到以下重要子目录:
- bin:HDFS、YARN常用的客户端命令,比如hdfs、yarn、mapred。
- sbin:启动和停止服务的脚本,比如start-dfs.sh、start-yarn.sh。
- etc/hadoop:配置文件目录,后面主要改这里。
- share/hadoop:官方自带的jar包和示例程序。
很多教程会让人先跑一下hadoop version看看是否安装成功,但这时还没配置环境变量,所以要么先配置,要么用相对路径运行。直接先配环境变量会省事很多。
3.2 核心环境变量配置
编辑vi /etc/profile,新增Hadoop相关环境变量:
export HADOOP_HOME=/opt/module/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop然后执行source /etc/profile,运行hadoop version,能看到版本信息就代表Hadoop已经可以基本使用了。不过此时还缺关键一步,需要在hadoop-env.sh里指定JAVA_HOME。
3.3 五个关键配置文件解析
Hadoop的配置主要围绕etc/hadoop目录下的五个文件展开。逐个改动前,先理解每个文件的作用,这样以后调优也不会懵。
第一个是hadoop-env.sh。这个文件负责定义Hadoop运行时的JVM参数和环境变量。找到文件中JAVA_HOME的位置,修改为绝对路径:
export JAVA_HOME=/opt/module/jdk8强烈建议直接写成绝对路径,不要在这个文件里用$(which java)之类的动态获取方式,因为Hadoop在通过SSH远程启动节点时,环境变量经常加载不完整,动态获取容易失败。
第二个是core-site.xml。它定义了Hadoop集群的全局属性,最关键的是默认文件系统。配置如下:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop01:8020</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/module/hadoop/tmp</value> </property> </configuration>fs.defaultFS指定了NameNode的地址和端口,端口默认8020,也可以写成9000,不同版本有默认区别,建议显式指定。hadoop.tmp.dir非常重要,它决定了NameNode元数据、DataNode数据块的存储根目录。如果不设置,默认会使用/tmp目录,系统一旦重启清理了临时文件,你的HDFS数据就可能全部丢失,这个坑非常经典。
第三个是hdfs-site.xml。主要配置NameNode和DataNode的存储路径、副本数等。伪分布式场景下,副本数建议设置为1:
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///opt/module/hadoop/tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///opt/module/hadoop/tmp/dfs/data</value> </property> </configuration>dfs.replication为1,意味着每个文件只存一份副本。集群环境一般设置为2或3,取决于节点数。副本数并不是越多越好,它直接占用存储空间,要根据可用节点数量来决定。
第四个是yarn-site.xml。YARN负责资源调度和任务分配。伪分布式需要配置如下:
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.env-whitelist</name> <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH.PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_HOME,PATH,LANG,TZ</value> </property> </configuration>yarn.nodemanager.aux-services配置为mapreduce_shuffle,这是MapReduce任务在YARN上运行的必需项,它相当于Map和Reduce之间数据传输的辅助服务。缺失这个配置,任务会一直卡在Running状态却不执行。
第五个是mapred-site.xml。这个文件在早期版本中需要从模板复制,新版本已经自带。配置MapReduce运行时框架为YARN:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>有的教程还会加上mapreduce.jobhistory.address的配置,那是给JobHistory服务用的,伪分布式阶段可以先不加,避免一开始就堆太多概念。
3.4 workers文件与格式化
workers文件(旧版本叫slaves)用于定义哪些节点作为DataNode或NodeManager。因为是伪分布式单节点,所以只需写入当前主机名:
hadoop01改完之后,第一次启动HDFS前,必须执行格式化命令。格式化的作用是初始化NameNode的元数据目录,生成一个唯一的集群ID。命令如下:
hdfs namenode -format如果看到successfully formatted的字样,说明格式化成功。
这里必须反复强调:格式化操作只能在第一次启动前执行。如果集群已经启动过,之后因为配置修改想重新格式化,必须先删除NameNode和DataNode的数据目录,否则会出现集群ID不一致的问题,表现为DataNode进程能起来,但就是无法注册到NameNode。
3.5 启动HDFS和YARN验证
启动之前,先把目录准备好,避免权限问题:
mkdir -p /opt/module/hadoop/tmp cd /opt/module/hadoop/sbin/ ./start-dfs.sh ./start-yarn.sh注意输出日志里如果有WARN util.NativeCodeLoader: Unable to load native-hadoop library,这是缺少本地native库的警告,不影响使用,可以忽略。
启动后,用jps命令查看Java进程:
jps正常情况下应该看到以下五个进程:
- NameNode
- DataNode
- SecondaryNameNode
- ResourceManager
- NodeManager
如果进程数量不齐,说明某一步配置出了问题,后面常见问题章节会详述。
Web界面验证也很直接。HDFS管理界面访问地址是http://hadoop01:9870,可以看到文件系统概况、节点状态和数据块信息。YARN资源管理界面访问http://hadoop01:8088,可以查看正在运行的任务和集群资源情况。
4. 从伪分布式平滑扩展到完全分布式集群
4.1 集群节点规划与主机名映射
把伪分布式扩展成完全分布式,原理上没有新增内容,只是把角色分散到多台机器上。一般来说,三台机器是最低配置,推荐规划如下:
- hadoop01:NameNode、ResourceManager、SecondaryNameNode
- hadoop02:DataNode、NodeManager
- hadoop03:DataNode、NodeManager
扩展前,先把每台机器的主机名改好,并在每台机器的/etc/hosts中添加完整的IP映射:
192.168.1.101 hadoop01 192.168.1.102 hadoop02 192.168.1.103 hadoop03注意不要写127.0.0.1 hadoop01这样的映射,否则NameNode之间通信时匹配不到正确的IP,容易出现莫名其妙的宕机。
4.2 免密登录的扩展方向
完全分布式集群中,NameNode所在机器需要能免密登录所有DataNode机器。所以需要在hadoop01上生成密钥,并把公钥分别分发到hadoop02和hadoop03上。
ssh-copy-id hadoop02 ssh-copy-id hadoop03ssh-copy-id命令会自动把本地公钥追加到目标机器的authorized_keys文件里,期间需要输入一次目标机器的用户密码。为了保险起见,还可以让每台机器都把自己公钥写入本机以及其他机器,方便后续操作脚本执行。
4.3 分发配置与启动顺序
在hadoop01上完成全部配置文件的修改后,用rsync或scp把整个Hadoop安装目录分发到另外两台机器:
rsync -av /opt/module/hadoop hadoop02:/opt/module/ rsync -av /opt/module/hadoop hadoop03:/opt/module/然后再把JDK和环境变量一起分发。注意,只需要在hadoop01上执行hdfs namenode -format,其他节点绝对不要格式化,否则集群ID不统一,集群就废了。
首次启动时,在hadoop01上执行:
start-dfs.sh start-yarn.sh脚本会通过SSH自动在所有节点上启动对应进程。之后用jps分别检查每台机器的进程,对照规划表验证是否齐全。
4.4 关于Hadoop和Zookeeper整合的简要说明
热词里出现“hadoop和zookeeper整合实战”,这里顺带讲一下。Zookeeper不是Hadoop运行的必选组件,HDFS的高可用架构(HA)才需要Zookeeper,它负责监控NameNode的状态,并在主NameNode故障时自动完成切换。
如果只是学习阶段,伪分布式完全不需要Zookeeper。但如果你计划搭建HA模式,那么Zookeeper集群一般独立部署在奇数台机器上(3台或5台),配置核心是zoo.cfg中的server.1、server.2这类节点列表,然后所有NameNode和DataNode的配置里增加ha.zookeeper.quorum参数,具体内容需要单独展开细讲,这里先不展开。
5. 常见问题与排查技巧实录
5.1 大数据安装后必须掌握的排查思路
Hadoop安装出问题,不要慌。按照“网络→端口→日志→配置”的顺序排查,能解决90%的问题。
先看进程是否存在,通过jps确认;再通过网络连通性测试,比如ping hadoop02确认网络可达;再看端口是否监听,ss -tlnp | grep 9870可以确认NameNode Web端口是否正常打开;最后才看日志,Hadoop日志位于每个节点的/opt/module/hadoop/logs目录下,文件命名一般是hadoop-<用户>-<角色>-<主机名>.log,比如hadoop-hadoop-namenode-hadoop01.log。
日志文件比任何教程都有话语权。遇到问题时,优先看日志尾部,一般Error信息会明确告诉你缺什么配置、端口被占用还是权限不足。
5.2 典型报错与解决方案对照表
我整理了在Hadoop安装搭建、Hive配置、Zookeeper整合以及日常运维中踩过的典型问题,用一张表列出来,按图索骥:
| 报错现象或提示 | 可能原因 | 解决方案 |
|---|---|---|
java.lang.NoClassDefFoundError: org/apache/hadoop/crypto/... | Hadoop公共库未被正确加载,常见于Hive、Tez、Spark组件与Hadoop版本不兼容 | 统一各组件编译版本,检查HADOOP_CLASSPATH和HIVE_AUX_JARS_PATH,将hadoop-common.jar加入CLASSPATH,或重新下载对应版本的hadoop-client |
| 8088端口打不开页面 | ResourceManager没启动,或防火墙拦截 | 检查jps是否有ResourceManager;关闭防火墙;查看yarn-site.xml是否配置了yarn.resourcemanager.webapp.address |
| DataNode进程存在,但Web界面显示1个节点且Live Nodes为0 | 执行了多次格式化,NameNode和DataNode的clusterID不一致 | 停止所有进程,删除每个节点的tmp/dfs/name和tmp/dfs/data目录,重新格式化NameNode再启动 |
Incompatible clusterIDs | 多次格式化后集群ID不匹配 | 删除所有节点的数据目录后重新格式化,必须全删干净,一个都不能留 |
启动时提示Permission denied (publickey) | SSH免密失效 | 检查~/.ssh/authorized_keys是否存在且权限为600,~/.ssh目录权限为700 |
上传文件到HDFS时报No space left | 伪分布式副本数设为3,但只有一个DataNode,无法满足副本策略 | 修改hdfs-site.xml的dfs.replication为1,同时检查磁盘空间 |
UnsupportedClassVersionError | JDK版本过高或过低,Hadoop与该JDK不兼容 | 统一使用JDK 8,重新编译或替换组件版本 |
start-dfs.sh卡在localhost: Permission denied | 当前用户对SSH授权目录权限配置错误 | 确保当前用户是Hadoop安装目录的属主,执行chown -R $USER:$USER /opt/module |
| NameNode启动后自动退出 | hadoop.tmp.dir未显式配置,系统重启后临时文件被清理 | 在core-site.xml设置专门的存储目录,彻底解决 |
5.3 最容易被忽略的几个细节
第一,JAVA_HOME的路径不能只配在/etc/profile里。Hadoop的很多子进程通过SSH远程启动,SSH会话不一定加载profile文件,所以hadoop-env.sh里的JAVA_HOME必须写成绝对路径,这个我之前反复强调,但每次帮人排查还是会遇到踩中的。
第二,不要随手执行hdfs namenode -format。每一次格式化都会生成新的集群ID,除非你明确知道要清空数据,否则就是亲手制造问题。如果需要重新格式化,提前把日志文件和元数据目录备份起来,至少能用来对比分析。
第三,遇到中文路径要格外小心。如果不小心把安装包的存放路径设置成带中文目录名,某些组件解析文件路径时会出现编码问题,表现为启动报错或任务卡死。安装软件这类操作,目录路径尽量全英文。
5.4 如何验证你的集群已经真正可用
启动完成后,很多人不知道该怎么确认集群是否真的能用。单纯看进程还不够,建议做一次真实的文件上传和下载测试。
在HDFS上创建目录并上传文件:
hdfs dfs -mkdir -p /test/input echo "hello hadoop" > /tmp/test.txt hdfs dfs -put /tmp/test.txt /test/input/ hdfs dfs -cat /test/input/test.txt如果cat能输出文件内容,说明HDFS读写链路是通的。接着跑一个官方自带的MapReduce示例程序,验证YARN是否正常工作:
cd /opt/module/hadoop hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /test/input /test/output等待任务跑完后,查看结果:
hdfs dfs -cat /test/output/part-r-00000如果看到单词统计结果,说明MapReduce的计算链路也完全跑通了。到这一步,你的Hadoop环境才是真正“能用”的状态,而不是只有进程列表好看。
5.5 关于Hadoop的启停命令速查
日常使用中,常用的启停命令及对应作用整理如下:
start-dfs.sh:启动HDFS相关进程,包括NameNode、DataNode、SecondaryNameNodestart-yarn.sh:启动YARN相关进程,包括ResourceManager、NodeManagerstop-dfs.sh:停止HDFS相关进程stop-yarn.sh:停止YARN相关进程start-all.sh:合并启动HDFS和YARN,在早期版本常用,新版本不推荐,容易让人忽视组件拆分逻辑hdfs dfsadmin -report:查看各DataNode的存储情况和节点状态hdfs dfs -du -h /:查看HDFS各目录占用情况
我在实际使用中更习惯于单独执行start-dfs.sh和start-yarn.sh,这样可以更清晰地定位问题出在哪一层。生产环境也是一样,HDFS和YARN逐步启动比一把梭更安全。
5.6 Ubuntu环境下的额外注意事项
如果你用的是Ubuntu而不是CentOS,路径和行为会有一点点差异。Ubuntu的默认shell是bash,但/etc/profile和~/.bashrc的加载机制不同,如果hadoop version不生效,先在~/.bashrc里追加环境变量再source ~/.bashrc。
Ubuntu的防火墙管理工具是ufw,命令前面说过。另外一个常见的坑是,Ubuntu的openjdk可能不全,建议从Oracle官网下载JDK 8,避免出现javac命令找不到的情况。
还有,Ubuntu的dash与bash在脚本执行上存在解析差异,有些Hadoop自带的shell脚本在Ubuntu上会报语法错误,这时不用改脚本,只需把/bin/sh重新指向bash,或者用bash 脚本名.sh的方式强制执行。如果你不确定当前环境,优先用bash来跑所有安装脚本。
写在最后的一些个人体会
按照这套流程完整走下来,你会对Hadoop的安装与搭建有一个比较体系化的理解。很多人装Hadoop失败,并不是某个配置有多难,而是在版本混用、路径混乱、格式化次数过多这类细节上翻车。我的体会是,安装大数据组件时,宁可慢一点,也要把每个配置文件的作用、每个参数的意义真正搞清楚,这样后面搭Hive、Spark、Flume之类生态组件时,才有底气去应对底层抛出来的异常。
最后再分享一个小技巧:每次改完配置,在启动服务之前,先把所有配置文件的XML格式检查一遍,标签是否闭合、属性名是否拼错,这两类低级错误占了启动失败的相当大比例。用xmllint工具可以快速验证,如果没有安装,至少也要打开文件扫一眼结构与缩进。希望这套流程能帮你少走一些弯路,剩下的事情就交给你的耐心了。