Hadoop 核心组件详解:HDFS、YARN、MapReduce 如何各司其职?
Hadoop 核心组件详解:HDFS、YARN、MapReduce 如何各司其职?
🌺The Begin🌺点点关注,收藏不迷路🌺 |
大数据时代,面对海量数据的存储与计算,Hadoop 作为一个开源的分布式基础架构,发挥了重要作用。它不仅仅是一个程序,而是一个完整的生态系统。要理解 Hadoop,首先要掌握它的三大核心组件:HDFS、YARN 和 MapReduce。
本文将深入浅出地解析这三大组件的架构与角色,并通过流程图和代码示例,帮助你理解它们是如何协同工作,处理海量数据的。
一、Hadoop 核心组件全景图
在 Hadoop 2.x 及以后的版本中,其架构主要由以下四部分组成(其中 Common 为底层支撑):
- HDFS(分布式文件系统):解决“海量数据怎么存”的问题。
- YARN(资源调度框架):解决“集群资源怎么管”的问题。
- MapReduce(分布式计算框架):解决“海量数据怎么算”的问题。
- Hadoop Common:支撑以上模块的公共工具库(如 RPC、序列化等)。
下图清晰地展示了 Hadoop 核心组件在大数据处理流程中的层次关系:
Client层
主节点 Master
数据读写
数据读写
心跳与块报告
心跳与块报告
心跳与资源汇报
心跳与资源汇报
从节点 Slave
DataNode
NodeManager
从节点 Slave
DataNode
存储数据块
NodeManager
管理容器
NameNode
HDFS元数据管理
ResourceManager
YARN全局资源调度
二、HDFS:分布式文件系统
HDFS 是整个 Hadoop 生态的存储基石。它的设计目标是运行在廉价硬件上,提供高容错、高吞吐量的数据访问。
1. 架构角色
HDFS 采用经典的主从(Master/Slave)架构 :
- NameNode(主节点):相当于“目录索引”。它管理文件系统的命名空间,维护所有文件和目录的元数据(如文件名、权限、以及文件数据块所在的DataNode列表)。NameNode 还会记录每个块的存放位置,但并不持久化存储每个块的具体位置信息,这些信息在启动时由DataNode提供。
- DataNode(从节点):真正的“搬运工”。负责存储实际的数据块(Block)。默认情况下,一个文件会被切割成 128MB 大小的块,并且每个块会有 3 个副本,分布在不同的 DataNode 上以保证数据安全 。
- Secondary NameNode(辅助节点):不是NameNode的热备。它定期合并 NameNode 的日志(edits log)和镜像文件(fsimage),帮助 NameNode 在重启时更快地启动,并在 NameNode 损坏时提供恢复依据 。
2. 读写流程(流程图)
HDFS 写数据流程
当客户端要往 HDFS 写入一个文件时,流程如下:
数据写入管道
返回可用DataNode列表
请求分配第一个Block
复制Block
复制Block
确认副本完成
更新元数据
客户端
向NameNode请求上传文件
NameNode检查权限及路径
客户端将文件切分为Block
DataNode 1
DataNode 2
DataNode 3
NameNode
写入成功
流程简述:客户端向 NameNode 请求上传文件 -> NameNode 检查目标路径和权限 -> NameNode 告知客户端可写入的 DataNode 列表 -> 客户端将文件切分成 Block -> 按顺序将 Block 以**管道(Pipeline)**方式写入第一个 DataNode,并由该节点自动复制给后续节点 -> 所有副本写入成功后,客户端通知 NameNode 更新元数据 。
HDFS 读数据流程
读取文件时,流程则体现为“计算向数据移动”的思想:
HDFS集群
客户端
向NameNode请求读取文件
NameNode返回元数据
文件Block分布在哪些DataNode
客户端根据元数据
选择最近的DataNode读取Block
DataNode 1
Block A
DataNode 2
Block B
客户端合并Block
完成读取
流程简述:客户端向 NameNode 请求读取文件 -> NameNode 返回该文件所有 Block 所在的 DataNode 列表(考虑网络拓扑,按近到远排序)-> 客户端直接连接到最近的 DataNode 并行读取数据块 -> 在客户端本地合并成完整的文件 。
三、YARN:资源调度与管理系统
在 Hadoop 1.x 时代,MapReduce 既负责计算又负责资源管理,这导致了系统的耦合度过高。YARN 的出现将资源管理和作业调度/监控分离,成为了 Hadoop 的操作系统内核 。
1. 架构角色
- ResourceManager(RM):全局老大。负责整个集群的资源管理和分配,处理客户端的请求,启动和监控 ApplicationMaster,并在节点故障时进行容错处理 。
- NodeManager(NM):单机管家。负责单个节点的资源管理(CPU、内存),启动并监控容器(Container),并定期向 ResourceManager 汇报本节点资源使用情况 。
- ApplicationMaster(AM):任务监工。每个提交到 YARN 的应用程序都有一个专属的 AM。它负责向 ResourceManager 申请资源(Container),并与 NodeManager 通信启动任务,同时监控任务的运行状态,进行容错 。
- Container:资源容器。对任务运行环境的抽象,封装了 CPU、内存等资源及环境变量。
2. YARN 的任务提交流程
提交Application
分配Container
启动ApplicationMaster
启动
向RM注册并申请资源
返回资源列表
通知NM启动Container
通知NM启动Container
执行Task
执行Task
心跳汇报进度
心跳汇报进度
注销并关闭
客户端
ResourceManager
NodeManager 1
ApplicationMaster
NodeManager 2
NodeManager 3
MapTask/ReduceTask
MapTask/ReduceTask
流程简述:客户端提交作业到 ResourceManager -> RM 在某个 NodeManager 上分配第一个 Container 启动 ApplicationMaster -> AM 启动后向 RM 注册并申请资源(Container列表) -> AM 向对应的 NodeManager 发送指令启动真正的 Task(Map/Reduce) -> Task 运行期间通过 AM 向 RM 汇报进度 -> 作业完成后,AM 注销并释放资源 。
四、MapReduce:分布式计算框架
MapReduce 是一种分而治之的编程模型,用于大规模数据集的并行计算。它将计算过程抽象为两个阶段:Map(映射)和Reduce(归约) 。
1. 核心思想
- Map:把复杂的任务分解为若干个“简单的任务”来并行处理。
- Reduce:把 Map 阶段处理后的结果进行汇总。
2. 经典 WordCount 代码示例
下面是一个统计文本中单词出现次数的经典案例 :
// Mapper类:负责切分单词并输出 <单词,1>publicstaticclassTokenizerMapperextendsMapper<Object,Text,Text,IntWritable>{privatefinalstaticIntWritable one =newIntWritable(1);privateText word =newText();publicvoidmap(LongWritable key,Text value,Context context )throwsIOException,InterruptedException{StringTokenizer itr =newStringTokenizer(value.toString());while(itr.hasMoreTokens()){ word.set(itr.nextToken()); context.write(word, one);// 输出: (hello, 1)}}}// Reducer类:负责累加相同单词的次数publicstaticclassIntSumReducerextendsReducer<Text,IntWritable,Text,IntWritable>{privateIntWritable result =newIntWritable();publicvoidreduce(Text key,Iterable<IntWritable> values,Context context )throwsIOException,InterruptedException{int sum =0;for(IntWritable val : values){ sum += val.get();// 累加: (hello, [1,1,1]) -> 3} result.set(sum); context.write(key, result);// 输出: (hello, 3)}}3. MapReduce 完整执行流程
Reduce阶段
Shuffle阶段
分区 排序 拷贝
Map阶段
输入分片
输出 (k,v)
输出 (k,v)
输出 (k,v)
文件 0
Split 1
Split 2
Split 3
MapTask
MapTask
MapTask
环形缓冲区
环形缓冲区
环形缓冲区
溢写到磁盘
并按分区排序
归并排序
合并溢写文件
ReduceTask
拉取对应分区数据
最终结果写入HDFS
流程详解 :
- Map 阶段:
- Input:从 HDFS 读取数据,根据输入格式(InputFormat)将文件切分成多个 Split(逻辑切片),每个 Split 启动一个 MapTask。
- Map:运行用户自定义的
map()函数,输出中间结果到内存缓冲区(环形缓冲区)。 - Spill(溢写):当缓冲区达到阈值(默认80%),后台线程开始将数据溢写到本地磁盘。在溢写过程中,会进行分区(Partition)和排序(Sort)。如果用户定义了 Combiner(相当于小型的本地Reduce),会在此时执行。
- Shuffle 阶段:
- Copy:ReduceTask 启动多个复制线程,通过 HTTP 方式从各个 MapTask 完成的节点上拉取属于自己的分区数据。
- Merge:ReduceTask 将从不同 Map 拉取来的数据进行合并(Merge)和排序,形成 Reduce 函数的输入文件。
- Reduce 阶段:
- 运行用户自定义的
reduce()函数,对排序后的数据进行聚合计算。 - 将最终结果写入 HDFS。
- 运行用户自定义的
五、总结:三驾马车的协同
在 Hadoop 集群中,这三大组件形成了一个高效的整体:
- HDFS 提供了坚实的数据仓库,让海量数据有处可存,且安全可靠。
- YARN 扮演了大管家的角色,统筹集群的计算资源,谁该用多少、什么时候用,都由它说了算。
- MapReduce 则是执行者,它利用 YARN 分配的资源,对 HDFS 上的数据进行大规模并行计算。
理解这三者的关系,是掌握 Hadoop 乃至整个大数据技术生态的基石。无论是后来的 Hive、Spark 还是 Flink,很多都是在 YARN 之上运行,并利用 HDFS 进行存储的。打好这个基础,你在学习其他大数据组件时会事半功倍。
🌺The End🌺点点关注,收藏不迷路🌺 |