改进Spark 1.5.2中的groupby操作

时间:2017-06-24 07:38:23

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

我们使用Spark表现不佳。

我有两个具体问题:

  1. 调试时我们发现在Rdd上完成的一些groupby操作花费的时间更多
  2. 还有一些阶段出现两次,有些阶段很快完成,有些阶段需要更多时间
  3. 以下是Spark UI when running locally的屏幕截图。

    目前在本地运行,将shuffle分区设置为2,分区数设置为5,数据大约为1,00,000条记录。

    说到groupby操作,我们基于两列对数据帧(这是几个连接的结果)进行分组,然后应用函数来获得一些结果。

           val groupedRows = rows.rdd.groupBy(row => (
            row.getAs[Long](Column1),
            row.getAs[Int](Column2)
            ))
          val rdd = groupedRows.values.map(Criteria)
    

    在Criteria中,某些函数对分组的结果行起作用。我们能以任何方式优化这一群体吗?

    以下是DAG Graph1的屏幕截图。

2 个答案:

答案 0 :(得分:0)

我建议您不要将现有的dataframe转换为rdd并执行您正在执行的复杂流程。

如果您想在两列(CriteriaColumn1)上执行Column2功能,可以直接在dataframe上执行此操作。此外,如果您的Criteria可以简化为内置functions的组合,那么它会很棒。但您始终可以将udf函数用于自定义规则。

我建议您groupBy上的dataframe并申请aggregation函数

rows.groupBy("Column1", "Column2").agg(Criteria function)

如果您想要分组dataframe中的多行,则可以使用Window函数。更多信息here

答案 1 :(得分:0)

.groupBy is known不是最有效的方法:

  

注意:此操作可能非常昂贵。如果你正在分组   为了对每个进行聚合(例如总和或平均)   密钥,使用PairRDDFunctions.aggregateByKey或   PairRDDFunctions.reduceByKey将提供更好的性能。

有时最好使用.reduceByKey.aggregateByKey,如here所述:

  

虽然这两个函数都会产生正确的答案,但是   reduceByKey示例在大型数据集上运行得更好。那是   因为Spark知道它可以将输出与每个输出的公共密钥组合在一起   在洗牌之前进行分区。

为什么.reduceByKey.aggregateByKey.groupBy工作得更快?因为部分聚合发生在map阶段,并且在reduce阶段期间较少的数据在工作节点周围进行混洗。以下是how does aggregateByKey work的一个很好的解释。