当我使用带有spark / scala的window.partitionBy()函数时,如何保持分区数不变?

时间:2017-06-07 08:01:16

标签: scala apache-spark apache-spark-sql

当我使用RDD时,我有一个RDD' partitionwindow结果更改为200,我使用partition时是否可以不更改window

这是我的代码:

val rdd= sc.parallelize(List(1,3,2,4,5,6,7,8),4)
val result = rdd.toDF("values").withColumn("csum", sum(col("values")).over(Window.partitionBy(col("values")))).rdd
println(result.getNumPartitions + "rdd2")

我的输入分区是4,为什么结果分区是200?

我希望我的结果分区也是4。

有没有更清洁的解决方案?

2 个答案:

答案 0 :(得分:3)

  

注意:如@eliasah所述 - 它是不可避免的   使用带有spark的窗口函数时的重新分区

  
      
  • 为什么结果分区是200?
  •   

Spark doc 默认值为spark.sql.shuffle.partitions 配置在为连接或聚合洗牌数据时要使用的分区数 - 是200

  
      
  • 我如何重新分配到4?
  •   

您可以使用:

coalesce(4)

repartition(4)

spark doc

coalesce(numPartitions)将RDD中的分区数减少为numPartitions。过滤大型数据集后,可以更有效地运行操作。

重新分区(numPartitions)随机重新调整RDD中的数据以创建更多或更少的分区并在它们之间进行平衡。这总是随机播放网络上的所有数据。

答案 1 :(得分:1)

(也将此答案添加到了https://stackoverflow.com/a/44384638/3415409

我刚刚从https://jaceklaskowski.gitbooks.io/mastering-spark-sql/spark-sql-performance-tuning-groupBy-aggregation.html中了解了有关使用groupBy聚合时控制分区数量的信息,似乎对Window也是有效的,在我的代码中我定义了一个窗口,如

windowSpec = Window \
    .partitionBy('colA', 'colB') \
    .orderBy('timeCol') \
    .rowsBetween(1, 1)

然后做

next_event = F.lead('timeCol', 1).over(windowSpec)

并通过

创建数据框
df2 = df.withColumn('next_event', next_event)

,实际上,它有200个分区。但是,如果我这样做

df2 = df.repartition(10, 'colA', 'colB').withColumn('next_event', next_event)

它有10个!