我的用例如下:
通过RDD
Wrtiting saveAsTable
归档(因此对ORC文件)。每次保存都会创建新文件(因此1000 000
着作会为我提供1000 000
个ORC文件)。我知道每个RDD都会创建新的ORC文件是很自然的。但是,我不知道为什么从ThriftServer查询它们的速度太慢。
我的问题是:如何理解这种奇怪的行为?
例如,1000 000行上的SELECT COUNT(*)
(因此相同的文件)大约需要1 minute
(!)。
但是,当我将1000 000
行保存到一个文件时,同一查询在50ms
中有效。
我想了解这种差异。毕竟,1000 000
文件是小编号。
答案 0 :(得分:6)
您的计数操作的高级执行计划将是这样的(假设您的文件位于分布式文件系统中,例如我将使用HDFS):
从HDFS NameNode请求文件
将HDFS块加载到执行程序
一些估计: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分钟从源中读取一次。