性能影响
混洗(Shuffle)是一个昂贵的操作,因为它会引发磁盘I/O,数据序列化,和网络I/O。对于混洗,要组织数据,Spark产生任务集合--map任务来组织数据,且一组reduce任务集合来聚合这些数据。这个术语来自MapReduce,与Spark的map和reduce没有直接关系。
在内部,各个map任务的结果是保存在内存中,直到不能填充(像在Hadoop中的话,它是有个阈值的,达到这个阈值的话,就溢写到磁盘)。然后,这些结果基于目标分区排好序并且写到一个文件中。在reduce端,任务读取相关的已排序的数据块。
特定的混洗操作会消耗大量的堆内存,因为传输记录之前或之后,他们要使用内存数据结构来组织他们。尤其是,reduceByKey
和aggregateByKey
在map端创建这些数据结构,'ByKey操作是在reduce端产生这些结构。当数据不能往内存中填充时,Spark会溢写这些数据到磁盘,导致额外的磁盘I/O负担,及垃圾回收的增加。
混洗也会在磁盘上产生大量的中间文件,例如Spark1.3,这些文件会保存,直到相应的RDDs不再被使用,且已被垃圾回收。这样做,使得如果lineage被重新计算,混洗文件不需要重新创建。垃圾回收仅仅会发生在,如果这个应用保持对这些RDDs的引用或者GC很久没有进行,然后经过一个很长的时间之后。这意味着长运行时间的Spark作业可能消耗大量的磁盘空间。当配置了Spark context时,临时存储目录由spark.local.dir配置参数指定。
混洗行为能够通过調整各种配置参数来被調整,请看Spark配置指南的“混洗行为”部分。