gpt4 book ai didi

apache-spark - 计算Spark数据帧的大小-SizeEstimator提供意外结果

转载 作者:行者123 更新时间:2023-12-04 03:10:31 26 4
gpt4 key购买 nike

我正在尝试找到一种可靠的方式来以编程方式计算Spark数据帧的大小(以字节为单位)。

原因是我希望有一种方法来计算“最佳”数量的分区(“最佳”在这里可能表示不同的意思:在写入Parquet表时可能表示having an optimal partition sizeresulting in an optimal file size,但都可以假定两者都是数据框大小的一些线性函数)。换句话说,我想在数据帧上调用coalesce(n)repartition(n),其中n不是固定数字,而是数据帧大小的函数。

SO上的其他主题建议使用SizeEstimator.estimate中的org.apache.spark.util来获取数据帧的字节大小,但是我得到的结果不一致。

首先,我将数据帧保存到内存中:

df.cache().count 

Spark UI在“存储”选项卡中显示为4.8GB。然后,我运行以下命令从 SizeEstimator获取大小:
import org.apache.spark.util.SizeEstimator
SizeEstimator.estimate(df)

结果为115'715'808字节=〜116MB。但是,将 SizeEstimator应用于不同的对象会导致非常不同的结果。例如,我尝试分别计算数据帧中每一行的大小并将其求和:
df.map(row => SizeEstimator.estimate(row.asInstanceOf[ AnyRef ])).reduce(_+_)

这导致大小为12'084'698'256字节=〜12GB。或者,我可以尝试将 SizeEstimator应用于每个分区:
df.mapPartitions(
iterator => Seq(SizeEstimator.estimate(
iterator.toList.map(row => row.asInstanceOf[ AnyRef ]))).toIterator
).reduce(_+_)

这再次导致10'792'965'376字节=〜10.8GB的不同大小。

我了解其中涉及内存优化/内存开销,但是在执行这些测试之后,我看不到 SizeEstimator如何可用于获得足够好的数据帧大小(进而是分区大小或生成的Parquet文件大小)的估计值。

为了获得对数据帧大小或其分区的良好估计,应用 SizeEstimator的适当方法是什么(如果有)?如果没有,这里建议的方法是什么?

最佳答案

不幸的是,我无法从SizeEstimator获得可靠的估计,但是我可以找到另一种策略-如果数据帧已缓存,我们可以从queryExecution中提取其大小,如下所示:

df.cache.foreach(_=>_)
val catalyst_plan = df.queryExecution.logical
val df_size_in_bytes = spark.sessionState.executePlan(
catalyst_plan).optimizedPlan.stats.sizeInBytes

对于示例数据帧,这恰好提供了4.8GB(这也对应于写入未压缩的Parquet表时的文件大小)。

这样做的缺点是需要缓存数据帧,但就我而言,这不是问题。

关于apache-spark - 计算Spark数据帧的大小-SizeEstimator提供意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49492463/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com