Spark:基于窗口的处理如何分割给执行器?

Rol*_*our 5 bigdata apache-spark apache-spark-sql

我清楚地了解 Spark 如何将数据拆分到执行器内的分区,然后处理每个分区,然后聚合直到最终的“逻辑”数据帧。

但是使用Windows,我觉得每个窗口数据应该位于单个分区中,以便每个执行器在本地拥有所有数据?或者数据仍然被分割,然后通过某种魔法聚合?

此类窗口的一个示例是:

val window = Window
  .partitionBy("partition-col")
  .orderBy("order-col")
  .rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)
myDF.withColumn("sum", sum("aCol").over(window))
Run Code Online (Sandbox Code Playgroud)

Spark 如何处理这个问题?使用windows的性能如何?

如果我处理一个窗口中的 50 列怎么办?它可能会产生大量的网络交换,还是每个窗口都会在本地处理?

Kom*_*owy 2

为了计算窗口函数,Spark 需要排列数据,以便partitionBy按照您的预期将其中提到的列/表达式的值分组到单个分区中。

例如,尝试运行一个带有跨越整个数据框的窗口的函数。您将收到以下警告:

scala> df.withColumn("rn", row_number().over(Window.orderBy(lit(1)))).show
19/10/16 00:08:03 WARN WindowExec: No Partition Defined for Window operation! Moving all data to a single partition, this can cause serious performance degradation.
Run Code Online (Sandbox Code Playgroud)