Hadoop

概念

​ Hadoop 是一个开源的分布式存储与计算框架,用于在普通服务器集群上存储和处理海量数据。它解决了传统单机无法处理 PB 级数据的难题,是大数据领域的基石技术。一句话概括就是:Hadoop = 把一堆普通电脑组成一个“超级计算机”,用来存储和处理海量数据。

Hadoop 三大核心组件

  1. HDFS(分布式文件系统)

负责存数据

把大文件切分成小块 (block,默认 128M),分散存集群不同机器;自动多副本备份,某一台机器挂掉,数据不会丢。

角色:

  • NameNode:主节点,记录文件目录、块存在哪台机器(元数据)
  • DataNode:从节点,真正保存数据块
  1. YARN(资源调度管理器)

负责分配机器 CPU、内存资源,调度任务跑在哪台机器

相当于集群的 “操作系统”,管理集群硬件资源,给计算程序分配资源。

  1. MapReduce(分布式计算框架)

负责处理、计算数据

分 Map(拆分处理)+Reduce(汇总结果),把大计算任务拆分给多台机器并行跑。

现在生产环境很多用 Spark 替代 MapReduce 做计算,但 HDFS+YARN 依然大量使用。

安装部署单机模式

Hadoop3.3.6 伪分布式完整部署 + 本地模式 MR 测试 + HDFS 配置初始化过程

