Hadoop计算框架——MapReduce

前提是你 提交于 2020-02-27 15:00:41

MapReduce概述

MapReduce定义

MapReduce是一个分布式计算框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上

MapReduce的优缺点

优点:

易于编程:简单的实现了一些接口,就可以完成一个分布式程序。这个分布式程序可以分布到大量廉价的PC机上运行。

良好的扩展性:当机器资源不足时,可以通过简单的增加机器来扩展它的计算能力。

高容错性:MapReduce有很好的容错性。比如其中一台机器挂掉,它就可以把计算任务转移到另外一个节点上运行,不至于这个任务运行失败,而且这个过程完全是由Hadoop内部完成的。

适合PB级以上的海量数据的离线处理:可以实现在上千台服务器上并发完成任务,提供数据处理能力。

缺点:

不擅长实时计算:无法像MySQL那样可以在毫秒级或秒级内返回结果。

不擅长流式处理:流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化。

不擅长DAG(有向图)计算:多个应用程序存在依赖关系,后一个应用程序的输入为前一个应用程序的输出。在这种情况下,MapReduce并不能这样做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能十分低下。

MapReduce的核心思想——shuffle过程

 

  • Map阶段的shuffle
Map的输出结果会先写入环形缓冲区,缓存中的数据会进行分区、排序和合并,当缓存达到溢写比后会写出为磁盘文件,在Map任务结束之前会将多个溢写文件合并为一个大文件,通知对应的Reduce任务进行处理。
Map端会处理数据并产生中间结果 这个中间的结果会写入磁盘, 每次从split的数据中写入到map中,map处理一行数据之后的k v 值都会先放入kvbuffer中缓存 kvbuffer会根据k v的顺序进行分区(partition), 每个分区中的数据再按照k进行排序 在kvbuffer中写入的数据达到阈值时,数据开始往磁盘转移 这个过程叫做溢写(spill),在spill写入之前,会有第二次的排序,根据数据所属的partition进行排序,每个partition中的数据再根据key来排序,接着运行combiner,combiner也称作map层的reduce,目的是对将要写入磁盘的文件进行一次处理,这样写入磁盘的数据量就会减少,最后将数据写到本地磁盘产生spill文件,每个map会产生多个spill文件,每个map任务结束前,会通过归并算法将这些spill文件归并成一个文件。
  • Reduce阶段的shuffle
从不同的Map处获取任务数据后放入缓冲区进行归并和合并操作,最后交给reduce函数处理
从每个map节点把map处理后的数据复制到reduce节点上,(因为在map阶段进行partition时,就相当于指定了每个reduce要处理的数据 partition对应了reduce,所以reduce在复制是 会复制自己所对应的partition中的数据)把拿到的结果按照k进行一次归并处理,这个过程就会产生最终的结果,把结果放入hdfs即可

 

MapReduce优化

程序运行慢的原因

  1. 计算机性能:CPU、内存、磁盘、网络等
  2. I/O操作优化
    1. 数据倾斜
    2. Map和Reduce数设置不合理
    3. Map运行时间过长,导致Reduce等待过久
    4. 小文件过多
    5. 大量的不可分块的超大文件
    6. Split次数过多
    7. Merge次数过多

优化方法

数据输入

  1. 合并小文件:在执行MR任务前将小文件进行合并,大量的小文件会产生大量的Map任务,增大Map任务装载次数,而任务的装载比较耗时,从而导致MR运行较慢。
  2. 采用CombineTextInputFormat作为输入,解决输入端大量小文件场景。

Map阶段

  1. 减少溢写(spill)次数:通过调整io.sort.mbsort.spill.percent参数值,增大触发Spill内存上限,减少Spill次数,从而减少磁盘IO。
  2. 减少合并(Merge)次数:通过调整io.sort.factor参数,增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间。
  3. 在Map之后,不影响业务逻辑前提下,先进行Combine处理,减少I/O。

