MapTask与ReduceTask的并行度

240

1、MapTask

并行度:就是分布式集群运行了多少个任务

MapTask任务:说白了就是分而治之中的分了多少个小任务,类似于代码中map函数的调用次数,对原始数据进行任务划分,让不同的数据跑在不同的节点上。

MapTask的任务划分究竟与什么有关联?

在FileInputFormat类中有一个getSplits()方法,这个方法就是决定每个MapTask的任务划分

split概念;逻辑切片,只是进行一个逻辑划分并没有将真正的数据进行切分

一个MapTask最终对应到数据上就是对应一个切片:1个split--->1个MapTask--->1个Yarn

主要代码如下:

public List<InputSplit> getSplits(JobContext job) throws IOException {
        Stopwatch sw = (new Stopwatch()).start();
        long minSize = Math.max(this.getFormatMinSplitSize(), getMinSplitSize(job));
        long maxSize = getMaxSplitSize(job);
        List<InputSplit> splits = new ArrayList();
        List<FileStatus> files = this.listStatus(job);
        Iterator i$ = files.iterator();

这里逻辑切片大小应该是多少?

假设:切片大小为1G,那么在当我们计算任务数据的时候,将会从多个节点进行拉取

假设:切片大小为100M,会造成第一个计算任务取得的是第一个块0-100M之间的数据,第二个计算任务取得是101-200M,同样会造成跨数据块的读取,产生网络传输,性能比较慢

所以将切片大小设置为128M最合适

面试题:切片和块的关系?

没有实际的切分,一个是逻辑上的切分,一个是数据存储的物理划分,默认情况下切片大小和块大小一致。

2、ReduceTask

当数据量特别大的时候,如果计算只有一个reduce任务,只在一个节点上跑,其他节点没事干,导致集群性能不高,并且执行任务的节点压力过大

ReudceTask任务的并行度怎么设置?

job.setNumReduceTasks(3); 设置ReduceTask的个数,参数传入的代表最终启动的ReduceTask数量,生成的3个文件各自统计不同的key结果,最终3个文件合并在一起就是最终的统计结果,内部是MapReduce的默认分区(HashPartitioner)决定的,不同map输出的key进入到不同的reducetask中。

分区的作用仅仅是规划每个reducetask应该计算的数据范围

默认情况下:key.hashCode() & Integer.MAX_VALUE)% numReduceTasks

ReduceTask的并行度最终会影响到程序的总体执行效率,设计分区的时候一定要足够了解数据,如果设计不好,容易产生数据倾斜。