伪分布式Hadoop搭建指南:从环境检查到WordCount实战
1. 环境准备装之前的三个硬性检查开始之前先把话说透。伪分布式Hadoop测试这个事说难不难但环境不对后面每一步都是坑。我自己带过不少新人也看过太多人在第一步就栽跟头所以我先把前置环境里最容易出问题的三个点拎出来讲清楚你照着做后面会顺很多。第一个检查项JDK版本。Hadoop 3.x要求JDK 8以上我实测用JDK 8最稳JDK 11也能跑但一些老项目的脚本可能会有兼容性怪癖。检查方法很简单java -version如果你输出的版本是1.8.0_xxx那就没问题。如果没装或者版本太老先去Oracle官网或者用OpenJDK装一个路径记住后面配JAVA_HOME要用。第二个检查项SSH免密登录。伪分布式虽然只有一台机器但Hadoop的脚本会通过SSH连接localhost来启动和停止守护进程所以必须配好免密。这个不配你每次启动集群都会被要求输密码甚至直接失败非常糟心。第三个检查项内存和磁盘。伪分布式跑测试不需要多高的配置2核4G的虚拟机就够用磁盘预留10G左右比较稳妥。需要注意的是NameNode和DataNode都会写大量日志如果你用的是云服务器注意系统盘别被撑爆。这三个检查做完环境基本上就没大问题了。接下来我们进入正题下载、解压、配置、启动、测试一条龙走完。2. 核心思路拆解为什么先用伪分布式来学Hadoop很多人一上来就想搭真正的分布式集群动辄三台五台机器结果环境配置就劝退了一半人。我的建议一直很明确先从伪分布式开始把HDFS和YARN的机制跑通再考虑扩展成集群这是性价比最高的学习路径。伪分布式的核心逻辑其实非常简单一台物理机上用多个Java进程分别模拟Hadoop集群中的不同角色。也就是说你的机器既当NameNode又当DataNode同时还是ResourceManager和NodeManager。听起来有点分裂但这个设计恰恰是Hadoop最巧妙的入门台阶它把分布式系统最核心的通信机制、存储机制、调度机制全部压缩在一台机器上让你能亲手摸到。为什么要这么做因为Hadoop的分布式架构里真正复杂的东西不是安装本身而是各组件之间的通信关系。比如客户端往HDFS写数据时要先问NameNode要元数据再找到DataNode去写块提交作业给YARN时ResourceManager要协调ApplicationMaster和NodeManager的协作。这些流程在伪分布式模式下和真实集群调用的接口、走到的代码路径几乎完全一样唯一区别就是所有进程都在同一台机器上。所以伪分布式不是“玩具”它是Hadoop官方推荐的单机教学模式资源配置可以尽可能简化但流程是真实的。有个细节要注意伪分布式和本地模式是有本质区别的。本地模式standalone mode下Hadoop用本地文件系统来模拟HDFS所有进程跑在一个JVM里主要是用来调试MapReduce代码的。而伪分布式pseudo-distributed mode会真正启动NameNode、DataNode这些守护进程走真正的RPC通信和HDFS存储协议。你在网上搜教程一定要分清这两种模式否则极易混淆。我自己带项目的经验是先用本地模式跑通WordCount确认代码逻辑没问题再切到伪分布式模式验证整个集群环境的稳定性最后才去扩集群这个阶梯上去基本不会摔。这套流程已经被很多团队验证过是最稳妥的路径。3. 伪分布式搭建实操下载、解压与三大配置文件的逐一解析现在进入实操环节。我以CentOS 7.9 Hadoop 3.3.6为例这套组合经过大量实践验证非常稳定踩坑概率最低。Hadoop 2.x虽然还有不少老项目在用但新学的话没必要回头了直接上3.x。3.1 下载与解压下载地址我推荐用国内镜像速度快而且稳定Apache官网的下载速度在部分地区实在感人。镜像站选一个你手边访问最快的就行# 以清华源为例 wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -xzvf hadoop-3.3.6.tar.gz -C /opt/ mv /opt/hadoop-3.3.6 /opt/hadoop解压完之后建议顺手把属主和属组改一下避免后续权限问题chown -R hadoop:hadoop /opt/hadoop因为我习惯用专门的hadoop用户来跑集群不用root。这里多说一句永远不要用root用户跑Hadoop虽然能跑但后续做权限测试时会遇到各种莫名其妙的坑而且HDFS本身的权限模型会在root下被绕过这对你理解HDFS的权限机制没有任何帮助。3.2 三个关键配置文件详解Hadoop的配置看似文件很多但伪分布式场景下真正需要动的就四个文件。我先讲三个core-site.xml、hdfs-site.xml、mapred-site.xmlyarn-site.xml放下一节单独讲。第一个是core-site.xml它定义了HDFS的访问入口和临时目录。核心配置就是fs.defaultFS指向NameNode的RPC地址configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name valuefile:///opt/hadoop/data/tmp/value /property /configuration这里的hdfs://localhost:9000就是HDFS的“门户地址”。客户端读写HDFS时都会先访问这个地址去获取元数据信息。hadoop.tmp.dir是NameNode、DataNode存储数据的公共基础目录默认在/tmp下但系统重启会清空/tmp这就可能导致元数据丢失所以强烈建议改到自定义路径。初次配置时记得建好目录比如mkdir -p /opt/hadoop/data/tmp。第二个是hdfs-site.xml它决定了副本数和NameNode的元数据存储位置configuration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name valuefile:///opt/hadoop/data/namenode/value /property property namedfs.datanode.data.dir/name valuefile:///opt/hadoop/data/datanode/value /property /configurationdfs.replication必须设为1这是伪分布式和真实集群最直观的区别伪分布式只有一台DataNode如果副本数写3HDFS会因为没法写满副本数而不断告警甚至进入安全模式。我在测试环境见过太多人因为这个踩坑特此提个醒。dfs.namenode.name.dir和dfs.datanode.data.dir分别指定元数据和数据块的存储位置同样建议放在自定义路径下别用默认的/tmp。第三个是mapred-site.xml它决定了MapReduce作业跑在哪套调度框架上。在Hadoop 3.x里这等同于把MapReduce从“本地跑”切换到“YARN上跑”configuration property namemapreduce.framework.name/name valueyarn/value /property /configuration这里设置为yarn意味着MapReduce作业将由YARN统一调度资源这样后面你会看到提交作业时ApplicationMaster启动、Container分配资源这些过程全部走真实流程价值非常大。3.3 环境变量与YARN配置配置文件改完之后别忘了设置环境变量。编辑/etc/profile在末尾追加export HADOOP_HOME/opt/hadoop export PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk注意JAVA_HOME一定要写你的实际JDK路径可以用readlink -f $(which java)查出来不要直接用/usr/bin/java因为Hadoop脚本里会对JAVA_HOME做路径拼接指到/usr/bin/java会直接报错。然后配置yarn-site.xml。对于伪分布式YARN配置的关键是让ResourceManager和NodeManager都跑在本机并且开启yarn.nodemanager.aux-services否则MapReduce作业无法正常运行configuration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.resourcemanager.hostname/name valuelocalhost/value /property /configuration这里的mapreduce_shuffle不是随便填的。MapReduce的Reduce阶段需要从各个Map Task所在节点拉取中间结果这个“拉取”的过程称为Shuffle是MapReduce性能的核心之一。yarn.nodemanager.aux-services就是告诉NodeManager要开启这个Shuffle辅助服务如果漏配作业会卡在SHUFFLE阶段起不来日志里全是Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster。还有一个容易被忽略的点Hadoop 3.x默认使用的hadoop.tmp.dir如果不指定NameNode格式化时会把元数据写到系统默认路径重启机器可能丢失。我在生产环境排障时经常遇到这种问题特别是云服务器重启后Hadoop直接起不来一看日志发现元数据文件没了所以这一步切记不要偷懒。3.4 格式化NameNode一次性的初始化操作配置完成后启动集群前必须先格式化NameNode。这是整个安装过程中最容易出问题的一步搞不好后面全白搭。hdfs namenode -format看到Storage directory ... has been successfully formatted就说明成功。格式化干的事情是把NameNode的元数据存储目录初始化成可以接收HDFS元数据的空仓库结构里面会用current/VERSION记录集群ID和命名空间ID同时产生一个fsimage_0000000000000000000镜像文件。格式化只做一次不要反复格式化因为每次会生成新的集群ID如果DataNode里存的集群ID和NameNode不一致DataNode注册会失败表现为数据节点明明活着但HDFS里就是看不到可用空间。如果不幸已经反复格式化了对伪分布式来说最简单的解决办法是删掉namenode和datanode目录重新来一次因为单机测试环境没有真实数据需要保留这个代价可以承受。但在真实集群里这种操作要格外谨慎必须停机而且确认没有多余的DataNode在跑否则容易把数据搞丢。格式化完之后可以顺手检查一下目录结构ls -l /opt/hadoop/data/namenode/current/里面应该有fsimage_*和VERSION文件这表示元数据初始化成功。4. 启动与验证HDFS和YARN可能各自为政4.1 启动HDFS服务首先要确认SSH免密登录配置好了否则启动脚本会在连接localhost时停下ssh localhost如果能直接登进去不需要输密码就说明没问题。如果还是会要密码执行ssh-keygen -t rsa -P -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys配好之后再次验证。这个配置看似简单但极其重要Hadoop的sbin/start-dfs.sh脚本会通过SSH依次远程启动NameNode和DataNode如果SSH卡住后面的服务全部起不来。启动HDFS$HADOOP_HOME/sbin/start-dfs.sh启动成功的标志是日志里出现Starting namenodes on [localhost]、Starting datanodes这类输出并且进程存在jpsjps是JDK自带的一个小工具专门用来查看Java进程比ps aux | grep java方便很多。正常情况下你会看到以下进程进程名角色说明NameNodeHDFS元数据管理相当于“图书馆总目录”DataNode数据块存储相当于“书架上的书”SecondaryNameNode定期合并NameNode的编辑日志相当于“定期备份整理员”如果jps报错说明环境变量还没生效先source /etc/profile或者重开一个终端。4.2 启动YARN服务然后启动YARN$HADOOP_HOME/sbin/start-yarn.sh启动成功后jps里会多出ResourceManager和NodeManager。到这里一台“伪分布式”机器上同时跑着5个守护进程NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager。这就是之前说的一台机器同时扮演所有角色。4.3 Web界面验证是否真的起来Hadoop提供了两个Web界面这个必须养成习惯去主动打开看因为JPS只能证明进程起了真正有没有“干活”得看状态页面组件地址主要信息HDFShttp://localhost:9870NameNode状态、DataNode列表、HDFS容量YARNhttp://localhost:8088队列资源、运行中的Application、节点状态我个人的习惯是启动之后先看HDFS页面里DataNode的“Live Nodes”是不是1如果是0说明DataNode没注册上。这个和jps有无DataNode进程是两回事进程在跑不代表它注册成功。常见原因就是之前说的集群ID不一致或者网络配置问题把DataNode日志翻出来一看便知。再看YARN页面如果打开后能看到Active Nodes有1说明NodeManager也注册成功了。这里如果只有0多半是yarn-site.xml里没配yarn.resourcemanager.hostname或者配的localhost和实际主机名对不上。4.4 HDFS基础操作首次真实写入文件为了确认HDFS能正常工作先做一次简单的文件操作测试hdfs dfs -mkdir -p /test/input echo hello hadoop hello hdfs /tmp/test.txt hdfs dfs -put /tmp/test.txt /test/input/ hdfs dfs -ls /test/input/看到Found 1 items就说明HDFS已经能正常读写。这里如果报错mkdir: Permission denied可以确认一下当前用户是否有权限因为HDFS的根目录默认属主是执行格式化的那个用户。实在嫌麻烦伪分布式测试环境可以直接改权限hdfs dfs -chmod -R 777 /。但说实话我更建议你去理解一下HDFS的权限模型这是面试常问的点。另外提醒一句hdfs dfs和hadoop fs在Hadoop 3.x里都可用hdfs dfs更语义化一些建议统一用这个。5. 跑一个真实的MapReduce测试WordCount实战5.1 准备示例程序Hadoop发行包里自带了一批示例JAR包其中hadoop-mapreduce-examples-3.3.6.jar里就有经典的WordCount程序。这个程序虽然是“教学玩具”但整个作业在YARN上的执行链路和真实业务的MapReduce作业完全一致。我们用它在HDFS上跑一次完整作业验证整个链路的可用性。5.2 创建测试目录并放数据hdfs dfs -mkdir -p /test/input hdfs dfs -put /tmp/test.txt /test/input/ hdfs dfs -cat /test/input/test.txt能看到文件内容说明HDFS读写正常。5.3 运行WordCounthadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /test/input /test/output这里有几个点注意一下输出目录/test/output必须不存在如果已经存在会直接报错因为MapReduce的输出目录是被作业独占的如果存在Hadoop会认为作业冲突直接拒绝执行。另外输出目录不能是输入目录的子目录这是为了保证MapReduce数据流不会产生数据被覆盖或污染的问题。跑起来之后屏幕上会刷一整屏日志重点看两个地方Submitted application application_xxx表示作业已提交成功ApplicationMaster已在队列里。map 100% reduce 100%表示Map和Reduce全部完成作业执行正常。5.4 查看结果hdfs dfs -ls /test/output hdfs dfs -cat /test/output/part-r-00000如果结果里能看到每个单词的计数说明整条链路完全打通。这里多说一句MapReduce跑完的结果文件叫part-r-00000不是part-00000。踩过坑的人知道找半天文件结果发现后缀还有个-r网上很多教程不讲这个细节但实际排障时非常重要。5.5 想想刚才发生了什么作业跑完后强烈建议你趁热做一件事打开YARN Web界面找到刚才那个Application点击进去看一下Container的运行记录。你会发现一个WordCount作业实际上经历了从客户端提交、ApplicationMaster申请资源、NodeManager启动Container、Map阶段并行处理、Shuffle排序、Reduce合并输出这样一个完整过程。这也是我前面强调“伪分布式不是玩具”的原因你在这个界面看到的每一个调度行为在真实集群中依然成立。唯一要注意的是伪分布式下资源有限YARN默认只分配一个Container所以Map和Reduce的并行度都是1运行速度自然会比真实集群慢很多。这属于正常现象不用怀疑配置问题。6. 停止与清理别让进程堆在机器上测试做完照例要把集群停下来攒一堆Java进程在后台占着内存后面其他服务会很难受。$HADOOP_HOME/sbin/stop-yarn.sh $HADOOP_HOME/sbin/stop-dfs.shjps确认一下应该只剩下JPS自己了。如果发现停了但进程还在就是SSH免密配置有问题导致脚本没能连上localhost发送停止指令检查authorized_keys即可。最后提醒一个重复测试时的小技巧如果第二次跑测试时想重新格式化HDFS标准流程是先全停、再删数据目录、再格式化、最后启动。不要图省事直接格式化你会发现DataNode全部注册失败。因为格式化会重新生成集群ID而DataNode目录里存的还是旧集群ID两边对不上注册自然被拒。7. 常见问题与排查技巧实录这一节是我最想让你认真看的因为我自己在带人和做支持的过程中翻来覆去遇到的坑也就这么几个。我把它们单独列出来配上排查思路你以后遇到问题先来这里翻一遍。7.1 JPS没有NameNode进程怎么办可能原因按概率排序格式化没有成功。没初始化元数据NameNode起不来。查看日志文件$HADOOP_HOME/logs/hadoop-hadoop-namenode-*.log如果出现NameNode is not formatted直接hdfs namenode -format重新格式化。JDK路径配错了。日志里出现JAVA_HOME is invalid就是这个问题检查/etc/profile里的JAVA_HOME指向是否真实存在。端口被占用。默认的fs.defaultFS端口是9000和别的服务撞了的话NameNode会因端口绑定失败而退出。7.2 DataNode进程在但Web界面Live Nodes显示0这是初学者最容易遇到的“玄学问题”。解决顺序先看DataNode日志$HADOOP_HOME/logs/hadoop-hadoop-datanode-*.log找Block pool ID needed或DatanodeRegistration相关报错。如果日志里出现集群ID不一致的报错说明NameNode被重复格式化过DataNode里的集群ID已经老了。解决办法停止集群删除namenode和datanode两个数据目录重新格式化再启动。如果日志里一直出现Connection refused检查有没有被防火墙拦了或者DataNode配置的RPC地址根本无法连通到NameNode。7.3 作业提交后卡在ACCEPTED状态不动作业提交到YARN但一直不跑ResourceManager页面上显示ACCEPTED。这个状态说明作业已经进了队列但NodeManager没有资源来分配Container。按下面几步依次排查先看jsp确认NodeManager进程还在不在。不在的话把yarn-site.xml里yarn.nodemanager.aux-services单独拿出来检查。这个我之前强调过漏配会直接在运行时报MapTaskAttemptImpl相关的NoSuchMethodError挺迷惑的。如果NodeManager在但是YARN页面显示0个Active Nodes检查防火墙或/etc/hosts配置确保localhost解析正常。7.4 作业运行失败日志报找不到Output目录或Input目录这类问题九成是路径写错了或者根本没有hdfs://前缀而作业是用本地路径解析的。留意一下hadoop jar里写的输入输出路径默认是被当作HDFS路径处理的。如果确实想用本地路径需要加file:///前缀比如/home/user/test.txt要写成file:///home/user/test.txt。伪分布式阶段我建议所有路径都走HDFS把习惯养好后面上集群会省很多事。7.5 跑在Windows上怎么处理有不少朋友是在Windows本机开发环境里跑伪分布式测试。官方原生不支持Windows但有几个常见做法用WSL跑Linux环境是最稳的路径其次是在Windows里装虚拟机跑CentOS或者用Docker Desktop拉一个Hadoop镜像。网上也有补丁包方式让Hadoop直接跑在Windows Native环境但这个坑比较多我见过不少人在NativeIO和Winutils上浪费一整天不太建议折腾。7.6 伪分布式排障快查表现象第一排查点第二排查点启动脚本卡住SSH免密是否配置/etc/hosts是否解析正常NameNode起不来是否格式化过Java路径是否真实存在DataNode注册失败集群ID是否一致防火墙是否拦截端口作业卡在ACCEPTEDNodeManager是否存活aux-services是否配置作业跑完但没结果文件是否输出了part-r-00000而非part-00000确认Reduce阶段是否执行完成这份表格是我干活时自己也会对着查的清单遇到问题先按表格过一遍能筛掉一半以上的低级坑。8. 几步之后还能怎么玩测试链路通了之后伪分布式的使命其实还可以再往前走几步让这台机器的价值最大化。第一把HDFS的块大小调小一点比如在hdfs-site.xml里加property namedfs.blocksize/name value1m/value /property这样往HDFS里传一个大文件你可以直观看到HDFS是怎么样把文件切分到多个DataNode块里的。虽然伪分布式只有一个DataNode但块信息仍然会在NameNode里被记录清楚。跑一个hdfs fsck /test/input/test.txt -files -blocks你会看到类似“块0、块1...”的清晰输出分布式文件系统的“分块”概念一下就通了。第二试着在YARN上提交一个需要多个Map任务的任务。比如给输入目录塞几十个文件再用一个PI计算示例程序跑一次你会看到YARN页面上的Container数量开始变化。虽然NodeManager在同一台机器上但资源调度的真实流程依然会展现得一清二楚。第三把HDFS的权限测试做一下。建一个普通用户用hdfs dfs -chown改文件属主再尝试用不同身份访问HDFS上的文件观察HDFS的权限控制行为。这个对理解HDFS的权限模型帮助极大也是面试常考的点。第四集成Zookeeper。网上经常拿“Hadoop和Zookeeper整合实战”来做高可用练习。伪分布式也能跑起来因为Zookeeper本身不需要多强配置跑一个单机ZooKeeper实例再把HDFS的高可用模式打开虽然资源紧张时会有点吃力但整个故障切换流程可以完整跑一圈对理解HDFS HA机制价值巨大。我个人在实际操作中的体会是伪分布式测试环境最厉害的地方不是“能跑个WordCount”而是它能让你在一台机器上把整个大数据技术栈的骨架搭起来。HDFS、YARN、MapReduce、Zookeeper、Hive、Spark都能在这个基础上逐个加装起来形成你个人的专属大数据实验室。后面换工作、做面试、跑Demo项目这套环境都是你最趁手的工具。