spark的合并功能是否会尝试创建统一大小的分区?

时间:2016-12-08 09:40:03

标签: apache-spark

我想在Spark中平衡rdds / dataframes的分区大小,以摆脱拖延我的工作的落后任务。我可以使用repartition(n_partition)来创建,它创建了大小相当均匀的分区。然而,这涉及到昂贵的洗牌。

我知道coalesce(n_desired_partitions)是一种更便宜的替代品,它可以避免混乱,而是在同一个执行器上合并分区。但是,我不清楚这个函数是否试图创建大致统一大小的分区,或者简单地合并输入分区而不考虑它们的大小。

例如,让我们说以下三个分区中[1,12]范围内的整数的Rdd如下:[(1,2,3,4,5,6,7,8),(9,10),(11,12)]。让我们说这些都在同一个执行者身上。

现在我致电rdd.coalesce(2)。为coalesce提供动力的算法是否能够合并两个小分区(因为它们更小,我们想要平衡的分区大小),而不仅仅是合并两个任意分区?

在其他地方讨论此主题

根据this presentation(跳至7:27),Netflix大数据团队需要实施自定义的coalese功能来平衡分区大小。另请参阅SPARK-14042

为什么这个问题不重复

关于分区和合并here之间的差异有一个更普遍的问题,但是没有人能解释为coalesce提供动力的算法是否试图平衡分区大小。

1 个答案:

答案 0 :(得分:0)

所以实际上重新分配并不是它的def看起来像下面

def repartition(numPartitions: Int)(implicit ord: Ordering[T] = null): RDD[T] = withScope {
    coalesce(numPartitions, shuffle = true)
}

所以它简单地与shuffle合并,但是当调用coalesce时,它的shuffle将默认为false,因此它不会将数据洗牌直到它不需要。

示例你有2个集群节点,每个都有2个分区,现在你调用rdd.coalesce(2)所以它将合并节点的本地分区,或者如果你调用coalesce(1)那么它将需要shuffle因为其他2个分区将在另一个节点上,因此在您的情况下它可能会加入本地节点分区,并且该节点的分区数量较少,因此分区大小不均匀。

根据您对问题的编辑,我也尝试按照以下步骤进行操作

    val data = sc.parallelize(List(1,2,3,4,5,6,7,8,9,10,11,12))
    data.getNumPartitions
    res2: Int = 4
   data.mapPartitionsWithIndex{case (a,b)=>println("partitionssss"+a);b.map(y=>println("dataaaaaaaaaaaa"+y))}.count

上面代码的输出将是 enter image description here

现在我将4分区合并到2并在该rdd上运行相同的代码以检查优化spark如何合并数据以便输出

enter image description here

现在你可以很容易地看到,即使在合并它之前,火花也会将数据均等地分配到两个分区6-6,所有分区中的元素数量都不相同。

 val coal=data.coalesce(2)
 coal.getNumPartitions
res4: Int = 2
coal.mapPartitionsWithIndex{case (a,b)=>println("partitionssss"+a);b.map(y=>println("dataaaaaaaaaaaa"+y))}.count