Hadoop
是一个开源的分布式计算框架,由 Apache Software Foundation
开发和维护,专为处理和存储大量数据而设计,具有高容错性和可扩展性。
Hadoop
主要由两个核心组件组成:Hadoop Distributed File System(HDFS)
与 MapReduce
,分别作用于存储数据与数据的编程和执行。
一、HDFS
HDFS
是 Hadoop
中的分布式文件系统,设计用于在大规模集群环境中存储非常大的文件,它将数据分块并将块分布在多个节点上,提供高容错性和高吞吐量。
1. 架构设计
HDFS
遵循主/从架构,由单个 NameNode(NN)
和多个 DataNode(DN)
组成:
- NameNode : 负责执行有关
文件系统命名空间
的操作,例如打开,关闭、重命名文件和目录等。它同时还负责集群元数据的存储,记录着文件中各个数据块的位置信息。 - DataNode:负责提供来自文件系统客户端的读写请求,执行块的创建,删除等操作。
2. 存储机制
HDFS
中的文件在物理上是分块存储 (block)
,块的大小可以通过配置参数 (dfs.blocksize)
来规定,默认大小在 hadoop2.x
版本中是 128M
,老版本中是 64M
;
HDFS
文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
;目录结构及文件分块信息(元数据)的管理由 Namenode
节点承担;
3. 存储结构
(1) 块
为了保证容错性,HDFS
提供了数据复制机制。HDFS
将每一个文件存储为一系列 块,每个块由多个副本来保证容错,块的大小和复制因子可以自行配置(默认情况下,块大小是 128M
,默认复制因子是 3
)。
(2) 副本
在写入程序位于 datanode
上时,就优先将写入文件的一个副本放置在该 datanode
上,否则放在随机 datanode
上。之后在另一个远程机架上的任意一个节点上放置另一个副本,并在该机架上的另一个节点上放置最后一个副本。此策略可以减少机架间的写入流量,从而提高写入性能。
4. 心跳机制
每个 DataNode
定期向 NameNode
发送心跳消息,如果超过指定时间没有收到心跳消息,则将 DataNode
标记为死亡。NameNode
不会将任何新的 IO
请求转发给标记为死亡的 DataNode
,也不会再使用这些 DataNode
上的数据。由于数据不再可用,可能会导致某些块的复制因子小于其指定值,NameNode
会跟踪这些块,并在必要的时候进行重新复制。
5. 数据验证
由于存储设备故障等原因,存储在 DataNode
上的数据块也会发生损坏。为了避免读取到已经损坏的数据而导致错误,HDFS
提供了数据完整性校验机制来保证数据的完整性,具体操作如下:
当客户端创建 HDFS
文件时,它会计算文件的每个块的 校验和
,并将 校验和
存储在同一 HDFS
命名空间下的单独的隐藏文件中。当客户端检索文件内容时,它会验证从每个 DataNode
接收的数据是否与存储在关联校验和文件中的 校验和
匹配。如果匹配失败,则证明数据已经损坏,此时客户端会选择从其他 DataNode
获取该块的其他可用副本。
二、MapReduce
1. 基本流程
MapReduce
处理的流程如下:
- Input : 从
HDFS
上读取文本文件; - Splitting : 将文件按照行进行拆分,此时得到的
K1
行数,V1
表示对应行的文本内容; - Mapping : 自定义实现,对
splitting
拆分后的执行计算操作,即输入是一对<key , value>
值,经过Map
计算后输出一对<key , value>
值; - Shuffling:由于
Mapping
操作可能是在不同的机器上并行处理的,所以需要通过shuffling
将相同key
值的数据分发到同一个节点上去合并,这样才能统计出最终的结果; - Reducing : 对
shuffling
的结果进行进一步处理最终输出结果。
MapReduce
编程模型中 splitting
和 shuffing
操作都是由框架实现的,需要我们自己编程实现的只有 mapping
和 reducing
,这也就是 MapReduce
这个称呼的来源。
2. 基础概念
(1) Combiner
Combiner
是 Map
运算后的可选操作,它实际上是一个本地化的 Reduce
操作,它主要是在 Map
计算出中间文件后做一个简单的合并重复 key
值的操作。
例词频统计经过 Map
运算后结果如下:
// Map-1
{aa : 1}, {bb : 1}, {aa : 1}
// Map-2
{cc : 1}, {dd : 1}, {dd : 1}
// Combiner-1
{aa : 2}, {bb : 1}
// Combiner-2
{cc : 1}, {dd : 2}
(2) Partitioner
Partitioner
可以理解成分类器,将 Map
的输出按照 Key
值的不同分别分给对应的 Reducer
,支持自定义实现。通过 Partitioner
即可便捷实现将结果按照自定义的规则存储分类存储至不同的文件中。
3. Key Process
我们以 Hadoop1
为例,MapReduce
运行过程涉及以下几类关键进程:
(1) 数据应用进程
启动用户 MapReduce
程序的主入口,主要指定 Map
和 Reduce
类、输入输出文件路径等,并提交作业给 Hadoop
集群。
(2) JobTracker 进程
根据要处理的输入数据量启动相应数量的 map
和 reduce
进程任务,并管理整个作业生命周期的任务调度和监控。JobTracker
进程在整个 Hadoop
集群全局唯一。
(3) TaskTracker进程
负责启动和管理 map
和 reduce
进程。因为需要每个数据块都有对应的 map
函数,TaskTracker
进程通常和 HDFS
的 DataNode
进程启动在同一个服务器,也就是说,Hadoop
集群中绝大多数服务器同时运行 DataNode
进程和 TaskTacker
进程。
4. Running Process
具体作业启动和计算过程如下:
- 应用进程将用户作业
jar
包存储在HDFS
中,将来这些jar
包会分发给Hadoop
集群中的服务器执行MapReduce
计算。 - 应用程序提交
job
作业给JobTracker
。 JobTacker
根据作业调度策略创建JobInProcess
树,每个作业都会有一个自己的JobInProcess
树。JobInProcess
根据输入数据分片数目(通常情况就是数据块的数目)和设置的reduce
数目创建相应数量的TaskInProcess
。TaskTracker
进程和JobTracker
进程进行定时通信。- 如果
TaskTracker
有空闲的计算资源(空闲CPU核),JobTracker
就会给他分配任务。分配任务的时候会根据TaskTracker
的服务器名字匹配在同一台机器上的数据块计算任务给它,使启动的计算任务正好处理本机上的数据。 TaskRunner
收到任务后根据任务类型(map
还是reduce
),任务参数(作业jar
包路径,输入数据文件路径,要处理的数据在文件中的起始位置和偏移量,数据块多个备份的DataNode主机名等)启动相应的map
或reduce
进程map
或reduce
程序启动后,检查本地是否有要执行任务的jar
包文件,如果没有就去HDFS
下载,然后加载map
或reduce
代码开始执行。- 如果是
map
进程,从HDFS
读取数据(通常要读取的数据块正好存储在本机),如果是reduce
进程,将结果数据写出到 HDFS。
三、YARN
Apache YARN(Yet Another Resource Negotiator)
是 hadoop 2.0
引入的集群资源管理系统,用户可以将各种服务框架部署在 YARN
上,由 YARN
进行统一地管理和资源分配。
1. ResourceManager
ResourceManager
通常在独立的机器上以后台进程的形式运行,它是整个集群资源的主要协调者和管理者。
ResourceManager
主要职能为负责给用户提交的所有应用程序分配资源,根据应用程序优先级、队列容量、ACLs
、数据位置等信息,做出决策,然后以共享的、安全的、多租户的方式制定分配策略,调度集群资源。
2. NodeManager
NodeManager
是 YARN
集群中的每个具体节点的管理者,主要负责该节点内所有容器的生命周期的管理,监视资源和跟踪节点健康,具体如下:
- 启动时向
ResourceManager
注册并定时发送心跳消息,等待ResourceManager
的指令; - 维护
Container
的生命周期,监控Container
的资源使用情况;
管理任务运行时的相关依赖,根据ApplicationMaster
的需要,在启动Container
之前将需要的程序及其依赖拷贝到本地。
3. ApplicationMaster
在用户提交一个应用程序时,YARN
会启动一个轻量级的进程 ApplicationMaster
。
ApplicationMaster
负责协调来自 ResourceManager
的资源,并通过 NodeManager
监视容器内资源的使用情况,同时还负责任务的监控与容错,具体如下:
- 根据应用的运行状态来决定动态计算资源需求;
- 向
ResourceManager
申请资源,监控申请的资源的使用情况; - 跟踪任务状态和进度,报告资源的使用情况和应用的进度信息;
- 负责任务的容错。
4. Container
Container
是 YARN
中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU
、磁盘、网络等。当 AM
向 RM
申请资源时,RM
为 AM
返回的资源是用 Container
表示的。
YARN
会为每个任务分配一个 Container
,该任务只能使用该 Container
中描述的资源。ApplicationMaster
可在 Container
内运行任何类型的任务。例如,MapReduce ApplicationMaster
请求一个容器来启动 map
或 reduce
任务,而 Giraph ApplicationMaster
请求一个容器来运行 Giraph
任务。
参考链接: