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