三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

从零搭建Hadoop 3.3.6集群:超详细步骤与核心配置解析

从零搭建Hadoop 3.3.6集群:超详细步骤与核心配置解析

1. 项目概述与核心价值

最近几年,大数据这个词的热度虽然有所回落,但数据驱动的决策和分析已经渗透到各行各业,成为基础设施的一部分。无论是电商平台的推荐系统、金融领域的风控模型,还是物联网设备的日志分析,背后往往都离不开一个稳定、可扩展的数据处理平台。而Hadoop,作为大数据生态的基石,其核心的分布式存储(HDFS)和分布式计算(MapReduce/YARN)思想,至今仍是许多企业数据仓库和数据处理流水线的首选方案。

很多人觉得现在云服务发达,直接购买EMR、Dataproc这类托管服务就行了,为什么还要自己动手搭集群?我的体会是,亲手从零搭建一个Hadoop集群,就像学开车不能只学自动挡一样。这个过程能让你彻底搞明白各个组件(NameNode, DataNode, ResourceManager, NodeManager)之间是怎么通信的,配置文件里每一个参数到底影响了什么,以及当集群出问题时,应该从哪个环节开始排查。这对于后续的运维、性能调优乃至架构设计,都是无可替代的经验。网上教程很多,但要么过于简略跳过了关键坑点,要么环境差异太大导致无法复现。我这次分享的,是我在多次生产环境和实验环境搭建后,总结出的一套全面且超详细的流程,目标是让你跟着做一遍,就能得到一个真正可用的、理解其运作原理的Hadoop集群。

2. 前期规划与系统准备

搭建一个集群,最忌讳的就是拿到机器就开始敲命令。前期的规划直接决定了后续的稳定性和可维护性。我们需要在纸上(或文档里)先明确几件事。

2.1 集群架构设计

一个典型的Hadoop集群主要由两类节点组成:管理节点(Master Nodes)和工作节点(Worker Nodes)。对于学习和中小规模场景,我推荐以下最小化架构:

  • 主节点 (Master Node-1):承担核心管理职责。建议配置稍高(如4核8G内存)。它上面将运行:
    • NameNode (NN):HDFS的“目录管理器”,负责管理文件系统的命名空间(目录树结构)和客户端对文件的访问。它是单点,至关重要。
    • ResourceManager (RM):YARN的“资源调度器”,负责整个集群的资源(CPU、内存)管理和分配。
  • 备用主节点/从节点 (Master/Worker Node-2):在伪分布式或小集群中,它可以同时作为备用管理节点和工作者。建议配置与主节点一致或稍低。它上面将运行:
    • SecondaryNameNode (SNN):注意,它不是NameNode的热备!它的主要工作是定期合并NameNode的编辑日志(Edits Log)到镜像文件(FsImage),减少NameNode启动时间,并在NameNode失效时提供元数据备份。
    • DataNode (DN):HDFS的数据存储单元,真正存放数据块的地方。
    • NodeManager (NM):YARN在每个节点上的“代理”,负责启动和管理容器(Container)来执行具体的计算任务。
  • 工作节点 (Worker Node-3, Node-4...):纯工作节点,配置可侧重于磁盘和内存。运行DataNode和NodeManager。

对于本次详细搭建,我们将使用3台虚拟机来模拟一个具有高可用雏形的集群:1台主节点(Master),2台工作节点(Slave1, Slave2)。这样既能理解分布式协作,又不会因机器过多而复杂化。

2.2 系统与环境要求

操作系统:选择CentOS 7.x 或 Ubuntu 20.04 LTS等稳定的Linux发行版。我习惯用CentOS 7.9,社区资料丰富。确保系统干净,最好是最小化安装。

机器配置:

  • Master:建议2核CPU,4GB内存,20GB磁盘。
  • Slave:建议1-2核CPU,2-4GB内存,磁盘尽可能大(如30GB+,因为DataNode存数据)。

软件版本:

  • Java:Hadoop是Java写的,必须安装JDK。Hadoop 3.x 需要 JDK 8 或更高版本。我们选择JDK 8u381,这是一个长期支持的稳定版本。
  • Hadoop:我们选择Hadoop 3.3.6,这是目前(截至我知识截止日期)的稳定版本。避免使用过新的版本,以免遇到未知Bug。

