Apache spark 如何处理Spark窗口函数中的数据倾斜?

Apache spark 如何处理Spark窗口函数中的数据倾斜?,apache-spark,pyspark,apache-spark-sql,window-functions,Apache Spark,Pyspark,Apache Spark Sql,Window Functions,我有一个数据集,我正试图在PySpark中处理。数据(在磁盘上作为拼花)包含用户ID、会话ID和与每个会话相关的元数据。我在数据框中添加了许多列,这些列是通过窗口聚合的结果。我遇到的问题是,除了4-6个执行者之外,所有执行者都将很快完成,其余的执行者将永远不会完成。我的代码如下所示: 导入pyspark.sql.f函数 从pyspark.sql.window导入窗口 空的条件=((f.col(“col\u a”).isNull())| (f.col(“col_A”)=“”) session\u

我有一个数据集,我正试图在PySpark中处理。数据(在磁盘上作为拼花)包含用户ID、会话ID和与每个会话相关的元数据。我在数据框中添加了许多列,这些列是通过窗口聚合的结果。我遇到的问题是,除了4-6个执行者之外,所有执行者都将很快完成,其余的执行者将永远不会完成。我的代码如下所示:

导入pyspark.sql.f函数
从pyspark.sql.window导入窗口
空的条件=((f.col(“col\u a”).isNull())|
(f.col(“col_A”)=“”)
session\u window=window.partitionBy(“用户id”、“会话id”)\
.orderBy(f.col(“步骤id”).asc())
输出_df=(
输入_df
.带列(“col_A_val”,f
.何时(空柱状态,f.lit(“NA”))
。否则(f.col(“col_A”))
#…又添加了10列,以替换空字符串/空字符串
.重新分区(“用户id”、“会话id”)
.withColumn(“s_用户id”,f.first(“用户id”,True)。结束(会话窗口))
.带列(“s_col_B”,f.收集列表(“col_B”)。结束(会话窗口))
.带列(“s_col_C”,f.min(“col_C”)。结束(会话窗口))
.带列(“s_col_D”,f.max(“col_D”)。结束(会话窗口))
#…在会话\u窗口上又添加了16列聚合
.其中(f.col(“会话标志”)==1)
其中(f.array_包含(f.col(“s_col_B”),“some_val”))
)
在我的日志中,我一遍又一遍地看到:

INFO ExternalAppendOnlyUnsafeRowArray: Reached spill threshold of 4096 rows, switching to org.apache.spark.util.collection.unsafe.sort.UnsafeExternalSorter
INFO UnsafeExternalSorter: Thread 92 spilling sort data of 9.2 GB to disk (2  times so far)
INFO UnsafeExternalSorter: Thread 91 spilling sort data of 19.3 GB to disk (0  time so far)
这表明Spark无法在内存中保存所有窗口数据。我尝试增加内部设置
spark.sql.windowExec.buffer.in.memory.threshold
spark.sql.windowExec.buffer.spill.threshold
,这有点帮助,但仍然有执行者没有完成

我相信这都是由于数据中的一些偏差造成的。根据
用户id
会话id
进行分组,共有5条记录的计数>=10000,100条记录的计数介于1000和10000之间,150000条记录的计数小于1000(通常计数=1)

input\u df\
.groupBy(f.col(“用户id”)、f.col(“会话id”))\
.count()\
.filter(“计数<1000”)\
.count()
#>=10k,6
#<10k和>=1k,108
#<1k,150k
这是生成的作业DAG:


你找到答案了吗?@ShubhamGupta还没有。我试着用盐腌制数据,重新划分数据,但还没有成功。