在spark DF中使用partitionBy之后是否可以进行重新分区?

时间:2019-02-08 07:09:53

标签: apache-spark apache-spark-sql

我之所以问这个问题,是因为如果我将重分区指定为5,那么我所有的数据(> 200Gigs)都会移到5个不同的执行器上,并且98%的资源未使用。然后partitionBy发生了,这又造成了很多洗牌。有没有一种方法,首先发生partitionBy,然后对数据运行重新分区?

2 个答案:

答案 0 :(得分:0)

尽管这个问题并不完全容易理解,但以下内容与其他答案一致,这种方法应避免在不必要的改组中提到的问题:

val n = [... some calculation for number of partitions / executors based on cluster config and volume of data to process ...]

df.repartition(n, $"field_1", $"field_2", ...)
  .sortWithinPartitions("fieldx", "field_y")
  .write.partitionBy("field_1", "field_2", ...)
  .format("location")

其中[field_1,field_2,...]是用于重新分区和partitionBy的同一组字段。

答案 1 :(得分:-1)

您可以使用repartition(5, col("$colName"))
因此,当您制作partitionBy("$colName")时,您将跳过'$colName'的随机播放,因为它已经被重新分区。

还要考虑分区的数量与执行程序数量乘以使用的内核数量乘以3的乘积相同(尽管这可能在2到4之间变化)。
因此,我们知道,Spark只能为RDD的每个分区运行1个并发任务。假设每个执行者有8个核心,而每个执行者有5个:
您需要具有:8 * 5 * 3 = 120个分区