我有一个场景,spark的初始阶段产生数十亿条记录并将其缓存。在这之后,我们要为一列浮点值(在上一步中产生)计算精确的分位数,比如说,从该列中识别5%的最小值。
我尝试使用 takeOrdered
对缓存的rdd执行操作,但它们暂时不起作用:
假设计算阶段的分区很大,那么 takeOrdered
操作效率低下,因为每个分区的单个记录将非常小,而每个分区只有5% totalNumberOfRecords
. 因此,它将获取驱动程序中的所有记录,大量超出驱动程序内存。
如果分区计数一开始就很小,那么随着并行度的降低,计算阶段的开销也会越来越大。另一方面,如果我们从大量分区开始,然后执行 coalesce
操作以显著减少分区,这样在驱动程序内存中只提取所需的最少数量的记录,然后在跨节点(分区)移动数据时,我们会看到由于序列化/反序列化而导致的缓冲区限制超过错误。我用kryo序列化程序和默认java序列化程序尝试了这种方法。
我了解到 approxQuantile
用相对误差近似分位数值。但是,假设我保持错误参数为 zero
有人认为,这将是一个昂贵的操作。我猜这个费用将与我们面临的问题相似 takeOrdered
以上操作。如果我错了,请纠正我!
有没有一种有效的方法来执行精确的分位数计算,在内存和时间方面进行评估,同时使其成为一个非常可扩展的方法?
暂无答案!
目前还没有任何答案,快来回答吧!