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 任务。
参考链接: