【问题标题】:Spark, executors loading/querying data - very low performanceSpark,执行器加载/查询数据 - 性能非常低
【发布时间】:2016-06-07 14:26:34
【问题描述】:

我的用例如下:

RDD 写入saveAsTable 的文件(因此写入ORC 文件)。每次保存都会创建新文件(所以1000 000 的文字给我1000 000 ORC 文件)。我知道每个 RDD 都会创建新的 ORC 文件是很自然的。但是,我不知道从 ThriftServer 查询它们时为什么这么慢。

我的问题是:如何理解这种奇怪的行为?
例如,SELECT COUNT(*) 在 1000 000 行(因此相同的文件)上大约需要 1 minute (!)。
但是,当我将1000 000 行保存到一个文件时,相同的查询在50ms 中有效。

我想了解这种差异。毕竟,1000 000 文件数量很少。

【问题讨论】:

标签: apache-spark


【解决方案1】:

您的计数操作的高级执行计划将是这样的(假设您的文件在分布式文件系统中,例如我将使用 HDFS):

  1. 从 HDFS NameNode 请求文件

  2. 将 HDFS 块加载到执行程序中

  3. 对每个分区进行计数(使用 ORC 元数据或直接 - 取决于实现)并将所有部分相加

一些估计:1000 000 个文件需要相同数量的 NameNode 请求来解析数据块的物理位置。它在 documentation:

与RCFile格式相比,例如ORC文件格式有很多 优点,例如:

a single file as the output of each task, which reduces the NameNode's load

虽然 ORC 试图减少文件数量,但您的代码却相反。和

默认条带大小为 250 MB。大条纹尺寸使大, 从 HDFS 高效读取。

文件页脚包含文件中的条纹列表,条数 每个条带的行数和每列的数据类型。它还包含 列级聚合计数、最小值、最大值和总和。

所以像计数这样简单的统计数据是预先计算的,不应该是性能问题。您可以尝试通过暴力简单地向 HDFS NameNode 添加内存和 CPU 能力来解决问题,但我认为保留适度数量的文件是合理的。如果您的数据来自某个流源,您可以创建某种压缩作业,将小文件合并为大文件并定期运行。或者,作为替代方案,您可以每 2-5 分钟从源读取一次,如果这种延迟适合您的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多