Reduce阶段

  1. 合理设置Map和Reduce数:两个都不能设置太少,也不能设置太多。太少会导致Task等待,延长处理时间;太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。
  2. 设置Map、Reduce共存:调整slowstart.completedmaps参数,使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间。
  3. 规避使用Reduce:因为Reduce在用于连接数据集市会产生大量的网络消耗。
  4. 合理设置Reduce端的Buffer:默认情况下,数据达到一个阈值时,Buffer中数据就会写入磁盘,然后Reduce会从磁盘中获取所有的数据。也就是说Buffer和Reduce是没有直接关系的,但是中间会有多次写磁盘->读磁盘的过程,会造成I/O消耗,可以设置。mapreduce.reduce.input.buffer.percent参数来设置。默认为0.0。当大于0时会保留指定比例的内存读Buffer中的数据直接拿给Reduce使用。这样一来,设置Buffer需要内存,读取数据需要内存,Reduce计算也需要内存,所以根据作业运行情况进行调整。

IO传输

  1. 采用数据压缩的方式,减少网络IO的时间,安装Snappy和LZO压缩编码器
  2. 使用SequenceFile二进制文件

常用的调优参数

(1)以下参数是在用户自己的 MR 应用程序中配置就可以生效(mapred-default.xml)

配置参数
参数说明
mapreduce.map.memory.mb
一 个 MapTask 可 使 用 的 资 源 上 限 ( 单 :MB), 默认为 1024 。如果 MapTask 实际 使用的资源量超过该值,则会被强制杀死。
mapreduce.reduce.memory.mb
一个 ReduceTask 可使用的资源上限(单:MB),默认为 1024。如果 ReduceTask实际使用的资源量超过该值,则会被强制杀死。
mapreduce.map.cpu.vcores
每个 MapTask 可使用的最多 cpu core 数目, 默认值 : 1
mapreduce.reduce.cpu.vcores
每个 ReduceTask 可使用的最多 cpu core 目,默认值 : 1
mapreduce.reduce.shuffle.parallelcopies
每个 Reduce Map 中取数据的并行数。默 认值是 5
mapreduce.reduce.shuffle.merge.percent
Buffer 中的数据达到多少比例开始写入磁 盘。默认值 0.66
mapreduce.reduce.shuffle.input.buffer.perce nt
Buffer 大小占 Reduce 可用内存的比例。默 认值 0.7
mapreduce.reduce.input.buffer.percent
指定多少比例的内存用来存放 Buffer 中的 数据默认值是 0.0

(2)应该在 YARN 启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)

配置参数 参数说明
yarn.scheduler.minimum-allocation-mb
给应用程序 Container 分配的最小内存,默 认值: 1024
yarn.scheduler.maximum-allocation-mb
给应用程序 Container 分配的最大内存,默 认值: 8192
yarn.scheduler.minimum-allocation-vcores
每个 Container 申请的最小 CPU 核数,默认 值: 1
yarn.scheduler.maximum-allocation-vcores
每个 Container 申请的最大 CPU 核数,默认 值: 32
yarn.nodemanager.resource.memory-mb
Containers 分配的最大物理内存,默认 值: 8192

(3)Shuffle 性能优化的关键参数,应在 YARN 启动之前就配置好(mapred-default.xml)

配置参数
参数说明
mapreduce.task.io.sort.mb
Shuffle 的环形缓冲区大小,默认 100m
mapreduce.map.sort.spill.percent
环形缓冲区溢出的阈值,默认 80%

容错相关参数(MapReduce 性能优化)

配置参数
参数说明
mapreduce.map.maxattempts
每个 Map Task 最大重试次数,一旦重试参数超过该值, 则认为 Map Task 运行失败,默认值: 4
mapreduce.reduce.maxattempts
每个 Reduce Task 最大重试次数,一旦重试参数超过该 值,则认为 Map Task 运行失败,默认值: 4
mapreduce.task.timeout
Task 超时时间,经常需要设置的一个参数,该参数表 达的意思为:如果一个 Task 在一定时间内没有任何进 入,即不会读取新的数据,也没有输出数据,则认为 Task 处于 Block 状态,可能是卡住了,也许永远会 卡住,为了防止因为用户程序永远 Block 住不退出, 则强制设置了一个该超时时间(单位毫秒),默认是 600000。 如果你的程序对每条输入数据的处理时间过 长(比如会访问数据库,通过网络拉取数据等),建 议将该参数调大,该参数过小常出现的错误提示是 AttemptID:attempt_14267829456721_123456_m_00 0224_0 Timed out after 300 secsContainer killed by the  ApplicationMaster. ”。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!