火花避免收集尽可能

Posted

技术标签:

【中文标题】火花避免收集尽可能【英文标题】:spark avoid collect as much as possible 【发布时间】:2020-11-02 18:14:11 【问题描述】:

我看到了对任何使用 spark 的人的一般性建议(在我的例子中是 Scala) 是避免任何将所有数据从执行器获取到驱动程序的操作(收集、计数、求和等)。 但是,当我尝试使用火花统计库时 http://spark.apache.org/docs/2.2.0/ml-statistics.html 我发现相关矩阵和 ChiSquareTest 方法 期望从 array\seq 获得的数组或矩阵作为它们的参数,因此我不 看看我如何避免对数据框进行收集(以及我假设的更多操作 如果我想使用此功能,请使其成为 Vectors 而不是 Row 类型)。将不胜感激。

【问题讨论】:

它说尽可能避免,而不是完全绕过它。需要收集操作才能获得任何相关的输出。 我读过,因为驱动可能会在大数据帧的情况下崩溃,不建议在生产中这样做。但是,我不确定我是否尝试在数据帧上进行许多操作,例如 groupBy 和 Joins,是不是也很昂贵?我试图了解总体上更好的方法是什么。 【参考方案1】:
    在您的示例中,Correlation.corrChiSquareTest.test 都接受数据帧,因此您无需在将数据传递给这些函数之前收集数据。您必须在驱动程序上收集这些函数的结果,但这不会导致任何问题,因为输出大小应该比初始数据集小得多,并且应该很容易放入驱动程序的内存中。 关于groupBy / joins 的评论中的问题 - 这些都是“昂贵的”,但出于不同的原因。分组和连接会导致数据混洗——因此,您的工作人员需要通过网络发送大量数据,这比本地数据处理需要更多时间。不过,如果您必须这样做 - 没关系,请注意性能影响。 collect 方法不建议在完整数据集上使用,因为它可能会导致驱动程序出现 OOM 错误(想象一下,您有 50 Gb 数据集,分布在一个集群上,现在您将它收集在一个节点),但是如果您已经处理了数据,并且您知道,会有一些合理数量的行 - 这样做是非常安全的。从内存的角度来看,count 根本不应该是一个问题,因为它只是返回数据集中的行数,而不是将它们全部发送到驱动程序节点。

【讨论】:

感谢您的回答!有两件事要澄清:1)是的,ChiSquareTest.test 得到 DF,但是向量序列。不是 dataset (或者最好是 dataset。2)一般来说,喜欢添加 lite(1) 列而不是 sum\count 的窗口函数是一个好习惯吗?还是“付出的代价太大”? 1) 例如,它是一个向量序列,稍后会转换为 DataFrame(内部密集和稀疏向量),您可以使用 map 从任何类型的数据创建你有,你不必把它全部放在驱动程序上。您可以在 s3 上有一个包含您的点的文件,将其读入您的工作人员,然后将这些点映射到向量。 2)我认为,使用 Spark 的现有功能实际上更好,如果它们符合您的目的 - Spark 通常可以更好地优化它们。因此,如果您只需要计数 - 直接使用 count 而不是 window,并且只将 window 用于非标准的东西

以上是关于火花避免收集尽可能的主要内容,如果未能解决你的问题,请参考以下文章

如何避免mongodb中的重复键错误收集

避免 Prometheus 调用所有 k8s 服务实例(只有一个,应用范围的指标收集)

查询Spark同时加载的hive表时如何避免错误

火花检查点比缓存更快吗?

避免使用mongodb重复文档而不使用唯一索引

如何避免星型模式中事实表之间的连接?