Spark,执行程序加载/查询数据 - 性能非常低

时间:2016-06-07 14:26:34

标签: apache-spark

我的用例如下:

通过RDD Wrtiting saveAsTable归档(因此对ORC文件)。每次保存都会创建新文件(因此1000 000着作会为我提供1000 000个ORC文件)。我知道每个RDD都会创建新的ORC文件是很自然的。但是,我不知道为什么从ThriftServer查询它们的速度太慢。

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

我想了解这种差异。毕竟,1000 000文件是小编号。

1 个答案:

答案 0 :(得分:6)

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

  1. 从HDFS NameNode请求文件

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

  3. 对每个分区进行统计(使用ORC元数据或直接 - 取决于实现)并总结所有
  4. 一些估计:1000,000个文件需要与NameNode相同数量的请求来解析数据块的物理位置。它是在&lt;中完成的。 60s(每个请求<0.06ms) - NameNode做得非常好。其余时间Spark将数据加载到内存中(如果需要)或/并从ORC元数据中获取统计信息。所以我会介绍NameNode(或类似的服务,如果你使用S3或其他) - 它的第一个候选人是一个瓶颈。来自ORC documentation

      

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

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

    当ORC尝试减少文件数量时,您的代码却相反。和

      

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

         

    文件页脚包含文件中的条带列表,数量为   每个条带的行,以及每个列的数据类型。它还包含   列级聚合count,min,max和sum。

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