Spark高效的groupby操作-重新分区?

时间:2019-05-30 14:41:18

标签: python apache-spark pyspark

我正在pyspark 2.3中工作,我试图找出从数据框中获取一些汇总统计信息的最有效方法。

我有一个数据帧,其中有15亿条记录分布在一个相对较小的10个节点的群集中。每个都有16gb的ram和4个核心。我的复制因子设置为2。

我的数据框可能有15列,这些列是数据类型的混合,但是我只对两列感兴趣-ID和eventDate。我要运行的代码非常简单:

output = df.groupby(['ID']).agg(F.min('eventDate').alias("firstDate"),F.max('eventDate').alias("lastDate"))
output.write.parquet('hdfs:///somewhere/dateFile.parquet',mode='overwrite')

我要弄清楚的是执行此操作的最有效方法。 ID(我正在对其进行分组的字段)具有12m的值,而df.rdd.getNumPartitions()当前为642。

我最好先将数据框投影到我想要的两列吗?拥有如此多的ID,我应该首先对数据集重新分区吗?我应该丢掉重复的东西吗?我可以在groupby之前运行这样的事情:

df = df[['ID','eventDate']].drop_duplicates().repartition(x)

df = df[['ID','eventDate']].repartition(x)

我正在努力寻找可以优化运行时间的方法。任何有关预定运行时间的指导将不胜感激。如果可能的话,我宁愿不只是“测试一下”,因为我有两个要运行的查询,每个查询都需要一段时间。

2 个答案:

答案 0 :(得分:2)

这可能不是您要找的答案,但是此操作的最佳代码正是

(function($) {

    $('select').each(function(e) {
        handleSelectSelections($(this));
    });


})( jQuery );

function handleSelectSelections(select) {

    var el = (select.next('.select2').length) ? jQuery(select.data('select2').$container) : select;

    if (select.val() !== "" && select.val() !== null) {
        el.addClass('has-selection');
    } else {
        el.removeClass('has-selection');
    }

}

Spark仅通过首先选择整个操作所需的必要列来优化流程。之后,Spark通过output = df.groupby(['ID']). \ agg(F.min('eventDate').alias("firstDate"), F.max('eventDate').alias("lastDate")) output.write.parquet('hdfs:///somewhere/dateFile.parquet', mode='overwrite') 对数据进行分区,并在每个分区上开始聚合过程。

允许最大数量的执行者肯定会有所帮助。我建议(根据您的描述)设置ID。 1200万的值是一个相当大的数字,也许可以尝试增加随机分配分区的数量,例如spark.executor.instances=10; spark.executor.memory=10g,只是为了避免出现一些令人讨厌的内存开销异常。

答案 1 :(得分:-2)

@flyingmeatball,

进行聚合之前,请执行以下步骤

1-删除不需要的数据(它将消耗您的资源)。

2-根据您的数据重新分区并缓存数据(这将减少执行时间)

提示:如果数据来自Cassandra,请使用分区键对数据进行重新分区,从而避免数据改组

现在您可以使用聚合逻辑了;)

谢谢,
维玛列什