Hadoop-MapReduc入门(代码编写流程,运行流程,并行度决定机制)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qichangjian/article/details/87947129

1. MapReduce 的介绍:

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

MapReduce大体上分三个部分

  • MRAppMaster:MapReduce Application Master,分配任务,协调任务的运行
  • MapTask:阶段并发任务,负责 mapper 阶段的任务处理 YARNChild
  • ReduceTask:阶段汇总任务,负责 reducer 阶段的任务处理 YARNChild

2.MapReduce编写代码的流程:

用户编写的程序分成三个部分:Mapper,Reducer,Driver(提交运行 MR 程序的客户端)

  • Mapper 的输入数据是 KV 对的形式(KV 的类型可自定义)
  • Mapper 的输出数据是 KV 对的形式(KV 的类型可自定义)
  • Mapper 中的业务逻辑写在 map()方法中
  • map()方法(maptask 进程)对每一个<K,V>调用一次
  • Reducer 的输入数据类型对应 Mapper 的输出数据类型,也是 KV 对的形式
  • Reducer 的业务逻辑写在 reduce()方法中
  • Reducetask 进程对每一组相同 k 的<K,V>组调用一次 reduce()方法
  • 用户自定义的 Mapper 和 Reducer 都要继承各自的父类
  • 整个程序需要一个 Drvier 来进行提交,提交的是一个描述了各种必要信息的 job 对象

3.MapReduce 程序的运行流程:

  • 一个 mr 程序启动的时候,最先启动的是 MRAppMaster,MRAppMaster 启动后根据本次job 的描述信息,计算出需要的 maptask 实例数量,然后向集群申请机器启动相应数量的maptask 进程
  • maptask 进程启动之后,根据给定的数据切片(哪个文件的哪个偏移量范围)范围进行数据处理,主体流程为:
    • 利用客户指定的 InputFormat 来获取 RecordReader 读取数据,形成输入 KV 对
    • 将输入 KV 对传递给客户定义的 map()方法,做逻辑运算,并将 map()方法输出的 KV 对收集到缓存
    • 将缓存中的 KV 对按照 K 分区排序后不断溢写到磁盘文件
  • MRAppMaster 监控到所有 maptask 进程任务完成之后(真实情况是,某些 maptask 进程处理完成后,就会开始启动 reducetask 去已完成的 maptask 处 fetch 数据),会根据客户指定的参数启动相应数量的 reducetask 进程,并告知 reducetask 进程要处理的数据范围(数据分区)
  • Reducetask 进程启动之后,根据 MRAppMaster 告知的待处理数据所在位置,从若干台maptask 运行所在机器上获取到若干个 maptask 输出结果文件,并在本地进行重新归并排序,然后按照相同 key 的 KV 为一个组,调用客户定义的 reduce()方法进行逻辑运算,并收集运算输出的结果 KV,然后调用客户指定的 OutputFormat 将结果数据输出到外部存储

4.MapTask 并行度决定机制:

一个 job 的 map 阶段并行度客户端在提交 job 时决定.
客户端对 map 阶段并行度的规划的基本逻辑为:将待处理数据执行逻辑切片(即按照一个特定切片大小,将待处理数据划分成逻辑上的多个 split),然后每一个 split 分配一个 mapTask 并行实例处理。
这段逻辑及形成的切片规划描述文件,是由FileInputFormat实现类的getSplits()方法完成的,小编后续会对MPjob提交过程的源码进行详细的分析。
   决定map task的个数主要由这几个方面:
     - 文件的大小
     - 文件的个数
     - block的大小
     - 逻辑切片的大小
   总的来说就是,当对文件进行逻辑划分的时候,默认的划分规则就是一个split和一个block的大小一样,如果文件没有到一个block大小,也会被切分出来一个split,这里有调优点,就是如果处理的文件都是小文件的话,那么机会并行很多的maptask,导致大量的时间都浪费在了启动jvm上,此时可以通过合并小文件或者重用jvm的方式提高效率。

逻辑切片机制

long splitSize = computeSplitSize(blockSize, minSize, maxSize)
blocksize:默认是 128M,可通过 dfs.blocksize 修改
minSize:默认是 1,可通过 mapreduce.input.fileinputformat.split.minsize 修改
maxsize:默认是 Long.MaxValue,可通过mapreduce.input.fileinputformat.split.maxsize 修改

因此,如果是想调小split的大小,那么就将 maxsize调整到比block小。
如果是想调大split的大小,那么就将minSize调整到比block大。

5.ReduceTask 并行度决定机制:

reducetask 的并行度同样影响整个 job 的执行并发度和执行效率,但与 maptask 的并发数由切片数决定不同,Reducetask 数量的决定是可以直接手动设置:job.setNumReduceTasks(4);,默认是1个,如果设置为0个表示没有reduce阶段,当然也可以设置多个,根据需求,如果有些需要全局计数的操作,那么只能设置1个reduce,有些可以设置多个reducetask的,千万不要设置太多,最好设置的和分区的个数能一一对应,不然的会就会有一些reduceTask空跑,导致了不能处理业务而且还占用系统资源。

猜你喜欢

转载自blog.csdn.net/qichangjian/article/details/87947129