[root@node1 ~]# ls                                # 查看当前目录安装包
anaconda-ks.cfg  hadoop-3.3.6.tar.gz  jdk-8u181-linux-x64.tar.gz
[root@node1 ~]# useradd hadoop                   # 创建hadoop运行普通用户
[root@node1 ~]# passwd hadoop                    # 设置hadoop用户密码
[root@node1 ~]# mv hadoop-3.3.6.tar.gz jdk-8u181-linux-x64.tar.gz /home/hadoop/  # 将安装包移动到hadoop家目录
[root@node1 ~]# su - hadoop                      # 切换至hadoop普通用户环境
[hadoop@node1 ~]$ ls                             # 确认家目录下两个压缩包
hadoop-3.3.6.tar.gz  jdk-8u181-linux-x64.tar.gz
[hadoop@node1 ~]$ tar zxf hadoop-3.3.6.tar.gz    # 解压hadoop二进制包
[hadoop@node1 ~]$ tar zxf jdk-8u181-linux-x64.tar.gz # 解压jdk8安装包
[hadoop@node1 ~]$ ln -s hadoop-3.3.6 hadoop      # 创建hadoop软链接,方便版本升级
[hadoop@node1 ~]$ ln -s jdk1.8.0_181/ jdk        # 创建jdk软链接,方便版本升级
[hadoop@node1 ~]$ vim .bash_profile              # 编辑用户环境变量配置文件
...
PATH=$PATH:$HOME/.local/bin:$HOME/bin:/home/hadoop/jdk/bin  # 将jdk/bin加入PATH环境变量
[hadoop@node1 ~]$ source .bash_profile            # 重载环境变量使其立即生效
[hadoop@node1 ~]$ cd hadoop/etc/hadoop/          # 进入hadoop配置文件目录
[hadoop@node1 hadoop]$ cat workers               # 查看从节点列表文件,单机模式为localhost
localhost
[hadoop@node1 hadoop]$ vim hadoop-env.sh         # 编辑hadoop环境脚本,指定JAVA_HOME
export JAVA_HOME=/home/hadoop/jdk
[hadoop@node1 hadoop]$ cd ~/hadoop                 # 切换hadoop根目录
[hadoop@node1 hadoop]$ bin/hadoop                # 验证hadoop脚本可执行
[hadoop@node1 hadoop]$ mkdir input               # 创建mapreduce测试输入目录
[hadoop@node1 hadoop]$ cp etc/hadoop/*.xml input # 拷贝配置xml作为测试输入样本
[hadoop@node1 hadoop]$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar grep input output 'dfs[a-z.]+' # 运行grep示例MR任务
[hadoop@node1 hadoop]$ cat output/*              # 查看MR任务输出结果
1       dfsadmin
[hadoop@node1 hadoop]$
[hadoop@node1 hadoop]$ cd etc/hadoop/            # 返回配置目录,准备配置HDFS
[hadoop@node1 hadoop]$ vim core-site.xml         # 编辑core-site核心配置文件
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost:9000</value>     # 指定HDFS NameNode访问地址
    </property>
</configuration>
[hadoop@node1 hadoop]$ vim hdfs-site.xml          # 编辑hdfs-site hdfs参数配置
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>                         # HDFS副本数,单机环境设置1
    </property>
</configuration>
[hadoop@node1 hadoop]$ cd /home/hadoop/hadoop	#返回当前层级Hadoop根目录
[hadoop@node1 hadoop]$ ssh-keygen                # 生成ssh公私钥,实现本机免密登录
[hadoop@node1 hadoop]$ ssh-copy-id localhost     # 将公钥推送至本机,实现localhost免密ssh
[hadoop@node1 hadoop]$ bin/hdfs namenode -format # 格式化HDFS NameNode元数据(仅首次执行!不要重复执行)
[hadoop@node1 hadoop]$ sbin/start-dfs.sh         # 启动HDFS集群(namenode+datanode+secondarynamenode)

访问:192.168.117.131:9870能看到界面

image-20260821165151861

操作分布式文件系统 HDFS

Hadoop 伪分布式模式下操作 HDFS 分布式文件系统

[hadoop@node1 hadoop]$ jps                     # 查看Java进程,验证HDFS组件全部正常运行
4880 DataNode                                  # HDFS数据节点进程
5024 SecondaryNameNode                         # HDFS辅助名称节点,做元数据checkpoint
5746 Jps                                       # jps本身进程
4781 NameNode                                  # HDFS主名称节点进程
[hadoop@node1 hadoop]$ bin/hdfs dfs -mkdir -p /user/hadoop   # 在HDFS上创建hadoop用户家目录(-p自动递归创建父目录)
[hadoop@node1 hadoop]$ bin/hdfs dfs -mkdir input              # 在HDFS的/user/hadoop下创建input输入目录(默认相对路径)

image-20260822211047352

上传本地文件

[hadoop@node1 hadoop]$ bin/hdfs dfs -put etc/hadoop/*.xml input # 将本地配置xml文件上传至HDFS的input目录
[hadoop@node1 hadoop]$ bin/hdfs dfs -ls input                 # 查看HDFS input目录下已上传文件列表
Found 10 items
-rw-r--r--   1 hadoop supergroup       9213 2026-08-21 17:07 input/capacity-scheduler.xml
-rw-r--r--   1 hadoop supergroup        884 2026-08-21 17:07 input/core-site.xml
-rw-r--r--   1 hadoop supergroup      11765 2026-08-21 17:07 input/hadoop-policy.xml
-rw-r--r--   1 hadoop supergroup        683 2026-08-21 17:07 input/hdfs-rbf-site.xml
-rw-r--r--   1 hadoop supergroup        867 2026-08-21 17:07 input/hdfs-site.xml
-rw-r--r--   1 hadoop supergroup        620 2026-08-21 17:07 input/httpfs-site.xml
-rw-r--r--   1 hadoop supergroup       3518 2026-08-21 17:07 input/kms-acls.xml
-rw-r--r--   1 hadoop supergroup        682 2026-08-21 17:07 input/kms-site.xml
-rw-r--r--   1 hadoop supergroup        758 2026-08-21 17:07 input/mapred-site.xml
-rw-r--r--   1 hadoop supergroup        690 2026-08-21 17:07 input/yarn-site.xml

image-20260822211354769

基于已经部署好的HDFS 伪分布式集群,运行一套完整的 MapReduce 分布式计算任务:从 HDFS 读数据 → MR 程序运算 → 结果写回 HDFS → 把计算结果下载到 Linux 本地查看,最后关闭 HDFS 服务

# 运行MapReduce grep示例,读取HDFS input目录,结果输出到HDFS output
[hadoop@node1 hadoop]$ bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar grep input output 'dfs[a-z.]+'
# 删除本地output文件夹里的内容
[hadoop@node1 hadoop]$ rm -rf output
# 将HDFS上output目录下载到本地当前目录,本地生成output文件夹
[hadoop@node1 hadoop]$ bin/hdfs dfs -get output output
# 读取本地output目录下所有文件;报错output/output是目录,实际有效输出1       dfsadmin
[hadoop@node1 hadoop]$ cat output/*
cat: output/output: Is a directory
1       dfsadmin
# 停止HDFS全部服务(NameNode、DataNode、SecondaryNameNode)
[hadoop@node1 hadoop]$ sbin/stop-dfs.sh
Stopping namenodes on [localhost]
Stopping datanodes
Stopping secondary namenodes [node1]
[hadoop@node1 hadoop]$ jps
2355 Jps

hadoop完全分布式

HDFS 默认 3 副本机架感知策略

image-20260822222722343

整体流程:

  1. 第 1 个副本:优先放在客户端所在的节点

图:client 在 r1 机架的 dn3,副本 1 放在 dn3(本机)。 如果客户端不在集群节点内,则随机选一个节点。

  1. 第 2 个副本:放到和第一个副本不同机架的任意一台 DataNode

图:副本 2 放到 r2 机架的 dn4。 目的:规避整个机架断电 / 故障风险,跨机架。

  1. 第 3 个副本:放到第二个副本所在机架内的另一个节点

图:副本 3 放在同 r2 机架的 dn6。 原因:跨机架网络带宽成本高,第三份放在同一个机架内部复制,节省跨机架网络 IO。

✔最终 3 个副本分布: 副本 1:机架 r1(dn3) 副本 2:机架 r2(dn4) 副本 3:机架 r2(dn6) 不会 3 个副本全塞同一个机架,也不会 3 份分散在 3 个不同机架(太耗跨机架带宽)。

HDFS 文件上传(写数据)流程

image-20260822222647562

完整步骤:

  1. 客户端发起上传请求 client 向 NameNode 发送上传文件请求。 NameNode 做权限校验、目录检查,在内存生成这条文件的元数据,返回 3 个 DataNode 节点列表(dn1,dn2,dn3)给客户端
  2. 客户端本地切分文件 client 本地把待上传大文件切分成一个个 128M 的 block 数据块,每个 block 要保存 3 份副本。
  3. 流水线 pipeline 传输数据包 client 向列表里第一个 dn1 发送数据包 packet; dn1 收到数据,自己保存一份,同时转发给下游 dn2; dn2 收到,自己保存一份,转发给 dn3; dn3 收到,保存第三份副本。
  4. 反向 ACK 确认应答 写入完成后应答反向回流:dn3→dn2→dn1→client。 全部副本写入成功,client 才认为这个 block 上传成功;只要任意一个 dn 失败,NameNode 会重新挑选节点重建副本。
  5. 块全部上传完毕,关闭文件 所有 block 全部传输完成,client 通知 NameNode:文件写入完成。 NameNode 把完整元数据持久化保存到磁盘(fsimage)。

DataNode 后续会定期向 NameNode 汇报自己保存了哪些 block。

部署NFS 服务端

node1 充当 NFS 服务端,把本机/home/hadoop目录共享给集群其他机器。 其他节点(客户端)就可以通过 NFS 挂载/home/hadoop,多台机器共用同一套目录文件,并且文件属主是 hadoop 用户,不会出现权限报错。

[hadoop@node1 hadoop]$ logout                                 # 退出hadoop普通用户
[root@node1 ~]# yum install -y nfs-utils                      # 安装nfs服务工具包
[root@node1 ~]# id hadoop                                    # 查看hadoop用户id信息
uid=1000(hadoop) gid=1000(hadoop) groups=1000(hadoop)        # 输出hadoop的uid与gid
[root@node1 ~]# vim /etc/exports                              # 编辑nfs共享配置文件
/home/hadoop    *(rw,sync,anonuid=1000,anongid=1000)         # 配置共享目录权限与uid gid映射
[root@node1 ~]# systemctl enable --now nfs                   # 启动nfs并设置开机自启
[root@node1 ~]# showmount -e                                 # 查看本机nfs导出共享列表
Export list for node1:
/home/hadoop *                                                # nfs共享导出结果

部署NFS 客户端

新增两台主机作为datanodes。挂载 node1 的 NFS 共享目录 /home/hadoop,实现多台机器共享 hadoop 家目录,让 node2 和 node3 直接使用 node1 上面的 jdk、hadoop 安装包,不用重复解压部署。

[root@node2 ~]# useradd hadoop                                 # 创建hadoop系统用户
[root@node2 ~]# echo westos |passwd --stdin hadoop             # 非交互设置hadoop用户密码为westos
[root@node2 ~]# yum install -y nfs-utils                       # 安装NFS客户端工具
[root@node2 ~]# showmount -e node1                             # 查询node1节点对外提供的NFS共享
Export list for node1:
/home/hadoop *                                                 # 查询结果:node1共享/home/hadoop目录
[root@node2 ~]# mount 192.168.117.131:/home/hadoop /home/hadoop # 将远端NFS共享挂载到本地/home/hadoop
[root@node2 ~]# df                                             # 查看磁盘挂载信息
Filesystem                   1K-blocks    Used Available Use% Mounted on
...
192.168.117.131:/home/hadoop  49251072 4274176  44976896   9% /home/hadoop  # NFS挂载成功的记录
[root@node2 ~]# ll -d /home/hadoop/                           # 查看挂载目录的属性权限
drwx------ 6 hadoop hadoop 262 Aug 21 16:49 /home/hadoop/      # 目录属主为hadoop用户组
[root@node2 ~]# id hadoop                                      # 查看本机hadoop用户UID/GID
uid=1000(hadoop) gid=1000(hadoop) groups=1000(hadoop)         # 本机hadoop uid,gid与服务端保持一致
[root@node2 ~]# su - hadoop                                    # 切换到hadoop普通用户
[hadoop@node2 ~]$ ls                                           # 列出hadoop家目录下文件
hadoop        hadoop-3.3.6.tar.gz  jdk1.8.0_181
hadoop-3.3.6  jdk                  jdk-8u181-linux-x64.tar.gz

另一个节点同理

修改Hadoop三大配置并启动HDFS

[hadoop@node1 ~]$ ssh node1                                 # 使用ssh登录本机node1,测试免密登录是否正常
[hadoop@node1 ~]$ logout                                    # 退出ssh会话
[hadoop@node1 ~]$ ssh node2                                 # ssh登录node2,验证集群节点免密互通
[hadoop@node1 ~]$ logout                                    # 退出ssh会话
[hadoop@node1 ~]$ ssh node3                                 # ssh登录node3,验证集群节点免密互通
[hadoop@node1 ~]$ logout                                    # 退出ssh会话
[hadoop@node1 ~]$ cd hadoop/etc/hadoop/                     # 进入hadoop配置文件目录
[hadoop@node1 hadoop]$ vim core-site.xml                    # 编辑hadoop核心配置文件core‑site.xml
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://node1:9000</value>                    # 指定HDFS的NameNode通信地址
    </property>
</configuration>
[hadoop@node1 hadoop]$ vim hdfs-site.xml                    # 编辑hdfs相关配置文件hdfs‑site.xml
<configuration>
    <property>
        <name>dfs.replication</name>
        <value>2</value>                                    # 设置hdfs数据块副本数量为2
    </property>
</configuration>
[hadoop@node1 hadoop]$ vim workers                          # 编辑workers文件,填写datanode工作节点列表
node2
node3
[hadoop@node1 hadoop]$ cd ..                                # 返回上一级etc目录
[hadoop@node1 etc]$ cd ..                                   # 返回hadoop根目录
[hadoop@node1 hadoop]$ bin/hdfs namenode -format            # 格式化NameNode,生成hdfs元数据
[hadoop@node1 hadoop]$ sbin/start-dfs.sh                    # 一键启动hdfs集群
Starting namenodes on [node1]
Starting datanodes
Starting secondary namenodes [node1]
[hadoop@node1 hadoop]$ jps                                  # 查看本机java进程
3045 NameNode                                               # NameNode进程
3271 SecondaryNameNode                                      # SecondaryNameNode进程
3391 Jps                                                    # jps自身进程

查看datanode节点信息

image-20260822221314784

可以通过logs查看日志

image-20260822221427952

日志目录

image-20260822221404550

HDFS 集群启动完成后,在分布式文件系统上创建业务目录,并且上传测试样本文件

[hadoop@node1 hadoop]$ bin/hdfs dfs -mkdir /user                     # 在HDFS文件系统根下创建/user目录
[hadoop@node1 hadoop]$ bin/hdfs dfs -mkdir /user/hadoop              # 在HDFS上创建/user/hadoop用户工作目录
[hadoop@node1 hadoop]$ bin/hdfs dfs -mkdir input                     # 在HDFS当前用户目录下创建input输入目录
[hadoop@node1 hadoop]$ bin/hdfs dfs -put etc/hadoop/*.xml input      # 将本地etc/hadoop下所有xml配置文件上传到HDFS的input目录

查看我们上传的样本文件,能看到存储在了哪些数据节点上

image-20260822221832245

启用资源管理器(yarn主调度服务)

[hadoop@node1 hadoop]$ vim etc/hadoop/mapred-site.xml	# 编辑MapReduce框架配置文件mapred‑site.xml
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>		# 指定mapreduce运行资源调度框架为yarn
    </property>
    <property>
        <name>mapreduce.application.classpath</name>
        <value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value> # mapreduce任务运行所需jar包类路径
    </property>
</configuration>
[hadoop@node1 hadoop]$ vim etc/hadoop/yarn-site.xml		# 编辑YARN资源调度框架配置文件yarn‑site.xml
<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value> # 开启shuffle洗牌服务,供MapReduce任务数据洗牌使用
    </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,HADOOP_MAPRED_HOME</value> # 节点管理器允许传递的环境变量白名单
    </property>
</configuration>
[hadoop@node1 hadoop]$ sbin/start-yarn.sh   # 一键启动yarn集群
Starting resourcemanager    # 启动ResourceManager(yarn主调度服务)
Starting nodemanagers    # 启动各个节点NodeManager(yarn从节点服务)

在线扩容

新增一台主机,关闭防火墙、selinux,做好解析,配置好时间同步

# 安装nfs工具包,用于NFS网络文件系统挂载
[root@node4 ~]# yum install -y nfs-utils

# 创建hadoop普通用户,hadoop集群运行使用该用户
[root@node4 ~]# useradd hadoop

# 通过标准输入给hadoop用户设置密码westos,非交互设置密码
[root@node4 ~]# echo westos |passwd --stdin hadoop
Changing password for user hadoop.
passwd: all authentication tokens updated successfully.

# 查询node1节点NFS共享目录导出列表,查看可挂载的共享路径
[root@node4 ~]# showmount -e node1
Export list for node1:
/home/hadoop *

# 将node1(192.168.117.131)的NFS共享目录/home/hadoop挂载到本地/home/hadoop
[root@node4 ~]# mount 192.168.117.131:/home/hadoop /home/hadoop

# 查看本地/home/hadoop目录属性,确认属主、权限
[root@node4 ~]# ll -d /home/hadoop/
drwx------ 6 hadoop hadoop 262 Aug 22 23:23 /home/hadoop/

# 切换登录为hadoop用户,进入hadoop家目录
[root@node4 ~]# su - hadoop

# 进入hadoop安装根目录
[hadoop@node4 ~]$ cd hadoop

# 编辑workers配置文件,定义集群从节点列表(DataNode、NodeManager会在这些节点启动)
[hadoop@node4 hadoop]$ vim etc/hadoop/workers
node2
node3
node4

# 后台守护进程方式启动HDFS的数据节点DataNode
[hadoop@node4 hadoop]$ bin/hdfs --daemon start datanode

# jps查看Java进程,验证DataNode是否成功启动
[hadoop@node4 hadoop]$ jps
1660 DataNode
1727 Jps

# 后台守护进程方式启动YARN的节点管理器NodeManager
[hadoop@node4 hadoop]$ bin/yarn --daemon start nodemanager

# 再次jps查看进程,确认DataNode、NodeManager都正常运行
[hadoop@node4 hadoop]$ jps
1872 Jps
1779 NodeManager
1660 DataNode

节点已经添加进来了

image-20260822233700306

访问:192.168.117.131:8088可以看到资源调度器的管理界面

image-20260822233808905

更多推荐