Hadoop总结
Hadoop提供了一套分布式系统基础架构。 核心内容包含hdfs和mapreduce。hadoop2.0 以后引入yarn. hdfs是提供数据存储的,mapreduce是方便数据计算的。
- hdfs 又对应 namenode 和 datanode. namenode 负责保存元数据的基本信息,datanode 直接存放数据本身;
- mapreduce 对应 jobtracker 和 tasktracker. jobtracker 负责分发任务,tasktracker 负责执行具体任务;
- 对应到 master/slave 架构,namenode 和 jobtracker 就应该对应到 master, datanode和 tasktracker 就应该对应到 slave.
注意:HDFS分布式存储系统,支持顺序读写MapReduce用于离线批量计算,不支持实时计算,且基于磁盘计算,即在数据处理过程中将数据写到磁盘中,处理结束后写到分布式存储系统中YARN资源管理和调度器
概念
面向批处理的分布式计算框架;
一种编程模型:MapReduce程序被分为Map(映射)阶段和Reduce(化简)阶段
核心思想
分而治之,并行计算
移动计算,而非移动数据
1 HDFS
1.1 Client
Client(代表用户) 通过与NameNode和DataNode交互访问HDFS中的文件。 Client提供了一个类似POSIX的文件系统接口供用户调用。
1.2 NameNode
整个Hadoop集群中只有一个NameNode。 它是整个系统的“ 总管”, 负责管理HDFS的目录树和相关的文件元数据信息。 这些信息是以“ fsimage”( HDFS 元数据镜像文件)和“ editlog”(HDFS 文件改动日志)两个文件形式存放在本地磁盘,当 HDFS 重启时重新构造出来的。此外, NameNode 还负责监控各个DataNode的健康状态, 一旦发现某个DataNode宕掉,则将该 DataNode 移出 HDFS 并重新备份其上面的数据。
1.3 Secondary NameNode
Secondary NameNode最重要的任务并不是为NameNode元数据进行热备份, 而是定期合并fsimage和edits日志, 并传输给NameNode。 这里需要注意的是,为了减小NameNode压力, NameNode自己并不会合并fsimage和edits, 并将文件存储到磁盘上, 而是交由Secondary NameNode完成。
1.4 DataNode
一般而言, 每个Slave节点上安装一个DataNode, 它负责实际的数据存储, 并将数据信息定期汇报给NameNode。 DataNode 以固定大小的block为基本单位组织文件内容, 默认情况下block大小为64MB。 当用户上传一个大的文件到HDFS上时, 该文件会被切分成若干个block,分别存储到不同的DataNode ; 同时,为了保证数据可靠, 会将同一个block以流水线方式写到若干个(默认是3,该参数可配置)不同的DataNode上。 这种文件切割后存储的过程是对用户透明的。
1.5 HDFS的读数据流程
1.6 HDFS的写数据流程
2 MapReduce
同 HDFS 一样,Hadoop MapReduce 也采用了Master/Slave(M/S)架构,具体如图所示。它主要由以下几个组件组成:Client、JobTracker、TaskTracker 和 Task。 下面分别对这几个组件进行介绍。
2.1 Client
用户编写的 MapReduce 程序通过Client提交到 JobTracker端; 同时, 用户可通过Client提供的一些接口查看作业运行状态。 在Hadoop内部用“作业”(Job)表示MapReduce程序。
一个 MapReduce 程序可对应若干个作业,而每个作业会被分解成若干个 Map/Reduce 任务(Task)。
2.2 JobTracker
JobTracker 主要负责资源监控和作业调度。JobTracker 监控所有 TaskTracker 与作业的健康状况,一旦发现失败情况后,其会将相应的任务转移到其他节点;同时 JobTracker 会跟踪任务的执行进
度、资源使用量等信息,并将这些信息告诉任务调度器,而调度器会在资源出现空闲时,选择合适的任务使用这些资源。在 Hadoop 中,任务调度器是一个可插拔的模块,用户可以根据自己的需要设计相应的调度器。
2.3 TaskTracker
TaskTracker 会周期性地通过 Heartbeat 将本节点上资源的使用情况和任务的运行进度汇报给JobTracker, 同时接收 JobTracker 发送过来的命令并执行相应的操作(如启动新任务、 杀死任务等)。TaskTracker 使用“slot” 等量划分本节点上的资源量。“slot” 代表计算资源(CPU、内存等)。一个 Task 获取到一个 slot 后才有机会运行,而 Hadoop 调度器的作用就是将各个TaskTracker 上的空闲 slot 分配给 Task 使用。 slot 分为 Map slot 和 Reduce slot 两种,分别供MapTask 和 Reduce Task 使用。 TaskTracker 通过 slot 数目(可配置参数)限定 Task 的并发度。
2.4 Task
Task 分为 Map Task 和 Reduce Task 两种, 均由 TaskTracker 启动。 HDFS 以固定大小的 block 为基本单位存储数据, 而对于 MapReduce 而言, 其处理单位是 split。split 与 block 的对应关系如图所示。 split 是一个逻辑概念, 它只包含一些元数据信息, 比如数据起始位置、数据长度、数据所在节点等。它的划分方法完全由用户自己决定。 但需要注意的是,split 的多少决定了 Map
Task 的数目 ,因为每个 split 会交由一个 Map Task 处理。
Map Task 执行过程如图所示。 由该图可知,Map Task 先将对应的 split 迭代解析成一个个key/value 对,依次调用用户自定义的 map() 函数进行处理,最终将临时结果存放到本地磁盘上,其中临时数据被分成若干个 partition,每个 partition 将被一个 Reduce Task 处理。
2.5 Reduce Task 执行过程
该过程分为三个阶段
- 从远程节点上读取 MapTask 中间结果(称为“Shuffle 阶段”);
- 按照 key 对 key/value 对进行排序(称为“ Sort 阶段”);
- 依次读取<key, value list>,调用用户自定义的 reduce() 函数处理,并将最终结果存到 HDFS
上(称为“ Reduce 阶段”)。
2.6 Hadoop MapReduce 作业的生命周期
1.作业提交与初始化
- 用户提交作业后, 首先由 JobClient 实例将作业相关信息, 比如将程序 jar 包、作业配置文件、 分片元信息文件等上传到分布式文件系统( 一般为 HDFS)上,其中,分片元信息文件记录了每个输入分片的逻辑位置信息。 然后 JobClient 通过 RPC 通知 JobTracker。JobTracker 收到新作业提交请求后, 由 作业调度模块对作业进行初始化:为作业创建一个JobInProgress 对象以跟踪作业运行状况, 而 JobInProgress 则会为每个 Task 创建一个TaskInProgress 对象以跟踪每个任务的运行状态, TaskInProgress 可能需要管理多个“ Task 运行尝试”( 称为“ Task Attempt”)。
2.任务调度与监控。 - 前面提到,任务调度和监控的功能均由 JobTracker 完成。TaskTracker 周期性地通过Heartbeat 向 JobTracker 汇报本节点的资源使用 情况, 一旦出 现空闲资源, JobTracker 会按照一定的策略选择一个合适的任务使用该空闲资源, 这由任务调度器完成。 任务调度器是一个可插拔的独立模块, 且为双层架构, 即首先选择作业, 然后从该作业中选择任务, 其中,选择任务时需要重点考虑数据本地性。 此外,JobTracker 跟踪作业的整个运行过程,并为作业的成功运行提供全方位的保障。 首先, 当 TaskTracker 或者 Task 失败时, 转移计算任务 ; 其次, 当某个 Task 执行进度远落后于同一作业的其他 Task 时,为之启动一个相同Task, 并选取计算快的 Task 结果作为最终结果。
3.任务运行环境准备 - 运行环境准备包括 JVM 启动和资源隔 离, 均由 TaskTracker 实现。 TaskTracker 为每个Task 启动一个独立的 JVM 以避免不同 Task 在运行过程中相互影响 ; 同时,TaskTracker 使用了操作系统进程实现资源隔离以防止 Task 滥用资源。
4.任务执行 - TaskTracker 为 Task 准备好运行环境后, 便会启动 Task。 在运行过程中, 每个 Task 的最新进度首先由 Task 通过 RPC 汇报给 TaskTracker, 再由 TaskTracker 汇报给 JobTracker。
5.作业完成。 - 待所有 Task 执行完毕后, 整个作业执行成功。
2.6 MapReduce 的 Shuffle 过程及 Hadoop 优化
Shuffle机制
1)Map 方法之后 Reduce 方法之前这段处理过程叫 Shuffle
2)Map 方法之后,数据首先进入到分区方法,把数据标记好分区,然后把数据发送到 环形缓冲区;环形缓冲区默认大小 100m,环形缓冲区达到 80%时,进行溢写;溢写前对数 据进行排序,排序按照对 key 的索引进行字典顺序排序,排序的手段快排;溢写产生大量溢 写文件,需要对溢写文件进行归并排序;对溢写的文件也可以进行 Combiner 操作,前提是 汇总操作,求平均值不行。最后将文件按照分区存储到磁盘,等待 Reduce 端拉取。
3)每个 Reduce 拉取 Map 端对应分区的数据。拉取数据后先存储到内存中,内存不够 了,再存储到磁盘。拉取完所有数据后,采用归并排序将内存和磁盘中的数据都进行排序。 在进入 Reduce 方法前,可以对数据进行分组操作。
Hadoop 优化
0)HDFS 小文件影响
(1)影响 NameNode 的寿命,因为文件元数据存储在 NameNode 的内存中
(2)影响计算引擎的任务数量,比如每个小的文件都会生成一个 Map 任务
1)数据输入小文件处理:
(1)合并小文件:对小文件进行归档(Har)、自定义 Inputformat 将小文件存储成 SequenceFile 文件。
(2)采用 ConbinFileInputFormat 来作为输入,解决输入端大量小文件场景。 (3)对于大量小文件 Job,可以开启 JVM 重用。
2)Map 阶段
(1)增大环形缓冲区大小。由 100m 扩大到 200m
(2)增大环形缓冲区溢写的比例。由 80%扩大到 90%
(3)减少对溢写文件的 merge 次数。
(4)不影响实际业务的前提下,采用 Combiner 提前合并,减少 I/O。
3)Reduce 阶段
(1)合理设置 Map 和 Reduce 数:两个都不能设置太少,也不能设置太多。太少,会 导致 Task 等待,延长处理时间;太多,会导致 Map、Reduce 任务间竞争资源,造成处理超 时等错误。
(2)设置 Map、Reduce 共存:调整 slowstart.completedmaps 参数,使 Map 运行到一定 程度后,Reduce 也开始运行,减少 Reduce 的等待时间。
(3)规避使用 Reduce,因为 Reduce 在用于连接数据集的时候将会产生大量的网络消 耗。
(4)增加每个 Reduce 去 Map 中拿数据的并行数
(5)集群性能可以的前提下,增大 Reduce 端存储数据内存的大小。
4)IO 传输
(1)采用数据压缩的方式,减少网络 IO 的的时间。安装 Snappy 和 LZOP 压缩编码器。
(2)使用 SequenceFile 二进制文件
5)整体
(1)MapTask 默认内存大小为 1G,可以增加 MapTask 内存大小为 4-5g
(2)ReduceTask 默认内存大小为 1G,可以增加 ReduceTask 内存大小为 4-5g
(3)可以增加 MapTask 的 cpu 核数,增加 ReduceTask 的 CPU 核数
(4)增加每个 Container 的 CPU 核数和内存大小
(5)调整每个 Map Task 和 Reduce Task 最大重试次数