先把话说在前面:干大数据这行,自己手动搭过一套Hadoop集群的人,十有八九都被配置文件和进程日志折磨过。网上那些动辄几十步的教程,你照着敲到凌晨两点,最后发现是hosts没配对,真的很泄气。所以当我第一次用Playground脚本把一套三节点Hadoop集群在几分钟内拉起来的时候,最大的感受就是:这东西早该出现了。这篇内容,我默认你是刚接触大数据、或者被传统手工部署流程劝退过的新人,我尽量把每一步的核心逻辑讲透,让你不只是“能跑起来”,而是知道为什么这些步骤必不可少。这是系列的第一篇,重心放在最基础的多节点完全分布式部署上,先把地基打好。
1. 动手前的核心认知:Hadoop集群和Playground脚本到底是怎么回事
1.1 先搞懂你要搭的到底是什么
Hadoop不是一个软件,是一个生态。最核心的三件套是HDFS(分布式文件系统)、YARN(集群资源调度)、MapReduce(分布式计算框架)。打个比方,你把HDFS理解成一个超大号的快递仓库,文件被拆成快递盒(数据块),分散存放在不同的货架(DataNode)上;YARN是调度中心,负责把计算任务派发给空闲的工人;MapReduce是拆解任务的工作流程,把复杂活拆成能并行干的小事。
集群的节点角色也分得很清楚:NameNode负责管理整个文件系统的元数据,相当于仓库管理员的脑子,它告诉你某个文件在哪个货架上;DataNode负责实际存放数据块;ResourceManager是YARN的总调度;NodeManager负责在单个节点上执行具体任务;还有辅助角色SecondaryNameNode,很多人误以为它是NameNode的热备,其实它是用来定期合并编辑日志、给元数据做检查点的。
理解了角色,你再看集群规划就清晰了。常见的集群规模有三种:单机模式(所有角色在一个进程里跑,纯学习用)、伪分布式(一台机器上每个角色单独起进程)、完全分布式(至少两台以上机器,每台分担不同角色)。本文要做的就是一个最标准的完全分布式三节点集群:一台Master节点跑NameNode和ResourceManager,两台Worker节点跑DataNode和NodeManager。这是你在企业里最常见的入门级生产形态,麻雀虽小五脏俱全。
1.2 Playground脚本为什么敢说“一键”
所谓Playground脚本,你可以理解成一套把Hadoop部署全流程“自动化”的解决方案。它的价值不在于脚本本身用了多高深的技术,而在于把那些反复折磨人的手工步骤全部沉淀成了代码。你想想,手工部署Hadoop要经历多少步:三台机器装JDK、配环境变量、改hosts、配SSH免密登录、解压安装包、修改好几处配置XML文件、格式化NameNode、逐个启动进程。每一步都是重复劳动,而且边上一步错,后面全崩。
Playground脚本做的事情,就是把这些步骤全部编排进一个可重复执行的执行流里。它会先做环境检测(比如检查你是不是root、Java装了没有、端口有没有被占用),然后自动配置SSH互信、把配置好的安装包分发到所有节点、按角色生成对应的core-site.xml、hdfs-site.xml、yarn-site.xml等配置、统一格式化NameNode、最后按照master和worker的角色分工把进程依次启动。整个过程对操作者是透明的,你只需要关注脚本给你的日志输出。
它真正的核心设计理念是“幂等性”——同一套脚本,你跑了第一次成功,第二次跑也安全,不会因为重复执行就把配置写乱、把文件系统重复格式化。这一点比很多自己人肉敲命令的操作要强太多。所以请你务必建立一个认知:脚本不等于黑盒,它帮你省掉体力活,但架构逻辑还是上面说的那些角色和配置,只是由脚本帮你统一生成和分发而已。
2. 环境准备:跑脚本前把这几件事做踏实
2.1 机器规划与版本选择
这一步做扎实了,后面能省一大半事。我建议的底子是至少三台4核8G的虚拟机或者云服务器,操作系统用CentOS 7.9或者Ubuntu 20.04 LTS都行。如果你是自己练手,电脑配置不够,用三台2核4G的也能跑起来,但也就是能“跑起来”,跑个稍微大点的任务内存就吃紧了。记住内存是Hadoop集群的命脉,YARN和HDFS都得吃内存,宁可CPU少两核,内存不要省。
版本选择我要单独强调一下。这里我用的是Apache Hadoop 3.3.x版本线,因为从3.x开始,很多机制有了质的改善,比如支持了基于容器的资源隔离、HDFS支持了纠删码。JDK方面,Hadoop 3.x必须搭配JDK 8及以上版本,推荐JDK 1.8(企业里用得最多、最稳)。我踩过一个大坑就是用了JDK 11跑Hadoop 3.2,结果部分组件启动报错,后来换回JDK 8就干净了。这种版本兼容性的问题,官方文档里其实有详细矩阵,但说实话不踩一遍你没有直观记忆。
2.2 JDK:最容易翻车的一环
所有节点先装JDK,这是脚本检测时的硬门槛。安装方式很朴素:下载JDK 8的tar压缩包,解压到统一目录,比如/usr/local/java,然后配置/etc/profile里的JAVA_HOME和PATH。这里我给你一个标准配置:
export JAVA_HOME=/usr/local/java/jdk1.8.0_202 export PATH=$PATH:$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar配置完执行source /etc/profile,再用java -version验证。注意,三台机器的JDK路径要完全一致,不然后面脚本分发配置的时候会产生很诡异的找不到Java的问题。这个“三台机器路径一致”的原则请划重点——不仅是JDK,后面Hadoop安装包的路径、数据目录的路径,我都强烈建议统一,能少排查很多问题。
2.3 网络、hosts与SSH基线配置
三台机器之间要走HDFS和YARN的数据传输,必须能通过主机名互相解析。最土但最有效的做法是直接编辑/etc/hosts,把三台机器的IP和主机名固写进去。比如:
192.168.1.10 master 192.168.1.11 worker01 192.168.1.12 worker02注意,hosts文件三台机器都要写一遍,而且内容一致。网上很多新手在这里踩坑,直接在Master上改了hosts,忘了Worker上也得有Master的映射,结果DataNode一直注册不上NameNode。
SSH免密登录是Hadoop启停脚本能一条命令拉起所有节点的前提。因为Master经常需要远程控制Worker节点,得先确认密钥能打通。生成密钥很简单,ssh-keygen -t rsa,然后疯狂回车就行;然后把公钥分发到所有节点的authorized_keys里。从Master节点分别ssh到worker01、worker02逐台验证一遍,不需要输入密码就说明通了。这段配置标准得不能再标准,脚本后续执行时的所有“说走就走”的远程操作都依赖这一步。
3. 实操现场:用Playground脚本5分钟拉起来一个集群
3.1 拿到脚本后需要改的配置项
当环境基线准备好以后,真正的重头戏就开始了。Playground脚本一般是以一个压缩包形式给你,里面主要是若干个Shell脚本,外加一个集群配置清单(通常是cluster.conf这样的文件),这个清单就是你和脚本交互的唯一窗口,也是你需要动手改配置的地方。
打开配置文件,核心是这几块信息:节点列表、节点角色、安装包路径、JDK路径。下面是一份我实际使用的配置修改示例:
# cluster.conf MASTER_NODE=master WORKER_NODES="worker01 worker02" HADOOP_HOME=/usr/local/hadoop JAVA_HOME=/usr/local/java/jdk1.8.0_202 HADOOP_VERSION=hadoop-3.3.6这里有一个很容易被忽略的细节:HADOOP_HOME这个路径,脚本会用来在每台节点上做软链接和目录初始化。如果你改乱了,脚本可能把安装包解压到了一个奇葩位置,导致后续起进程时找不到目录。所以我的建议是路径保持最传统的/usr/local/下,别玩花的,别加版本号子目录过深。
3.2 执行脚本,看每一步都发生了什么
配置改好之后,执行方式极其简单,通常就是类似./deploy.sh start这样一条命令。我第一次跑的时候,盯着滚动日志看了半天,这里我帮你翻译一下脚本大概干了哪些事:
第一阶段,做环境预检。脚本会逐台机器SSH过去检测Java版本、磁盘空间、hosts映射是否匹配。这个阶段如果检查不过会直接中断,并且告诉你哪台机器哪个环节挂了。这是脚本设计里我认为最人性的地方——错误尽量前置,不让你启动到一半才炸。
第二阶段,制作并分发安装包。脚本会在Master节点上用你指定的Hadoop版本重新生成或者定位一个标准压缩包,然后并行分发到两台Worker节点,再统一解压到HADOOP_HOME。这一步对网络有一定要求,如果三台机器之间网络带宽一般,稍微等一会儿很正常。
第三阶段,配置生成。脚本会根据cluster.conf里的角色关系,在每台节点上自动生成那四个核心配置文件:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml。比如说Master节点上的core-site.xml会设置fs.defaultFS为hdfs://master:9000,所有节点都会把NameNode地址指向Master;Worker节点上的hdfs-site.xml会设置自己的数据存放目录、副本数等参数。这套配置如果让你自己手写,至少半小时起步,而且容易漏掉一些参数。
第四阶段,格式化与启动。格式化只能做一次,脚本在检测到HDFS还没有被格式化的时候,会帮你执行一次hdfs namenode -format,然后依次在Master上面启动NameNode和ResourceManager,再到各个Worker节点上启动DataNode和NodeManager。到这一步,基本上集群就活了。
3.3 启动后必须做的验证清单
别看到“启动成功”四个字就撒欢,验证集群是否真的健康才是最关键的。我最常用的验证手段是四板斧:
第一斧,在所有节点上执行jps命令,看进程存不存在。按我们规划的角色,Master节点应该看到NameNode、SecondaryNameNode、ResourceManager这三个进程,Worker节点应该看到DataNode、NodeManager这两个进程。哪个缺失,哪个环节就有问题。
第二斧,访问HDFS的Web管理界面,默认端口是9870(注意Hadoop 2.x是50070,3.x改成了9870),浏览器打开http://master:9870,应该能看到NameNode的界面,并且在Datanodes标签页里看到你的两台Worker都活着。能看到节点状态为In Service、容量正常显示,说明HDFS这一层是通的。
第三斧,访问YARN的资源管理界面,默认端口是8088,打开http://master:8088,看到Active Nodes数量是2,说明YARN层节点注册成功。
第四斧,跑一个测试用例验证整个链路。最简单的是创建一个测试目录并上传一个文件:
hdfs dfs -mkdir -p /test hdfs dfs -put /etc/hosts /test/ hdfs dfs -cat /test/hosts能正常看到文件内容,说明HDFS读写链路通了。如果想进一步验证MapReduce任务执行,可以跑一个标准的单词统计例子:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /test /test-output任务跑完查看输出目录的结果,基本就可以盖棺定论:部署成功。
4. 常见问题与排查技巧实录
4.1 反复踩坑:SSH免密为什么会失效
我见过太多人SSH免密刚开始是通的,跑了两天突然又要求输密码了。常见原因是~/.ssh/authorized_keys的权限不对。SSH对公私钥文件的权限非常敏感:authorized_keys的权限必须是600,.ssh目录必须是700,如果你用root账号之间的免密,还要注意各节点root目录本身不能有异常权限。另一个原因是/etc/ssh/sshd_config里开了StrictModes yes严格模式,对权限检查更苛刻。遇到免密失效,优先查这两处。
4.2 NameNode启动不了或者连不上DataNode
NameNode启动失败最常见的原因是重复格式化。这里必须郑重提醒:如果你已经启动过集群,想重新格式化,光执行hdfs namenode -format是不够的,必须先把所有节点上HDFS数据目录里的内容手动清干净,否则NameNode的clusterID和DataNode的clusterID对不上,DataNode就会一直处于初始化失败、无法注册的状态。脚本在设计上一般会检测你是否已经在跑集群,但你自己手动去格式化时最容易踩这个坑。
还有一类情况是DataNode进程起来了,明明存在,但Web界面上就是显示连不上。优先排查防火墙:CentOS 7默认firewalld可能拦截了8020/9870等端口,还有云服务器安全组也别忘了放行端口。另外看看Master和Worker之间的hosts映射是否一致,不一致时DataNode会尝试往一个解析不了的地址上注册。
4.3 集群性能很差的排查方向
很多人部署完以后跑个测试,发现慢得像蜗牛,就质疑是不是部署方式有问题。先别急着下结论,按这个顺序排查:第一步看是不是没有配置mapred-site.xml里的MR框架为YARN,如果没配置,任务会走本地模式,根本起不了分布式计算;第二步看数据副本数,如果你的Worker节点根本没存下数据副本,任务就会跨网络拉数据,速度自然感人;第三步看看是不是内存分配过小,Hadoop 3.x默认的资源配置是保守的,如果小任务都卡顿,优先调大yarn.nodemanager.resource.memory-mb和yarn.scheduler.maximum-allocation-mb。
4.4 问题排查速查表
这里我把主力问题整理成一个速查表,建议你直接存一份到备忘录:
| 症状 | 可能原因 | 快速操作 |
|---|---|---|
| DataNode起不来/注册不上 | clusterID不一致、hosts不对、端口被防火墙拦截 | 清空数据目录重新格式化;检查hosts;放行端口 |
| ResourceManager界面看不到节点 | NodeManager内存不足 | 调大容器内存分配参数 |
| SSH仍要输密码 | 文件权限不对、known_hosts冲突 | 检查authorized_keys权限600、目录700 |
| HDFS上传文件卡住 | 副本数大于数据节点数 | 调小dfs.replication或确认节点数量够 |
| 跑MR任务一直是本地模式 | mapred-site.xml未配置 | 设置mapreduce.framework.name=yarn |
| Web界面打不开 | 访问端口不对 | Hadoop 3.x用9870,旧教程的50070已弃用 |
有一条排查原则我再多说一句:遇到集群问题,先看日志。Hadoop的日志目录通常在$HADOOP_HOME/logs/,里面有各种角色的log文件,报错信息大部分都写得比较清楚。网上很多人会上来就百度,其实日志里早写了答案。看日志这个习惯,你越早养成,后面排障效率越高。
4.5 心态和习惯:别让第一次成功变成负担
部署这件事,一次成功当然好,但我反而觉得第一次失败、再成功的过程更有价值。因为你在排查的过程中才会真正理解组件之间的依赖关系。脚本能帮你快速搭建环境,但它替代不了你排查问题的经验。我建议你第一次用脚本搭好后,故意干点“坏事”练手,比如手动改坏一个配置、手动停掉一个DataNode、手动清空一次数据目录再格式化,看看会发生什么,再观察日志和Web界面的变化。这种“破坏性实验”会让你对集群内部机制的印象非常深刻。
经验告诉我,真正能让你在集群故障时保持冷静的,不是背多少命令,而是知道数据在哪个目录、日志在哪个目录、每个角色用什么端口通信这一类最基础的信息。脚本帮你把“搭建重复环境”的时间压缩到了分钟级,省下来的时间就应该花在这种理解底层逻辑的训练上。这比多跑几个集群有意思得多,也实用得多。