网络规划:

  1. 固定IP:为三台虚拟机设置静态IP地址,例如:Master: 192.168.10.10,Slave1: 192.168.10.11,Slave2: 192.168.10.12
  2. 主机名映射:在每台机器的/etc/hosts文件中,添加所有节点的IP和主机名映射。这是集群内部通信的基础。
  3. 防火墙与SELinux:在实验环境,可以先关闭防火墙和SELinux以排除网络干扰。生产环境则需要精细配置规则。
    # 关闭防火墙 (CentOS 7) systemctl stop firewalld systemctl disable firewalld # 关闭SELinux (需重启生效,或临时setenforce 0) sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 建议重启 reboot

2.3 基础环境搭建实操

假设你现在有三台刚安装好的CentOS 7虚拟机,主机名分别为master, slave1, slave2。

第一步:配置静态IP和主机名(每台机器)编辑网络配置文件(CentOS 7是/etc/sysconfig/network-scripts/ifcfg-ens33,Ubuntu是/etc/netplan/*.yaml),设置静态IP、网关、DNS。然后修改/etc/hostname文件为永久主机名(如master)。

第二步:配置主机映射(每台机器)编辑/etc/hosts,加入以下内容:

192.168.10.10 master 192.168.10.11 slave1 192.168.10.12 slave2

完成后,互相ping一下主机名(如ping slave1),确保能解析并通迅。

第三步:创建专用用户(每台机器)不建议直接使用root运行Hadoop。我们创建一个hadoop用户。

useradd hadoop passwd hadoop # 设置密码,例如 hadoop

为了方便,我们将hadoop用户加入sudoers,并配置SSH免密登录。

第四步:配置SSH免密登录(关键步骤)集群管理需要主节点能无密码登录到所有节点(包括自己)。在master节点上操作:

su - hadoop # 切换到hadoop用户 ssh-keygen -t rsa # 一路回车生成密钥对 ssh-copy-id master # 将公钥拷贝到自己 ssh-copy-id slave1 # 拷贝到slave1 ssh-copy-id slave2 # 拷贝到slave2

执行后,尝试ssh slave1,应该可以直接登录,无需密码。

第五步:安装JDK(每台机器)/opt目录下创建softwaremodule目录,分别存放安装包和解压后的软件。

# 以root身份操作 mkdir -p /opt/software /opt/module chown -R hadoop:hadoop /opt/software /opt/module

将下载好的jdk-8u381-linux-x64.tar.gz上传到master节点的/opt/software。 在master上解压并配置环境变量:

su - hadoop tar -zxvf /opt/software/jdk-8u381-linux-x64.tar.gz -C /opt/module/

编辑~/.bashrc文件,添加:

export JAVA_HOME=/opt/module/jdk1.8.0_381 export PATH=$PATH:$JAVA_HOME/bin

使环境变量生效:source ~/.bashrc。检查安装:java -version将配置好的JDK目录和环境变量配置同步到slave1和slave2。你可以用scp命令拷贝/opt/module/jdk1.8.0_381目录和.bashrc文件,或者在从节点上重复安装步骤。

注意:环境变量配置是新手常踩的坑。一定要确保JAVA_HOME的路径是绝对路径,并且没有多余的空格或换行。可以用echo $JAVA_HOME命令来检查。

3. Hadoop安装与核心配置详解

基础环境就绪后,我们进入Hadoop本身的安装与配置环节。这是整个搭建过程的核心,配置文件的理解程度决定了你对集群的掌控力。

3.1 Hadoop软件包分发与解压

将下载的hadoop-3.3.6.tar.gz上传到master节点的/opt/software目录。 在master上解压:

tar -zxvf /opt/software/hadoop-3.3.6.tar.gz -C /opt/module/

为了方便,可以重命名并配置环境变量:

cd /opt/module mv hadoop-3.3.6/ hadoop # 编辑 ~/.bashrc,在JDK配置后面追加 export HADOOP_HOME=/opt/module/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

使环境变量生效:source ~/.bashrc。检查:hadoop version

现在,将master上配置好的整个/opt/module/hadoop目录同步到两个从节点:

scp -r /opt/module/hadoop slave1:/opt/module/ scp -r /opt/module/hadoop slave2:/opt/module/

同样,也需要将masterhadoop用户的.bashrc文件同步过去,或者手动在从节点上添加HADOOP_HOME环境变量。

3.2 Hadoop配置文件深度解析

Hadoop的配置文件位于$HADOOP_HOME/etc/hadoop/目录下。我们需要修改以下几个核心文件。所有操作在master节点的hadoop用户下进行。

1.core-site.xml- 核心全局配置这个文件定义了Hadoop最基础的属性,最重要的是指定HDFS的访问地址(NameNode的位置)。

<configuration> <!-- 指定HDFS中NameNode的地址(协议、主机名、端口) --> <property> <name>fs.defaultFS</name> <value>hdfs://master:9000</value> </property> <!-- 指定Hadoop运行时产生文件的存储目录,如日志、临时文件等 --> <property> <name>hadoop.tmp.dir</name> <value>/opt/module/hadoop/data/tmp</value> </property> </configuration>
  • fs.defaultFS: 这是客户端连接HDFS的默认入口。hdfs://是协议,master是我们配置的主机名,9000是NameNode默认的RPC端口。
  • hadoop.tmp.dir: 非常重要!很多组件(如DataNode)的存储基础路径会基于此目录派生。务必确保该目录存在且hadoop用户有读写权限。我们将它放在Hadoop安装目录下,便于管理。

2.hdfs-site.xml- HDFS相关配置这个文件专门配置HDFS相关的参数。

<configuration> <!-- 指定HDFS副本的数量,默认是3。我们只有3个节点,设为2或3均可 --> <property> <name>dfs.replication</name> <value>2</value> </property> <!-- SecondaryNameNode的HTTP服务器地址和端口 --> <property> <name>dfs.namenode.secondary.http-address</name> <value>slave1:9868</value> </property> <!-- NameNode本地存储元数据的目录(路径需要提前创建) --> <property> <name>dfs.namenode.name.dir</name> <value>file://${hadoop.tmp.dir}/dfs/name</value> </property> <!-- DataNode本地存储数据块的目录(路径需要提前创建) --> <property> <name>dfs.datanode.data.dir</name> <value>file://${hadoop.tmp.dir}/dfs/data</value> </property> </configuration>
  • dfs.replication: 数据块的副本数。这是HDFS可靠性的关键。在生产环境,通常设为3。我们集群只有3个节点,设为2可以在可靠性和存储开销间取得平衡。
  • dfs.namenode.secondary.http-address: 指定SecondaryNameNode运行在哪台机器。我们让它运行在slave1上。
  • dfs.namenode.name.dirdfs.datanode.data.dir: 这里使用了${hadoop.tmp.dir}变量,它们最终会指向/opt/module/hadoop/data/tmp/dfs/name/opt/module/hadoop/data/tmp/dfs/data务必在每台节点上手动创建这些目录

3.yarn-site.xml- YARN资源调度配置这个文件配置YARN框架。

<configuration> <!-- 指定ResourceManager的主机名 --> <property> <name>yarn.resourcemanager.hostname</name> <value>master</value> </property> <!-- NodeManager上运行的附属服务。需配置为mapreduce_shuffle,MapReduce才能运行 --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 是否启用日志聚合(将Container日志收集到HDFS),建议开启 --> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <!-- 日志在HDFS上保留的时间(秒),7天 --> <property> <name>yarn.log-aggregation.retain-seconds</name> <value>604800</value> </property> </configuration>
  • yarn.resourcemanager.hostname: 明确告诉集群ResourceManager在哪里。
  • yarn.nodemanager.aux-services: 这是关键配置。MapReduce任务在YARN上运行时,需要Shuffle(洗牌)阶段,这个服务就是处理这个的。不配置或配错,MapReduce作业会失败。

4.mapred-site.xml- MapReduce应用配置这个文件告诉Hadoop,MapReduce程序应该运行在YARN框架上。

<configuration> <!-- 指定MapReduce作业运行在YARN上 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <!-- MapReduce作业历史服务器地址 --> <property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property> <!-- MapReduce作业历史服务器Web UI地址 --> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>master:19888</value> </property> </configuration>

在Hadoop 3中,这个文件可能默认不存在,需要从模板复制:cp mapred-site.xml.template mapred-site.xml

5.workers- 指定DataNode和NodeManager节点这个文件(旧版本叫slaves)列出了所有工作节点的主机名。编辑它:

slave1 slave2

注意:文件里不要有空格、空行或localhost。每行一个主机名。

3.3 配置文件分发与目录创建

master上配置完所有文件后,需要将它们同步到所有从节点:

cd $HADOOP_HOME/etc scp -r hadoop/ slave1:$HADOOP_HOME/etc/ scp -r hadoop/ slave2:$HADOOP_HOME/etc/

然后,在每台机器上(master, slave1, slave2),以hadoop用户身份创建必要的目录:

mkdir -p $HADOOP_HOME/data/tmp/dfs/name mkdir -p $HADOOP_HOME/data/tmp/dfs/data # 检查目录权限 chmod -R 755 $HADOOP_HOME/data

4. 集群启动、验证与基础操作

配置全部完成后,激动人心的启动时刻到了。Hadoop的启动有严格的顺序。

4.1 格式化HDFS与启动集群

第一步:格式化NameNode(仅在第一次启动前,在master执行一次!)

hdfs namenode -format

这个命令会初始化NameNode的元数据存储目录(就是我们之前配置的dfs.namenode.name.dir)。如果看到“successfully formatted”或类似提示,并且目录下生成了current文件夹,说明成功。

警告:格式化操作会清空所有HDFS数据!只能在首次搭建或决定彻底重置集群时使用。重复格式化会导致DataNode的存储ID与NameNode不匹配,导致DataNode无法注册。

第二步:启动HDFS(在master执行)

start-dfs.sh

这个脚本会读取workers文件,依次登录到slave1slave2启动DataNode,并在master启动NameNode,在slave1启动SecondaryNameNode。 用jps命令在每台机器上检查进程:

  • master:应有NameNodeDataNode(如果master也在workers列表中)。
  • slave1:应有DataNode,NodeManager(如果启动了YARN),以及SecondaryNameNode
  • slave2:应有DataNode

第三步:启动YARN(在master执行)

start-yarn.sh

这个脚本会在master启动ResourceManager,并根据workers文件在所有节点启动NodeManager。 再次用jps检查:

  • master:新增ResourceManager
  • slave1/slave2:新增NodeManager

第四步(可选):启动历史日志服务器(在master执行)

mapred --daemon start historyserver

jps检查master上应有JobHistoryServer。这方便我们查看已完成的MapReduce作业日志。

4.2 集群健康状态验证

启动后,如何确认集群是健康的?

1. 通过Web UI查看:

  • HDFS NameNode UI:http://master:9870(Hadoop 3.x端口是9870,2.x是50070)。在这里可以看到集群概况、DataNode存活情况、存储空间使用率等。
  • YARN ResourceManager UI:http://master:8088。在这里可以提交作业、查看集群资源使用、监控运行中的应用。

打开浏览器,输入上述地址。如果能正常访问,并看到Live Nodes数量为2(或3,如果master也作为DataNode),说明HDFS启动正常。在8088端口看到所有NodeManager都连接上,说明YARN正常。

2. 通过命令行验证:master上执行:

hdfs dfsadmin -report

这个命令会打印出详细的HDFS集群报告,包括每个DataNode的状态、容量、使用情况。检查是否有Dead节点。

yarn node -list

这个命令会列出所有向ResourceManager注册的NodeManager节点及其状态。

4.3 HDFS基础文件操作

现在,让我们像使用本地文件系统一样使用HDFS。

# 1. 在HDFS上创建一个目录 hdfs dfs -mkdir -p /user/hadoop/input # 2. 将本地文件上传到HDFS # 假设本地有一个测试文件 test.txt echo "Hello Hadoop World" > test.txt hdfs dfs -put test.txt /user/hadoop/input/ # 3. 列出HDFS目录内容 hdfs dfs -ls /user/hadoop/input # 4. 查看HDFS文件内容 hdfs dfs -cat /user/hadoop/input/test.txt # 5. 从HDFS下载文件到本地 hdfs dfs -get /user/hadoop/input/test.txt ./test_download.txt # 6. 删除HDFS上的文件 hdfs dfs -rm /user/hadoop/input/test.txt # 7. 删除HDFS目录 hdfs dfs -rm -r /user/hadoop/input

4.4 运行一个MapReduce示例作业

Hadoop自带了一些示例JAR包,我们可以运行经典的WordCount来测试整个计算框架是否正常。

# 1. 准备输入数据。在HDFS上创建输入目录并上传多个文本文件。 hdfs dfs -mkdir -p /wordcount/input # 可以上传一些本地文本文件,或者直接创建 echo "Hello World Bye World" > file1.txt echo "Hello Hadoop Goodbye Hadoop" > file2.txt hdfs dfs -put file*.txt /wordcount/input/ # 2. 运行WordCount示例程序。 # hadoop-mapreduce-examples-3.3.6.jar 包含了各种示例 # 语法:hadoop jar <jar包路径> <主类名> <输入路径> <输出路径> # 注意:输出路径必须不存在,程序会自动创建。 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount /wordcount/input /wordcount/output # 3. 观察输出。作业会提交到YARN,可以在8088端口Web UI看到作业运行状态。 # 等待作业完成(SUCCEEDED)。 # 4. 查看结果。 hdfs dfs -cat /wordcount/output/part-r-00000

你应该能看到每个单词及其出现的次数,例如:

Bye 1 Goodbye 1 Hadoop 2 Hello 2 World 2

如果这个作业能成功运行并输出正确结果,那么恭喜你,一个功能完整的Hadoop集群已经搭建成功了!

5. 集群管理、问题排查与进阶思考

集群跑起来只是第一步,日常管理和问题排查才是真正的挑战。

5.1 日常管理命令

  • 启动/停止所有服务:

    # 在master执行 start-all.sh # 启动所有 (HDFS+YARN,不推荐,已废弃,建议分开启) stop-all.sh # 停止所有 # 推荐分开管理 start-dfs.sh # 启动HDFS stop-dfs.sh # 停止HDFS start-yarn.sh # 启动YARN stop-yarn.sh # 停止YARN mapred --daemon stop historyserver # 停止历史服务器
  • 单独启动/停止某个服务:

    # 在对应节点执行 hdfs --daemon start|stop namenode|datanode|secondarynamenode yarn --daemon start|stop resourcemanager|nodemanager
  • 查看日志:日志是排查问题的生命线。Hadoop日志通常位于$HADOOP_HOME/logs/目录下,按用户和进程分文件。

    • hadoop-hadoop-namenode-master.log(NameNode日志)
    • hadoop-hadoop-datanode-slave1.log(DataNode日志)
    • yarn-hadoop-resourcemanager-master.log(ResourceManager日志) 使用tail -f <日志文件>可以实时查看日志输出。

5.2 常见问题与排查实录

根据我踩过的坑,这里列出几个最常见的问题及其解决思路。

问题1:DataNode启动失败,日志显示“Incompatible clusterIDs”或“NamespaceID”不匹配。

  • 原因:最常见的原因是多次格式化NameNode。每次格式化都会生成新的集群ID(clusterID),而DataNode还保存着旧的ID,导致无法注册。
  • 解决:
    1. 停止所有服务:stop-all.sh
    2. 删除所有节点上Hadoop数据目录(${hadoop.tmp.dir},例如/opt/module/hadoop/data/tmp)下的所有内容。注意:这会清空所有HDFS数据!
    3. 重新格式化NameNode:hdfs namenode -format
    4. 重新启动集群。

问题2:从节点(Slave)的DataNode或NodeManager进程没有启动。

  • 排查步骤:
    1. 在master执行start-dfs.shstart-yarn.sh时,观察终端输出,看是否有连接被拒绝(Connection refused)或权限被拒绝(Permission denied)的错误。
    2. 登录到出问题的从节点,用jps查看是否有进程。如果没有,去$HADOOP_HOME/logs/查看对应日志(如hadoop-hadoop-datanode-slave1.log)。
    3. 常见原因:
      • SSH免密登录未配置成功:在master上尝试ssh slave1,看是否需要密码。
      • 防火墙未关闭:在从节点执行systemctl status firewalld检查。
      • 主机名映射错误:在从节点ping master,看是否能解析为正确的IP。
      • 目录权限问题:确保hadoop用户对Hadoop安装目录和数据目录有读写权限。
      • Java环境问题:在从节点执行java -versionecho $JAVA_HOME,确保与master一致。

问题3:Web UI(9870或8088)无法访问。

  • 排查步骤:
    1. 检查进程是否存活:jps
    2. 检查端口是否监听:netstat -tlnp | grep 9870(或8088)。
    3. 如果端口未监听,检查对应进程的日志。
    4. 如果端口监听但无法访问,检查master节点的防火墙规则,或者是否在虚拟机网络配置中做了端口转发。

问题4:运行MapReduce作业失败,YARN Web UI显示作业状态为FAILED。

  • 排查步骤:
    1. 在8088 UI上点击失败的作业,查看日志。特别是“Diagnostics”信息和Container日志。
    2. 常见原因:
      • yarn.nodemanager.aux-services未配置或配置错误:必须是mapreduce_shuffle
      • 资源不足:NodeManager可用内存或CPU不足。需要调整yarn-site.xmlmapred-site.xml中的资源相关参数,如yarn.nodemanager.resource.memory-mb,yarn.scheduler.maximum-allocation-mb,mapreduce.map.memory.mb等。
      • 类路径问题:作业依赖的库找不到。可以考虑将依赖JAR包上传到HDFS,并通过-libjars参数指定。

5.3 性能调优与安全初步

对于生产环境,我们还需要考虑更多。

基础性能调优:

  • JVM堆内存设置:hadoop-env.shyarn-env.sh中调整HADOOP_HEAPSIZEYARN_HEAPSIZE。对于NameNode和ResourceManager,建议设置2-4GB以上。
  • DataNode磁盘选择:dfs.datanode.data.dir可以配置多个用逗号分隔的目录,这些目录应该对应不同的物理磁盘,以提高IO吞吐量。
  • YARN资源配置:根据机器物理资源,合理设置yarn.nodemanager.resource.memory-mb(NodeManager总内存)和yarn.nodemanager.resource.cpu-vcores(总虚拟CPU核数)。容器内存设置(mapreduce.map.memory.mb,mapreduce.reduce.memory.mb)应小于NodeManager单个容器可分配的最大内存。

安全配置:

  • 启用HDFS权限检查:hdfs-site.xml中,确保dfs.permissions.enabledtrue。HDFS有类似Linux的文件权限模式(rwx)。
  • 使用Kerberos进行认证:这是生产集群的标配,用于防止未授权访问。配置过程较为复杂,涉及KDC服务器、生成keytab文件等。
  • 配置网络加密:使用SSL/TLS对RPC和HTTP传输进行加密。

5.4 集群停止与维护

当需要关机维护时,务必按顺序停止服务:

# 在master上执行 stop-yarn.sh stop-dfs.sh mapred --daemon stop historyserver

粗暴地直接关机可能导致元数据损坏。定期检查磁盘空间,清理过期日志($HADOOP_HOME/logs/和YARN聚合日志目录)。对于NameNode元数据(dfs.namenode.name.dir),建议定期通过hdfs dfsadmin -fetchImage命令备份到远程。

搭建只是起点,理解其运行机制,并能稳定运维和性能调优,才是掌握Hadoop的关键。这套超详细的流程几乎涵盖了从零开始的所有环节,希望你能通过亲手实践,真正吃透每个步骤背后的原理。遇到问题多查日志,善用Web UI和社区资源,大数据之路就从这里开始了。

← 返回列表