框架通用流程:
聚合和排序是可选的。
map分区标记就是在
每个partition都有个buffer,输出到一个分区文件(本地磁盘),最后合并为一个文件。
优点:速度很快。
缺点:partition过多,buffer就越多,内存消耗过大,并且输出的分区文件很多。
常见的算子有:groupByKey(100),partitionBy(100),sortByKey(100)。分区数较少,默认分区上限参数为200
排序过程需要Array数组(PartitonPairBuffer)来进行排序。 可以扩容和spill到磁盘,spill到磁盘的多个文件再进行全局排序(一个map task的排序),结果输出到磁盘。
这个可以解决第一种类型的缺点,排序后可直接写入一个文件。
常见的算子有:groupByKey(300),partitionBy(300),sortByKey(300)。分区数较多
spark暂时并没有实现这个排序的数据操作,用户可自定义。
聚合过程需要类似HashMap的数据结构来进行聚合。
HashMap的key是 “partitionId+key” 。
比如reduceByKey()进行sum()操作。
有两种聚合方式:
1.两步聚合,全部存在list中再func ,占用内存比较大。
2.在线聚合,每个record加入HashMap就进行func操作。
排序,再用Array数组。
spark使用了特殊设计的HashMap,即PartitionAppendOnlyMap,可同时聚合和排序。
框架通用流程:
聚合和排序是可选的。
从各个map task中获取一种分区的数据,输出到buffer中,再从buffer中获取数据。
优点:简单。
适用算子:partitionBy()
排序过程需要Array数组(PartitonPairBuffer)来进行排序。 可以扩容和spill到磁盘,spill到磁盘的多个文件再进行全局排序。
适用算子:sortByKey()
spark使用了特殊设计的HashMap,即ExternalAppendOnlyMap,可同时聚合和排序。
和map端的聚合的PartitionAppendOnlyMap不同,ExternalAppendOnlyMap不包含Partition信息。
AppendOnlyMap就是只支持添加和更新的HashMap。
HashMap基于数组+链表,AppendOnlyMap只基于数组( Array[(K, V)] )。
扩容:利用率达到70%,扩大一倍,因此所有key需要rehash。
排序:将所有
AppendOnlyMap只支持内存,ExternalAppendOnlyMap支持内存+磁盘。
ExternalAppendOnlyMap就是靠AppendOnlyMap和磁盘来解决问题。
全局聚合:最小堆进行多路归并。
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() 先聚合,再排序