在数据帧中使用dropDuplicates会导致分区号

时间:2016-05-26 08:08:47

标签: apache-spark pyspark apache-spark-sql partitioning

我有一个大型数据框,我用800个分区创建。

df.rdd.getNumPartitions()
800

当我在数据帧上使用dropDuplicates时,它会将分区更改为默认值200

df = df.dropDuplicates()
df.rdd.getNumPartitions()
200

这种行为会给我带来麻烦,因为它会导致内存不足。

您对修复此问题有什么建议吗?我尝试将spark.sql.shuffle.partition设置为800,但它不起作用。感谢

2 个答案:

答案 0 :(得分:5)

这是因为dropDuplicates需要随机播放。如果要获取特定数量的分区,则应设置spark.sql.shuffle.partitions(其默认值为200)

df = sc.parallelize([("a", 1)]).toDF()
df.rdd.getNumPartitions()
## 8

df.dropDuplicates().rdd.getNumPartitions()
## 200

sqlContext.setConf("spark.sql.shuffle.partitions", "800")

df.dropDuplicates().rdd.getNumPartitions()
## 800

另一种方法(Spark 1.6+)首先要重新分配:

df.repartition(801, *df.columns).dropDuplicates().rdd.getNumPartitions()
## 801

它稍微灵活但效率较低,因为它不执行本地聚合。

答案 1 :(得分:0)

我在Removing duplicates from rows based on specific columns in an RDD/Spark DataFrame

找到了解决方案

使用reduceByKey而不是dropDuplicates。 reduceByKey还可以选择指定最终rdd的分区数。

在这种情况下使用reduceByKey的缺点是它很慢。