hive存储格式优化调研报告

写在前面:

hive表的源文件存储格式有以下几类:text 、sequence、parquet、rc、orc。下面试着从写入时间、压缩比、查询速度、表结构修改几个方面对上述存储方式进行对比说明。

由于orc是对rc格式的改进,各方面相对于rc都有很好的优化和提升,因此暂时不对rc格式进行测试。

新增了两个关于parquet的对比格式。其中,parquet_gzip是基于gzip压缩的parquet格式,没有对小文件进行合并,基于spark写入和查询数据;parquet_gzip_hive是基于gzip压缩、设置小文件自动合并的parquet格式,基于hive写入数据,spark查询数据,文件个数相对于源数据减少一半。

一、测试环境:

  1. --num-executors 4 --executor-memory 8192M 
  2. 以 db.table 表 2017112010~2017112022 分区为测试数据,生成 text、sequence、parquet、orc 四种格式的表。数据总量为 513860462

二、写入对比 

        2.1写入时间对比(单位:秒)



PARTITION
TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
2017112010 139.875 161.922 177.558 322.427 121.823 379.446
2017112011 143.115 186.697 199.509 366.907 118.545 394.13
2017112012 197.395 164.251 219.805 462.125 165.834 561.403
2017112013 195.96 186.888 230.038 386.816 139.169 506.125
2017112014 151.181 193.149 212.073 367.469 133.471 458.147
2017112015 186.04 145.464 197.705 425.044 143.64 419.974
2017112016 225.897 172.785 262.152 474.486 151.698 566.061
2017112017 218.478 298.682 320.536 609.084 123.545 863.74
2017112018 239.46 335.477 351.783 755.441 120.063 942.073
2017112019 166.566 173.899 238.157 489.502 137.448 627.191
2017112020 130.077 170.375 184.109 358.55 153.59 489.428
2017112021 111.029 158.18 164.101 320.314 138.056 446.86
2017112022 84.106 87.013 113.43 219.574 121.91 260.406

   2.2 占用空间对比(单位:G)




PARTITION
TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
2017112010 24.1 24.7 12.6 4.2 4.5 3.6
2017112011 28.2 28.9 14.9 4.9 5.2 4.2
2017112012 32.4 33.2 17.3 5.7 6.1 4.9
2017112013 29.7 30.4 15.8 5.2 5.5 4.4
2017112014 29.1 29.8 15.5 5.1 5.4 4.4
2017112015 29.5 30.2 15.7 5.2 5.5 4.4
2017112016 33.4 34.2 18.1 6 6.3 5.1
2017112017 46.6 47.7 26.2 8.7 9 7.5
2017112018 50.8 52.1 28.7 9.6 9.9 8.2
2017112019 33.9 34.7 18.5 6.2 6.5 5.2
2017112020 26 26.6 13.6 4.6 4.9 3.9
2017112021 22.6 23.2 11.7 3.9 4.1 3.3
2017112022 16.1 16.5 8.1 2.7 2.8 2.3

三、查询对比

        3.1 单分区简单查询(单位:秒)




try_times
TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
平均 73.1146 50.524 7.2248 0.7746 1.3566 8.8422
try5 72.5 44.154 5.139 0.484 0.601 6.108
try4 72.146 44.754 5.252 0.637 0.593 6.521
try3 72.401 45.103 5.289 0.907 0.726 8.11
try2 73.051 51.242 5.948 0.708 0.855 8.165
try1 75.475 67.367 14.496 1.137 4.008 15.307


3.2 单分区复杂查询(单位:秒)




try_times
TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
try1 72.358 57.302 8.388 3.632 1.462 10.213
try2 72.229 57.216 6.313 2.703 0.976 8.785
try3 72.802 56.598 5.982 1.436 1.001 7.741
try4 72.349 56.169 5.559 2.038 0.98 8.388
try5 72.284 53.769 5.082 1.266 0.956 8.443
平均 72.4044 56.2108 6.2648 2.215 1.075 8.714

3.3 多分区简单查询(单位:秒)


TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
444.031 591.862 8.827 6.824 2.7094 51.716




 3.4 多分区复杂查询(单位:秒)     



TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
577.578 594.109 22.515 8.2882 5.773 55.587



四、表结构修改

           4.1 修改表名




TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
1.226 0.961 1.206 0.928 0.842 1.04


 4.2 添加新列



TEXT
SEQUENCE
PARQUET
PARQUET_GZIP
PARQUET_GZIP_HIVE
ORC
0.715 0.699 0.731 0.644 0.674 0.697


四、总结

  1. 写入速度:text > sequence > parquet > parquet_gzip_hive > parquet_gzip > orc
    1. 前四名相差不大

  2. 压缩比:    orc > parquet_gzip > parquet_gzip_hive > parquet > text > sequence
    1. 前三名相差不大

  3. 查询速度:parquet_gzip_hive ≈ parquet_gzip > parquet > orc > sequence > text
    1. 当数据量小的时候,parquet_gzip_hive与parquet_gzip相差无几
    2. 当数据量大的时候,parquet_gzip_hive查询速度远远大于其它存储格式

  4. 以目前文件合并阈值来看(128M),parquet_gzip_hive 文件个数只有其它存储格式文件个数的一半

  5. 表结构修改:均支持变更表名、添加新列

  6. 支持hive查询

  7. 进一步说明
    TEXT:
    1.   默认格式,建表时不指定默认为这个格式,存储方式:行存储  
    2.   导入数据时会直接把数据文件拷贝到hdfs上不进行处理。源文件可以直接通过hadoop fs -cat 查看  
    3.   磁盘开销大 数据解析开销大,压缩的text文件 hive无法进行合并和拆分  

           SEQUENCE:

    1.  一种Hadoop API提供的二进制文件,使用方便、可分割、可压缩等特点。  
    2.  将数据以<key,value>的形式序列化到文件中。序列化和反序列化使用Hadoop 的标准的Writable 接口实现,优势是文件和Hadoop api中的mapfile是相互兼容的。

           PARQUENT:

    1. 能够很好的压缩,有很好的查询性能

           ORC:

    1. 属于RCFILE的升级版,性能有大幅度提升,而且数据可以压缩存储,压缩快 快速列存取 
    2. 压缩比和Lzo压缩差不多,比text文件压缩比可以达到80%的空间。而且读性能非常高,可以实现高效查询。


         综上,parquet_gzip_hive是最优方案,即:按gzip压缩的parquet存储方式,并设置小文件合并规则,以hive写入数据,以spark查询数据。

五、操作方案

  1. 建表
    1. 语句:
      use test;

      CREATE TABLE `table_name_parquet_gzip_hive`(id ....)
      PARTITIONED BY (`day` int)
      ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
      STORED AS
      INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
      OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat';

    2. hive 或 sparkSQL执行均可

  2. 写入数据
    1. 语句:
      set parquet.compression=GZIP;
      set hive.merge.mapfiles = true;
      set hive.merge.mapredfiles = true;
      set hive.merge.size.per.task = 115000000;
      set hive.merge.smallfiles.avgsize=115000000;
      set hive.exec.reducers.bytes.per.reducer=115000000;
      set hive.exec.reducers.max=120000000;
      set hive.warehouse.subdir.inherit.perms=false;

      insert overwrite TABLE table_name_parquet_gzip_hive partition(day=2017112015)
      select ... from db.table where day='2017112015';

    2. 一定要用hive执行,切记!
  3. 查询
    1. 语句:select * from table_name_parquet_gzip_hive;
    2. hive或sparkSQL执行均可,sparkSQL执行会快一些