我正在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)
我正在努力寻找可以优化运行时间的方法。任何有关预定运行时间的指导将不胜感激。如果可能的话,我宁愿不只是“测试一下”,因为我有两个要运行的查询,每个查询都需要一段时间。
答案 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,请使用分区键对数据进行重新分区,从而避免数据改组
现在您可以使用聚合逻辑了;)
谢谢,
维玛列什