Spark数据帧组的平均值和中位数未完成

时间:2018-03-09 22:55:27

标签: apache-spark apache-spark-sql spark-dataframe

我使用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()卡住的关键不平衡?

1 个答案:

答案 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的情况下运行?