我有一个大型数据框,我用800个分区创建。
df.rdd.getNumPartitions()
800
当我在数据帧上使用dropDuplicates时,它会将分区更改为默认值200
df = df.dropDuplicates()
df.rdd.getNumPartitions()
200
这种行为会给我带来麻烦,因为它会导致内存不足。
您对修复此问题有什么建议吗?我尝试将spark.sql.shuffle.partition设置为800,但它不起作用。感谢
答案 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的缺点是它很慢。