我使用Spark sql数据帧执行groupby操作,然后计算每个组的数据的平均值和中位数。原始数据量约为1 TB。
val df_result = df.filter($"DayOfWeek" <= 5).groupBy("id").agg(
count("Error").as("Count"),
avg("Error").as("MeanError"),
callUDF("percentile_approx", col("Error"), lit(0.05)).as("5thError"),
callUDF("percentile_approx", col("Error"), lit(0.5)).as("MedianError"),
callUDF("percentile_approx", col("Error"), lit(0.95)).as("95thError")).
filter($"Count" > 1000)
df_result.orderBy(asc("MeanError")).limit(5000)
.write.format("csv").option("header", "true").save("/user/foo.bar/result.csv")
当我运行该查询时,我的工作陷入困境并且无法完成。我该如何调试问题?是否存在导致groupby()
卡住的关键不平衡?
答案 0 :(得分:0)
评论中已经有很多明智的建议,但是我的想法是值得的:
1)df.count有效吗?如果没有,您的问题出现在您发布的代码之前(如评论中所示)
2)查看Spark UI(如评论中所示) - 大多数任务快速完成,少数需要很长时间/出现卡住?如果是这样,倾斜可能是你的问题
3)您可能会重写您的查询,首先只能找到每个'id'的'count'。接下来过滤原始df以仅包含通过广播(以避免随机播放df)内部连接的id出现超过1000次的行(如果没有太多的id超过1000次出现)。然后聚合这个较小的数据帧并计算所有统计数据。如果计数聚合有效,则输出还应显示是否存在任何重要的数据偏差!
4)有时将计算分解为更小的步骤并写入然后立即从磁盘读取,这有助于我在过去完成尴尬的工作。如果首先生成df代价高昂,也可以更快地进行调试。
5)绝对值得提升spark.sql.shuffle.partitions(如评论中所示); 2001年是一个神奇的数字(What should be the optimal value for spark.sql.shuffle.partitions or how do we increase partitions when using Spark SQL?)
6)我也会尝试改变数据量,如果你只使用一周中的一天= 1(如评论中所建议的那样)它是否有效
7)查询是否在没有percentile_approx的情况下运行?