Spark设计原理(一)——Shuffle机制

目录

  • 一.Shuffle Write框架
    • 1.不聚合,不排序(BypassMergeSortShuffleWriter)
    • 2.不聚合,但排序(SortShuffleWriter)
    • 3.聚合,排序或者不排序
  • 二.Shuffle Read框架
    • 1.不聚合,不按key排序
    • 2.不聚合,按key排序
    • 3.聚合,排序或者不排序
  • 三.支持高效聚合和排序的数据结构
  • 四.Spark和MapReduce的shuffle机制对比
  • 五.总结

一.Shuffle Write框架

框架通用流程:

map分区标记
聚合
排序
分区输出

聚合和排序是可选的。

map分区标记就是在 record上加上partition信息,变为

1.不聚合,不排序(BypassMergeSortShuffleWriter)

每个partition都有个buffer,输出到一个分区文件(本地磁盘),最后合并为一个文件。

优点:速度很快。
缺点:partition过多,buffer就越多,内存消耗过大,并且输出的分区文件很多。

常见的算子有:groupByKey(100),partitionBy(100),sortByKey(100)。分区数较少,默认分区上限参数为200

2.不聚合,但排序(SortShuffleWriter)

排序过程需要Array数组(PartitonPairBuffer)来进行排序。 可以扩容和spill到磁盘,spill到磁盘的多个文件再进行全局排序(一个map task的排序),结果输出到磁盘。

  • 只对partition排序

这个可以解决第一种类型的缺点,排序后可直接写入一个文件。
常见的算子有:groupByKey(300),partitionBy(300),sortByKey(300)。分区数较多

  • 对 (partition, key) 排序

record,变为<(partition,key),value> record。相当于进行双重排序。
spark暂时并没有实现这个排序的数据操作,用户可自定义。

3.聚合,排序或者不排序

聚合过程需要类似HashMap的数据结构来进行聚合。

HashMap的key是 “partitionId+key” 。
record 聚合成 。对list进行func操作。

比如reduceByKey()进行sum()操作。

有两种聚合方式:
1.两步聚合,全部存在list中再func ,占用内存比较大。
2.在线聚合,每个record加入HashMap就进行func操作。

排序,再用Array数组。

spark使用了特殊设计的HashMap,即PartitionAppendOnlyMap,可同时聚合和排序。

二.Shuffle Read框架

框架通用流程:

数据获取
聚合
排序
后续transformation

聚合和排序是可选的。

1.不聚合,不按key排序

从各个map task中获取一种分区的数据,输出到buffer中,再从buffer中获取数据。

优点:简单。
适用算子:partitionBy()

2.不聚合,按key排序

排序过程需要Array数组(PartitonPairBuffer)来进行排序。 可以扩容和spill到磁盘,spill到磁盘的多个文件再进行全局排序。

适用算子:sortByKey()

3.聚合,排序或者不排序

spark使用了特殊设计的HashMap,即ExternalAppendOnlyMap,可同时聚合和排序。

和map端的聚合的PartitionAppendOnlyMap不同,ExternalAppendOnlyMap不包含Partition信息。

三.支持高效聚合和排序的数据结构

AppendOnlyMap就是只支持添加和更新的HashMap。

HashMap基于数组+链表,AppendOnlyMap只基于数组( Array[(K, V)] )。

扩容:利用率达到70%,扩大一倍,因此所有key需要rehash。

排序:将所有 record移到数组前端(不留空隙),然后可以快排,按key值排序,比如聚合后需要排序的操作。对于其他操作,只需要按key的Hash排序即可,比如groupByKey()。

AppendOnlyMap只支持内存,ExternalAppendOnlyMap支持内存+磁盘。
ExternalAppendOnlyMap就是靠AppendOnlyMap和磁盘来解决问题。

全局聚合:最小堆进行多路归并。

四.Spark和MapReduce的shuffle机制对比

MapReduce的优点:
MapReduce是强制性按key排序,不管map端还是reduce端。原生支持sortByKey(),而且聚合操作,可以从前往后直接遍历,很高效。
MapReduce的缺点:
1.有些操作并不需要按key排序,如groupByKey()。
2.不能在线聚合,耗内存。从reduce函数可看出,函数参数是数组。(即先combine,再reduce)

spark改进:
1.提供按key排序,按partition排序多种方式。
2.基于hashMap,能够在线聚合。(比如reduceByKey(),groupByKey()不能。)

五.总结

mr强制按key排序,有聚合操作的话,就是先排序,然后聚合

spark可以不按key排序,不聚合:partitionBy()
不聚合,按key排序:sortByKey() 基于Array
聚合,不排序:reduceByKey() 基于HashMap
聚合,按key排序:rdd.reduceByKey().sortByKey() 先聚合,再排序

你可能感兴趣的:(#,Spark基础与问题解决,spark,大数据)