我正在阅读Spark的源代码,在其shuffle实现中发现,在shuffle读取期间,当调用BlockStoreShuffleReader.read
时,它将首先使用ExternalAppendOnlyMap
进行聚合
def combineValuesByKey(
iter: Iterator[_ <: Product2[K, V]],
context: TaskContext): Iterator[(K, C)] = {
val combiners = new ExternalAppendOnlyMap[K, V, C](createCombiner, mergeValue, mergeCombiners)
combiners.insertAll(iter)
updateMetrics(context, combiners)
combiners.iterator
}
然后,它将使用ExternalSorter
进行排序和汇总。因此,这里会有很多磁盘溢出/读取工作。
val resultIter = dep.keyOrdering match {
case Some(keyOrd: Ordering[K]) =>
// Create an ExternalSorter to sort the data.
val sorter =
new ExternalSorter[K, C, C](context, ordering = Some(keyOrd), serializer = dep.serializer)
...
我的问题是为什么我们同时需要ExternalSorter
和ExternalAppendOnlyMap
?我们有可能将这两部分合而为一吗?
我的意思是它们的代码看起来非常相似,为什么我们所有人都不能使用ExternalSorter
而不是ExternalAppendOnlyMap
?因为它既可以汇总又可以排序?
答案 0 :(得分:0)
免责声明,我现在只是在探索Spark Core的这一部分,因此我的理解可能完全不正确。
我的理解是ExternalAppendOnlyMap
只是一个可溢出的尺寸跟踪的仅附加图,而ExternalSorter
可以是缓冲区或地图(基于地图侧部分值的地图侧合并标志)。
是否有可能将这两部分合而为一?
基于这一点,我认为他们有很多共同点,ExternalSorter
似乎更灵活(因为它可以完成ExternalAppendOnlyMap的工作)。
我认为您的问题的答案是“是”,但是很少有人勇敢或有足够的勇气来实施更改。