没想好怎么开头的话,我用一句话说清楚:这一篇,解决的是“先把集群的地基打牢固”这件事,让你后续跑分布式任务时不被环境问题反复打断。
1. 项目概述与整体思路拆解
1.1 为什么坚持自己动手在Linux上搭Hadoop高性能集群
很多朋友上来就问:“直接用云服务商的一键集群不香吗?为什么非要自己掏钱买服务器、在Linux上一步步搭Hadoop集群?”
这个问题我做过几次对比,直接说结论:自己搭集群,最大的收益不是省几十块钱硬件费,而是对整个系统的掌控权。
举个具体的例子。我在本机搭过一套由4台虚拟机构成的实验集群,也在某云计算平台开过类似配置的托管集群。托管集群从创建到能跑,确实十分钟能完成,但后续一旦想要调整hdfs-site.xml里的副本系数,或者换一套YARN的资源调度策略,托管平台往往只开放少量自定义窗口,很多底层参数碰不到。对于纯开发测试或许无所谓,但真要往“高性能”方向调优,连内核层面的参数都碰不到,就无从谈优化。Linux上自己搭建,主机名、网络栈、磁盘挂载、内核参数、JVM堆大小全部暴露在我面前,哪里卡了直接查,调完可以立刻对比前后性能差异。这种“透明感”是托管集群给不了的。
另外,自己搭集群对理解分布式系统内部运作也有非常大的帮助。比如,NameNode格式化之后如果误删了dfs.namenode.name.dir目录会发生什么事情,这种问题的答案无法从管理控制台学会,只能在实际拆装中形成直觉。而有了直觉之后,再去用任何托管产品或科技公司内部的平台,都心中有底。这篇系列文章第一讲,就是先把规划和环境准备做到位。
1.2 高性能的底层逻辑:瓶颈不在单机CPU,而在数据流动效率
标题里写着“高性能”,很多新手对此有误解,以为高性能等于高配置,直接把每台机器拉满顶配就行。实际操作中,Hadoop的高性能更像是一套数据流动效率的工程:数据在磁盘、网络、内存之间搬运时是否顺畅,才是决定集群最终吞吐量的关键。
以HDFS写入为例,一份文件会被切分成若干个Block(默认128MB),每个Block产生两个副本,三个副本分别写到不同的DataNode。此时网络带宽、磁盘顺序写速度、副本放置策略、节点间的物理距离都会参与进来。如果网络交换机的背板带宽不够,或者NIC(网卡)中断没有绑定到特定CPU核心,哪怕CPU再强也无济于事,瓶颈稳稳地落在网络和IO侧。
所以我在搭建集群时,第一个思考永远是如何减少数据路径上不必要的等待。比如,DataNode的数据目录要放在多块独立磁盘上,而不是用RAID0合并成一个大分区,然后只挂一个目录。HDFS本来就有多目录机制,允许一个DataNode同时管理多个磁盘,与其让RAID层负责合并,不如在HDFS层做分布,后者既保留磁盘独立带宽,又便于单独更换损坏盘。再比如,内核参数中vm.swappiness要调小,尽量让内存不被交换到磁盘,NameNode的元数据驻留内存才能稳定支撑海量文件的响应。
如果把这部分抽象成一句话:高性能不是某一个环节的极致,而是各个环节之间冗余的消除。这也是系列文章第一讲先讲规划和系统基础的原因,参数调优的细节后续会逐层展开,但基础设计如果从一开始就偏离了,后面花再多精力都只是在补救,而非优化。
1.3 系列文章的技术路线规划
既然标题写了“(一)”,后续自然会有二、三、四等篇章。我先说一下整个系列的规划,方便你对号入座:
- 第一篇(本文):集群规划、环境准备、Linux基础调优、SSH免密、目录规划。
- 第二篇:HDFS核心组件安装与配置,重点讲NameNode、DataNode、SecondaryNameNode的部署细节及最终验证。
- 第三篇:YARN资源调度与MapReduce测试任务,重点是调度器选型、内存与CPU资源设置。
- 第四篇:性能压测、参数调优实践、常见故障恢复方案,这部分会侧重分析一些长期运行的案例。
这个顺序是按照依赖关系设计的,每篇都建立在前一篇的基础之上。本文作为开篇,会花较多篇幅讲规划原则,有些看着“不性感”,但请耐心对待,后续每一篇实操能顺利跑通,都和第一篇的基础扎实程度直接相关。
2. 从硬件到系统:搭建前的关键准备
2.1 硬件选型与资源估算方法
关于硬件配置,这里先说一个最常被问的问题:“大数据集群用什么配置合适?”这取决于你的目标数据量。以一个入门级但能真正称为“集群”的三节点配置为例,数据规模在数TB到数十TB级别,推荐配置参考如下表格:
| 角色 | CPU | 内存 | 磁盘方案 | 网络 |
|---|---|---|---|---|
| NameNode节点(1台) | 8核及以上 | 32GB及以上 | 系统盘SSD,元数据目录SSD(可独立) | 万兆内网 |
| DataNode节点(2台起步) | 8核及以上 | 32GB起步,与数据规模相关 | 4块以上机械盘 + 1块系统SSD | 万兆内网 |
| 辅助节点(可选,可复用NameNode) | 4核 | 16GB | 无明显要求 | 千兆/万兆 |
内存方面有一个比较实用的估算公式推荐给大家:HDFS中每个文件、目录、Block大概会占用NameNode堆内存150字节到500字节不等,取决于文件名的长度和副本系数。假设有1000万个文件(包括目录与Block计数),NameNode堆内存至少要预留4GB到8GB。JVM堆最大别超过物理内存的一半,否则操作系统没有足够页缓存来加速读取热数据。是不是听到这个数字有点发怵?实际工作中很多场景的文件数量也就百万级,32GB内存的NameNode完全够用。如果真到了数亿文件级别,可能会考虑引入联邦机制或者对象存储来分担压力,那就是另一套架构方案了。
磁盘配置上补充一点经验:HDFS的DataNode多目录机制是天然的高性价比方案,没必要在单节点内组硬件RAID0。硬件RAID0虽然提高了单盘逻辑卷带宽,但坏一块盘数据全丢,和HDFS的副本设计理念冲突。HDFS本身的三个副本已经保证了高可用,磁盘坏了让HDFS去重建副本,比依赖RAID更贴近分布式系统的设计哲学。另外,物理机上如果有条件,用独立SSD作为NameNode的dfs.namenode.name.dir存储目录,会让元数据操作延迟体验明显提升,这是一个很典型的“花小钱办大事”的配置。
2.2 操作系统发行版选型
操作系统的选择方面,业内比较主流的是两条路线:CentOS系(或其免费替代品)和Ubuntu Server系。两条路线都可以承载Hadoop集群,没有绝对的好坏,但需要考虑后续维护习惯。我自己接触较多的是CentOS系环境,系统稳定性好,很多大数据发行版默认针对RHEL/CentOS系做过打磨,生产环境里这类系统分布也广。教程也好、公司内部运维脚本也罢,通常默认适配这一派。如果你更熟悉Ubuntu,用来搭建也没有问题,只是要留意个别文件路径和网络配置命令略有区别。
这里涉及一个需要提前说明的点:下载Hadoop发行版时,官方包名里有针对不同CPU架构的编译版本,如果你用的是比较新的ARM服务器,需要确认下载的是对应的aarch64版本,而不是通用的x86_64版本,否则后续启动HDFS时会出现比较基础级别的错误。这类问题不复杂,却特别容易让人开局就被困住。另外,系统时间同步需要配置chrony或ntp服务。分布式系统集群内时间不同步,后续Kerberos认证、日志时间戳比对都会出乱子。对纯测试环境来说也许影响不大,但既然目标是高性能集群,从第一天就统一时间同步是低成本高收益的做法。
系统安装完成后,我通常会在每个节点上统一创建一个专用的运行用户,比如取名hadoop,而不是直接使用root跑所有服务。单独用户管理的好处有两点:一是避免HDFS误操作删除系统关键目录,因为Hadoop命令在文件系统层面非常“强势”;二是后续部署日志或服务托管时,权限边界清晰,排查问题更省心。有朋友带着测试的心态一直用root操作,短期似乎没出问题,但等到多租户共用环境时就会意识到权限隔离的缺失有多么难受。
2.3 JDK版本选型与安装:最容易翻车的环节
Hadoop本身是用Java开发的开源项目,所以JDK环境直接关系到整个集群能否稳定启动。这里先强调一个最核心的经验:一定不要使用过于新的JDK主版本。Hadoop 3.x系列官方文档中明确推荐JDK 8或JDK 11,在实际踩坑经历中,JDK 8的兼容性最稳,JDK 11在个别Hadoop小版本上可能有兼容性问题,但整体可用。如果你直接上了JDK 17甚至21,某些依赖库会因为模块化封装问题抛异常,排查起来特别费时间。所以选型可以直接锁定OpenJDK 1.8,虽然没有特别新潮,但作为Hadoop的“老搭档”最让人放心。
安装JDK时,用系统包管理器安装最常见。以CentOS系环境为例,执行yum install java-1.8.0-openjdk-devel或在Ubuntu上执行apt install openjdk-8-jdk即可。但有一点需要注意,系统默认Java路径在不同发行版之间并不一样。为了后续配置环境变量方便,我习惯先用update-alternatives查看当前Java真实安装路径,然后固定写到/etc/profile.d/hadoop.sh中,而不是污染全局profile文件。这个文件里除了Java,还可以把后续要用的Hadoop环境变量一并写好,内容大概是:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk export HADOOP_HOME=/opt/hadoop export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin写入之后执行source /etc/profile.d/hadoop.sh,再执行java -version确认版本正确即可。这个步骤虽然简单,但有一个常见的坑是:不同节点安装了不同版本的JDK,导致某些节点启动正常、某些节点报莫名其妙的UnsupportedClassVersionError,这类问题一旦集群规模超过三个节点,排查起来会非常痛苦。最好的习惯是在同一批节点安装完全一致的JDK版本,安装完成后每个节点同步校验一次,不要想当然地跳过检查。
3. 集群网络规划与SSH免密登录配置
3.1 主机规划与/etc/hosts映射
集群里各节点之间需要互相通信,这意味着网络规划要清晰。如果再细分一下,内网传输可以分为存储数据访问和任务调度通信两类:HDFS写入与读取Block副本走的是存储数据通道,YARN在申请容器、传输Shuffle数据时走的是任务调度通道。如果机器数量较少(少于10台),可以使用一张内网网卡同时承担两类流量;如果机器数量和规模上来,就需要考虑分离管理网络和数据网络了。本系列面向的是中小型入门集群,所以我推荐方案是:所有节点接入同一台千兆或万兆交换机,用静态IP配好内网地址,保持节点之间延迟尽可能低。
主机名规划我建议遵循“角色与序号结合”的原则,比如node1负责NameNode和ResourceManager,node2和node3则担任DataNode和NodeManager。主机名建议不要一上来就叫namenode或datanode,因为角色职责可能会发生调整,比如后期把node2提升为新的NameNode,如果主机名早就定义成“datanode”,后续修改涉及面会很大,比较别扭。主机名规划实例如下:
| 节点 | 内网IP(示例) | 主机名 | 初始角色 |
|---|---|---|---|
| 节点A | 192.168.10.11 | node1 | NameNode + ResourceManager |
| 节点B | 192.168.10.12 | node2 | DataNode + NodeManager |
| 节点C | 192.168.10.13 | node3 | DataNode + NodeManager |
每台机器的/etc/hostname文件写入对应的主机名,然后修改/etc/hosts,把三台机器的IP和主机名对应关系统一写入。这里有个细节容易被忽略:主机名解析不要依赖DNS,而是使用/etc/hosts。原因很简单——避免因为DNS服务故障导致集群各节点之间偶发性通信超时。DNS域名解析在分布式环境里每时每刻都会被调用,一旦出现抖动,表面上看起来就是节点间连接超时或心跳丢失,极其难以排查。
3.2 SSH免密登录的心得与常见坑
Hadoop集群各大守护进程之间需要互相通信,最直接的方式就是通过SSH免密登录来启动或停止服务,比如在主节点上执行start-dfs.sh时,脚本需要远程SSH到各个DataNode上拉起对应进程。配置SSH免密的过程并不繁琐:在每个节点生成密钥对,然后把公钥分发到所有节点的authorized_keys中。实际操作时我习惯在node1上生成密钥对,然后使用ssh-copy-id把公钥分发到所有节点(包括node1自己),再从node1依次尝试SSH连接node1、node2、node3,确保第一次连接后不再提示输入密码。
关于SSH免密配置,有几个实践细节值得单独拿出来讲。第一,authorized_keys文件权限必须为600,.ssh目录权限为700,否则SSH服务端出于安全策略会直接忽略该文件,表现就是明明已经ssh-copy-id成功,但连接时仍然要求输入密码。绝大多数SSH免密失败的案例,最后都能归因到权限问题上。可以先执行chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys,再重试。第二,如果生成密钥时设置了passphrase(口令短语),后续自动启动脚本时会卡在口令输入上,所以在线环境里不要设置口令。第三,建议直接用ssh node2验证连接,而不是只验证ssh 192.168.10.12。因为Hadoop主机名解析走的是/etc/hosts,如果你的配置里定义的是主机名映射,但实际测试一直依赖IP,容易掩盖主机名解析层面的问题。
4. 集群角色划分与目录规划
4.1 角色分配的经典思路
Hadoop集群的角色可以通俗地理解为分布式系统的各类“工种”。NameNode是HDFS的“总管家”,维护整个文件系统的目录树和Block位置信息,所有文件的增删改查都要经过它的元数据确认。DataNode是“仓管员”,实际存储Block数据并定期向NameNode汇报自身状态。ResourceManager和NodeManager则负责YARN层的资源调度,一个负责全局资源分配,一个负责单节点资源供给。小规模集群最经典的角色分配方式是把NameNode和ResourceManager放在同一台机器上,这样既节省了一台机器的资源,也方便统一管理“大脑类”的服务。而SecondaryNameNode并不是NameNode的“热备”,它主要承担定期合并元数据镜像和编辑日志的工作,缓解NameNode自身的压力。生产环境如果条件允许,建议让SecondaryNameNode跑在另一台独立的机器上,不要和NameNode同居一台物理机,否则一旦物理机故障,两份检查点机制同时失效。
规模再大一些的集群,可以考虑让ResourceManager与NameNode分离部署,因为在大规模并行任务提交时,ResourceManager的CPU、内存以及网络开销非常可观,混布会影响NameNode的响应延迟。对于本文设想的3节点入门集群,还是先把二者放一起,等到完成第三篇的YARN配置后,再对规模扩展的替代方案做详细说明。
4.2 数据目录与日志目录的规划细节
安装Hadoop时会涉及几类关键目录,它们的规划直接影响了后续维护和性能。我的建议是把它拆成四类:
- Hadoop安装目录:存放Hadoop发行版解压后的二进制文件和库文件,通常放在
/opt/hadoop。建议解压后使用软链或直接统一路径,方便后续写配置脚本时保持路径一致。 - NameNode元数据目录:由
dfs.namenode.name.dir指定。这个目录保存着整个HDFS文件系统的镜像(fsimage)和编辑日志(edits)。生产环境建议配置两个不同磁盘路径,比如一块SSD和一块机械盘,HDFS会同时向两个位置写入,增加一层冗余。有些团队把两个路径放在同一块物理盘的不同分区上,这其实没有意义,起不到硬件级保护作用。 - DataNode数据目录:由
dfs.datanode.data.dir指定。多条路径用逗号分隔,每个路径对应一块独立的物理磁盘。这里要特别注意:如果服务器上有4块数据盘,不要用RAID合并成一个大逻辑卷后再只配置一个目录。正确做法是每块盘独立挂载,然后在配置中配置4个目录,例如/dfs/d1,/dfs/d2,/dfs/d3,/dfs/d4。HDFS写入时会在多个目录间轮流选择,充分用上每块盘的带宽。 - 日志目录:由
HADOOP_LOG_DIR指定。各个守护进程的运行日志会存放在这里。日志目录建议规划到单独的路径,比如/data/log/hadoop,避免后续排查问题时在系统盘里翻找半天。其实很多新手遇到集群启动失败时,第一反应是到处问“该怎么办”,但正确顺序是先到日志目录去看,大多数问题在日志里都写得明明白白。
规划完成后,还有一个经常被忽略的步骤:确保相关目录的所有者和属组是之前创建的hadoop用户,并且权限满足写需求。执行命令时经常遇到类似“Permission denied”的报错,排查到最后发现是目录权限不对,只挂载了却没有chown。在批量节点上配置目录时,最好写一个小循环在每一台机器上执行,纯手工一台台敲命令容易遗漏,产生“有的节点目录权限对、有的不对”的混乱状态。
5. Linux内核参数与Hadoop基础配置
5.1 内核参数与文件描述符调整
Linux系统作为Hadoop的底层承载环境,默认参数往往是面向通用桌面或小型服务设计的,并不适合大规模分布式计算场景。以文件描述符为例,NameNode每次处理客户端请求和DataNode汇报都会占用文件句柄,默认的1024上限很容易被迅速耗尽。所以务必在/etc/security/limits.conf中提高上限,把nofile和nproc都调大。典型配置如下:
hadoop soft nofile 65535 hadoop hard nofile 65535 hadoop soft nproc 65535 hadoop hard nproc 65535同时还需要确认/etc/sysctl.conf中的fs.file-max参数也足够大,这个参数控制的是整个操作系统层面的文件句柄总量。修改后执行sysctl -p让配置生效,并在每个节点上执行ulimit -n验证结果。我见过不少案例是配置了limits.conf,但使用的SSH会话是之前已经打开的,旧会话不会自动加载新限制,重启会话才看到效果。
网络层面的参数也值得提前调优。Hadoop节点之间在传输数据时会建立大量的TCP连接,默认的TCP读写缓冲区偏小会导致吞吐量上不去。建议在/etc/sysctl.conf中调整:
net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216vm.swappiness要调低,一般建议设为1到10之间。这个参数控制操作系统在内存紧张时倾向于交换内存页的程度。Hadoop的守护进程需要低延迟地访问内存,如果系统频繁把页面换出到磁盘,整个集群的响应速度会明显恶化。我习惯设为1,既保留了轻微交换能力,又避免内存页面在闲置时被过早地写入交换分区。
磁盘I/O调度器对分布式存储的底层表现也有明显影响。机械硬盘场景下,HDFS主要执行顺序读写和部分随机写操作,采用deadline调度器能平衡延迟和吞吐量,避免某些I/O请求长时间没有机会被处理。SSD场景则可以直接采用none调度器,因为SSD不需要复杂的寻道优化,调度层反而会引入额外开销。如果你的系统盘和数据盘类型不同,务必分开设置磁盘调度器,而不是一刀切地把所有设备设置成同一个调度器。检查与修改方式:
cat /sys/block/sda/queue/scheduler echo deadline > /sys/block/sda/queue/scheduler这种修改重启后会还原,想永久生效需要借助udev规则或系统级配置,各家发行版方法略有不同,可以按实际系统查阅后再设置。
5.2 Hadoop基础配置文件的初步设计
Hadoop的配置文件集中在$HADOOP_HOME/etc/hadoop目录下。系列第一篇里不需要把所有参数全部调完,但有几个核心配置文件需要提前打好底子。
core-site.xml中需要配置默认文件系统,核心内容是指向NameNode的地址。以规划中的三节点为例,核心配置如下:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://node1:9820</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop/tmp</value> </property> </configuration>hadoop.tmp.dir这个参数有一个坑:如果不显式指定,系统默认会用/tmp/hadoop-${user.name}。系统/tmp目录在重启时可能被清理,一旦NameNode的元数据因为tmp被清理而不见,整个集群等于“失忆”了。一定要把hadoop.tmp.dir指向持久化存储目录。
hdfs-site.xml中需要设置NameNode元数据持久化路径和DataNode数据目录,同时需要设定副本数。三节点集群副本数设为2还是3,取决于目标可靠性要求。如果只有三台节点,设为3意味着每一份数据都占满所有节点,虽然最安全,但可用空间只相当于一块磁盘。实际生产环境通常使用三副本,但若只是做学习和性能验证,先设2能节省不少空间。补充一个隐藏的细节:副本数也不是越高越好,因为每次写入都需要等待所有副本确认成功才返回客户端,副本越多,写延迟越高。这是性能与可靠性之间的经典权衡。
yarn-site.xml则涉及YARN资源管理的初步配置,要把ResourceManager地址指定到node1,并启用节点管理器执行Shuffle辅助服务:
<property> <name>yarn.resourcemanager.hostname</name> <value>node1</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>同时,每台NodeManager能分配给YARN的最大内存和CPU核数也需要按实际配置设置,具体参数在第一篇中先明确思路,后一篇YARN专题会给出详细的计算方式和策略。
6. 踩坑实录:环境准备阶段的高频故障
6.1 SSH免密配置反复失效
SSH免密登录是搭建过程中第一个高频出问题的环节。症状是明明已经把公钥拷贝到目标节点的authorized_keys文件里了,但登录依然要求输入密码,而且查看/var/log/secure之类的系统日志,又没有明显的报错信息。这种问题有相当大概率是文件权限出错,~/.ssh或~/.ssh/authorized_keys的权限过于宽松,SSH服务端出于安全机制拒绝信任该文件。处理方法并不复杂:在目标节点上执行chmod 700 ~/.ssh和chmod 600 ~/.ssh/authorized_keys,然后换个新会话测试。如果还不行,可以到/etc/ssh/sshd_config里确认没有开启StrictModes yes叠加限制,但在系统默认情况下,一般保持默认即可。每次测通之后,记得用ssh node2这种方式来测试,而不要只测IP,因为两者走的主机名解析路径不一致,前者更能模拟Hadoop真正的通信方式。
6.2 JDK版本不一致导致节点启动失败
集群所有节点如果使用了不同版本或不同发行版来源的JDK,表面上不会有任何提示,直到启动HDFS时才发现部分节点甚至启动失败,或者虽然启动成功,但持续抛出各类Java异常。这个问题在干净的测试环境下往往不会出现,但一旦纳入公司统一镜像或批量初始化的机器列表,不同批次机器的JDK很容易出现差异。我经历过的比较典型的情况是node1装的是OpenJDK 1.8.0_292,而node2装的是OpenJDK 11,最终HDFS服务在node2上陷入启动后反复崩溃的循环。排查手段是先在所有节点依次执行java -version,并把输出结果统一比对,确认版本字段完全一致后再进行下一步。也可以写一个简单的shell循环批量检查输出,不用一台台手动登录。
6.3 NameNode格式化之后无法启动
我在实验室环境里见过多次这样的问题:安装完成后执行了hdfs namenode -format,然后启动start-dfs.sh,随后检查JPS进程,发现DataNode节点正常出现,但NameNode进程不存在,查看日志时出现“java.io.IOException: NameNode is not formatted”之类的信息。这个问题的常见原因之一是企业环境里配置的dfs.namenode.name.dir路径下之前已经存在过旧的元数据,即使已经格式化过,目录下残留文件仍可能造成名字冲突。更稳妥的做法是:在第一次格式化前,彻底清理dfs.namenode.name.dir和dfs.datanode.data.dir指定目录下的所有内容,再把目录权限交给hadoop用户,然后执行格式化。特别提醒一句:格式化会造成元数据丢失,这是一条不可逆的操作。如果集群已经含有业务数据,请勿轻易执行格式化。同时,HDFS设计上是不支持“再次格式化后无缝恢复旧数据”的,一旦对已有数据的集群执行了格式化,原有文件的Block信息和目录树都会被清空。
6.4 磁盘满导致节点目录拒写
DataNode数据目录空间不足时,表面上进程还活着,但数据块写入会持续报“磁盘空间不足”的异常。比较危险的是,系统不会特别显眼地通知你,只有查看NameNode日志或系统df命令才能发现。在规划集群时,要给每个磁盘预留一定比例的缓冲空间,不要把存储利用率推到接近100%。HDFS本身也有dfs.datanode.du.reserved参数,用于为磁盘非HDFS文件预留空间,建议在一开始就把这个参数设置为不小于20GB。别等到线上数据持续增长后才发现磁盘规划失误,那会让你面临“扩容”和“重建”之间的艰难取舍。
7. 用一个小案例验证集群连通性
在开始后续的HDFS和YARN组件安装之前,可以先做一次集群连通性验证。流程很简单:在node1上逐个执行ssh node1、ssh node2、ssh node3,验证均无需密码即可登录;然后执行ping node2,观察延迟是否正常且稳定。之后,在node1上创建一段测试文件,并通过SCP复制到node2和node3上,比如:
echo "cluster connectivity test" > /tmp/test.txt scp /tmp/test.txt node2:/tmp/ scp /tmp/test.txt node3:/tmp/如果能无密码完成整个操作,说明网络和SSH链路已经打通。这个测试虽然简单,但已经覆盖了后续所有Hadoop启停脚本所需的核心通道。如果在这里折腾了很久,也请不要气馁,很多初学用户在这一步花费的时间甚至比安装Hadoop本身还多,根源多半还是在权限或主机名解析这些细节点上。
验证通过后,可以在每个节点上执行date -R确认系统时间一致。时间同步问题初期不显眼,等到后文配置Kerberos、启用安全认证时,时间不同步会成为致命伤。宁可现在多在细节上花一些时间,也不要让后续的报错和排查耗尽耐心。集群搭建这件事,本质上就是把一个一个细节校准到位的过程。
我个人也经历过那种满心期待准备启动集群,却因为某个节点配置不一致而反复折腾的夜晚。当时最深的体会是:与其每次凭印象去改配置,不如从一开始就在每个节点上记录配置清单。我在节点上习惯维护一份简单文档,记录当前节点的IP、主机名、JDK版本、磁盘挂载路径、Hadoop相关目录的属主等信息。节点少时这看似多余,一旦节点数量增长,这份文档就能在排查问题时提供非常关键的参照。下一篇文章里,会正式进入HDFS核心组件的安装与配置,并完成NameNode格式化与集群启动验证。