vlambda博客
学习文章列表

大压缩文件对Impala查询性能的影响

Hadoop/HDFS/MapReduce/Impala被设计用于存储和处理大量文件的场景,比如TB或者PB级别数据量的文件。大量小文件对查询性能有很大的影响,因为NameNode要保存大量的HDFS文件元数据,一次性查询很多分区或者文件的话,需要获取文件列表并一个个读取文件信息,不仅会对查询性能造成很大的影响,还可能会超过操作系统的文件描述符数量限制而导致查询失败。

因此,这就意味着我们要尽可能让文件保持很大吗?当然不是。大文件对表的性能也会有影响,原因是在大多数情况下,Hadoop用户会压缩存储在HDFS中的数据,这样虽然可以节省磁盘空间,但是如果你有一个大的压缩文件,花费在解压上的时间也会导致查询变慢。

为了证明上面的说法,我在CDH环境中做了以下测试:

1、我准备了一个565M的普通Text格式的文件和一个使用bzip2压缩方式压缩的135M的文件,文件下载链接:https://www.kaggle.com/usdot/flight-delays#flights.csv

2、我用4个这样的bzip2文件创建了一个名为bzip2_smallfiles_4的表,用8个这样的文件创建了另一个名为bzip2_smallfiles_8的表

3、然后,我还将这个文本文件合并4次,生成一个文本文件,使用bzip2对其进行压缩,大小变为大约510MB,并在其上创建了一个名为bzip2_bigfile_4的表

4、和3是一样的。但我将文件合并了8次,使其变大,压缩后文件大小为1.1GB,并创建了一个名为bzip2_bigfile_8的新表

5、然后,我对这4个表逐个运行“SELECT COUNT(*) FROM”查询来比较结果

毫无疑问,我看到对表bzip2_bigfile_8的查询是最慢的。以下是对这四张表的测试数据:

bzip2_smallfiles_4:

  • 4台主机运行查询

  • 查询运行时间大约53秒

  • 最大扫描时间52秒

  • 最大解压时间为49秒

Operator Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail 00:SCAN HDFS 4 26s464ms 52s687ms 23.28M -1 40.32 MB 160.00 MB test.bzip2_smallfiles_4
Query Timeline... Rows available: 53.86s (53861836202) First row fetched: 53.87s (53869836178) Unregister query: 53.87s (53874836163)
Fragment F00 Instance fc48dc3e014eb7a5:7d7a2dc100000004 (host=xxxx:22000) AGGREGATION_NODE (id=1) HDFS_SCAN_NODE (id=0) File Formats: TEXT/BZIP2:2 - DecompressionTime: 49.45s (49449847498)


bzip2_smallfiles_8:

  • 4台主机运行查询

  • 查询运行时间大约54.69秒

  • 最大扫描时间54.196秒

  • 最大解压时间为51.18秒


Operator Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail 00:SCAN HDFS 4 52s514ms 54s196ms 46.55M -1 40.32 MB 160.00 MB test.bzip2_smallfiles_8
Query Timeline... Rows available: 54.36s (54359822792) First row fetched: 54.68s (54683821736) Unregister query: 54.69s (54688821720)
Fragment F00 Instance 5642f67b9a975652:c19438dc00000004 (host=xxxx:22000) AGGREGATION_NODE (id=1) HDFS_SCAN_NODE (id=0) File Formats: TEXT/BZIP2:2 - DecompressionTime: 51.18s (51183849937)

bzip2_bigfile_4:

  • 4台主机运行查询

  • 查询运行时间大约1分50秒

  • 最大扫描时间为1分49秒

  • 最大解压时间为1分7秒

Operator Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail 00:SCAN HDFS 4 27s394ms 1m49s 23.28M -1 40.15 MB 176.00 MB test.bzip2_bigfile_4
Query Timeline... Rows available: 1.8m (109781665214) First row fetched: 1.8m (110408663300) Unregister query: 1.8m (110413663284)
Fragment F00 Instance 4545c110dbca4c9c:6cd1db1100000004 (host=xxxx:22000) AGGREGATION_NODE (id=1) HDFS_SCAN_NODE (id=0) File Formats: TEXT/BZIP2:2 - DecompressionTime: 1.7m (104339662922)

bzip2_bigfile_8:

  • 4台主机运行查询

  • 查询运行时间大约3分6秒

  • 最大扫描时间为3分35秒

  • 最大解压时间为3分4秒

Operator Hosts Avg Time Max Time #Rows Est. #Rows Peak Mem Est. Peak Mem Detail 00:SCAN HDFS 4 53s902ms 3m35s 46.55M -1 40.32 MB 176.00 MB test.bzip2_bigfile_8
Query Timeline... Rows available: 3.6m (215992297509) First row fetched: 3.6m (216480295920) Unregister query: 3.6m (216484295907)
Fragment F00 Instance 8f42a3b6ca6cf1cf:72fd65e100000004 (host=xxxx:22000) AGGREGATION_NODE (id=1) HDFS_SCAN_NODE (id=0) File Formats: TEXT/BZIP2:2 - DecompressionTime: 3.4m (203596406406)

我选择bzip2压缩格式的原因是因为bzip2是可分割的,我所有的测试查询都是使用4台主机来运行的,即使是对于那两个大的bzip2文件也是如此。

正如我们所看到的,为了让Impala读取最大的1.1GB bzip2文件,解压这个文件几乎需要4分钟。对于表bzip2_smallfiles_8,虽然我们有更多的文件需要解压,但是因为我们可以在多个主机上并行执行解压操作,因此不会对性能造成太大影响。

综上所述,太多的小文件(比如KB或者比较小的MB文件)在Hadoop中是不允许的,然而,文件太少而压缩大小太大也是不好的。理想情况下,我们应该使文件大小尽可能接近块大小(在CDH中默认为256MB),以便优化性能。

编译自:https://www.ericlin.me/2019/04/big-compressed-file-will-affect-query-performance-for-impala/