火花中的flatMap会导致洗牌吗



flatMap在spark中的行为是否与map函数类似,因此不会导致混洗,或者它是否会触发混洗。我怀疑它确实会引起洗牌。有人能证实吗?

map或flatMap都没有混洗。导致混洗的操作有:

  • 重新分区操作:
    • 重新分区:
    • 聚结物:
  • ByKey操作(计数除外):
    • 按键分组:
    • ReduceByKey:
  • 加入操作:
    • Cogroup:
    • 加入:

尽管新混洗数据的每个分区中的元素集是确定的,分区本身的排序也是确定的,但这些元素的排序不是。如果一个人希望在洗牌后得到可预测的有序数据,那么可以使用:

  • mapPartitions使用例如.sorted对每个分区进行排序
  • repartitionAndSortWithinPartitions可在重新分区的同时对分区进行高效排序
  • sortBy生成全局排序的RDD

更多信息请点击此处:http://spark.apache.org/docs/latest/programming-guide.html#shuffle-操作

无混洗。以下是两种功能的来源:

/**
 * Return a new RDD by applying a function to all elements of this RDD.
 */
def map[U: ClassTag](f: T => U): RDD[U] = withScope {
  val cleanF = sc.clean(f)
  new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
}
/**
 *  Return a new RDD by first applying a function to all elements of this
 *  RDD, and then flattening the results.
 */
def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U] = withScope {
  val cleanF = sc.clean(f)
  new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF))
}

正如您所看到的,RDD.flatMap只是在Scala的迭代器上调用代表分区的flatMap

flatMap在某些情况下可能会导致无序写入。比如,如果你在同一个分区中生成多个元素,而这个元素不能放在同一分区中,那么它会将这些元素写入不同的分区。

如以下示例:

val rdd = RDD[BigObject]
rdd.flatMap{ bigObject => 
    val rangList: List[Int] = List.range(1, 1000)
    rangList.map( num => (num, bigObject))
}

上面的代码将在同一个分区上运行,但由于我们创建了太多BigObject实例,它将把这些对象写入单独的分区,这将导致无序写入