一个例子让你了解MapReduce中shuffle的过程

Shuffle

目录
  一 .Shuffle基本概念
  二 .MapReduce 过程为什么需要shuffle过程呢?
  三 .Combiner
    1 Combiner对系统的优化
  四 .Partitioner
    1 用数据分区解决数据相关性问题
    2 Partitioner主要作用
  五 .Shuffle过程的期望
  六 .Sort
  七 .Merge
  
  四 .总结

Shuffle基本概念

  Shuffle的本义是洗牌、混洗,把一组有一定规则的数据尽量转换成一组无规则的数据,越随机越好。MapReduce中的Shuffle更像是洗牌的逆过程,把一组无规则的数据尽量转换成一组具有一定规则的数据。

MapReduce 过程为什么需要shuffle过程呢?

  我们都知道MapReduce计算模型一般包括两个重要的阶段:Map是映射,负责数据的过滤分发;Reduce是规约,负责数据的计算归并。Reduce的数据来源于Map,Map的输出即是Reduce的输入,Reduce需要通过Shuffle来获取数据。Map和Reduce输出的个格式都是一致,但是我们Reduce的输入可能和Map的输出不一样,这时候需要shuffle聚集处理,完成Reduce的输入格式。
  广义来说:Map的输出到Reduce输入这段称为shuffle过程,由hadoop默认执行,中间执行步骤有Combiner和Partitioner,sort和Merge。如下图:

一个例子让你了解MapReduce中shuffle的过程_第1张图片

Combiner

  • 一个可选的本地reducer,可以在map阶段聚合数据
  • 可以明显减少通过网络传输的数据量
  • 使用combiner可以产生特别大的性能提升,并且没有副作用
  • 不能保证执行,不能作为整个算法的一部分
  • 并不是所有情况下都能使用combiner,combiner使用于对记录汇总的场景(如求和,但是求平均数的场景就不能使用了

Combiner对系统的优化
问题:大量的键值对数据在传送给Reduce节点时会引起较大的通信带宽开销。
解决方案:
  每个Map节点处理完成的中间键值队将由combiner做一个合并压缩,即把那些键名相同的键值对归并为一个键名下的一组数值。
  一个例子让你了解MapReduce中shuffle的过程_第2张图片

Partitioner

  • 将mapper(如果使用了combiner就是combiner)输出的键/值对拆分为分片(shard),每个reducer对应一个分片。
  • (1)partitioner组件可以让Map对Key进行分区,从而可以根据不同的key来分发到不同的reduce中去处理;
  • (2)你可以自定义key的一个分发股则,如数据文件包含不同的省份,而输出的要求是每个省份输出一个文件;
  • (3)提供了一个默认的HashPartitioner。

用数据分区解决数据相关性问题
问题:
  一个Reduce节点上的计算数据可能会来自多个Map节点,因此,为了在进入Reduce节点计算之前,需要把属于一个Reduce节点的数据归并到一起。

解决方按:
  在Map阶段进行了Combining以后,可以根据一定的策略对Map输出的中间结果进行分区(partitioning),这样既可解决以上数据相关性问题避免Reduce计算过程中的数据通信。

例如:
  有一个巨大的数组,其最终结果需要排序,每个Map节点数据处理好后,为了避免在每个Reduce节点本地排序完成后还需要进行全局排序,我们可以使用一个分区策略如:(d%R),d为数据大小,R为Reduce节点的个数,则可根据数据的大小将其划分到指定数据范围的Reduce节点上,每个Reduce将本地数据排好序后即为最终结果。
  
Partitioner主要作用:
就是将map的结果发送到相应的reduce。这就对partitioner有两个要求:
  1)均衡负载,尽量的将工作均匀的分配给不同的reduce。
  2)效率,分配速度一定要快。

Shuffle过程的期望

  • 完整地从map task端拉取数据到reduce 端。
  • 在跨节点拉取数据时,尽可能地减少对带宽的不必要消耗。
  • 减少磁盘IO对task执行的影响。

Shuffle描述着数据从map task输出到reduce task输入的这段过程。

每个map task都有一个 内存缓冲区,存储着map的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,生成最终的正式输出文件,然后等待reduce task来拉数据。

Sort

  先把 缓冲区中的数据按照partition值和key两个关键字升序排序,移动的只是索引数据,排序结果是Kvmeta中数据按照partition为单位聚集在一起,同一partition内的按照key有序。

Merge

  对于数据量非常大,Map task的内存缓冲区不够,达到一定容量时候,就要把内存缓冲区的内容写入out文件。
  对于很多out文件,此时Merge就闪亮登场了。
  然后为merge过程创建一个叫file.out的文件和一个叫file.out.Index的文件用来存储最终的输出和索引。
  根据file.out.index文件和file.out文件提供out文件的路径和索引,指出之前内存缓存区写出的out文件结果进行扫描。
  最后一个partition一个partition的进行合并输出。对于某个partition来说,从索引列表中查询这个partition对应的所有索引信息,每个对应一个段插入到段列表中。也就是这个partition对应一个段列表,记录所有的Spill文件中对应的这个partition那段数据的文件名、起始位置、长度等等。
  

你可能感兴趣的:(MapReduce编程)