HIVE调优之存储格式

目录

  1. 行式数据库和列式数据库的对比
  2. 存储格式的比较
  3. 存储格式的应用

行式数据库和列式数据库的对比

  1. 存储比较

    行式数据库存储在hdfs上式按行进行存储的,一个block存储一或多行数据。而列式数据库在hdfs上则是按照列进行存储,一个block可能有一列或多列数据。

  2. 压缩比较

    对于行式数据库,必然按行压缩,当一行中有多个字段,各个字段对应的数据类型可能不一致,压缩性能压缩比就比较差。

    对于列式数据库,必然按列压缩,每一列对应的是相同数据类型的数据,故列式数据库的压缩性能要强于行式数据库。

  3. 查询比较

    假设执行的查询操作是:select id,name from table_emp;

    对于行式数据库,它要遍历一整张表将每一行中的id,name字段拼接再展现出来,这样需要查询的数据量就比较大,效率低。

    对于列式数据库,它只需找到对应的id,name字段的列展现出来即可,需要查询的数据量小,效率高。

    假设执行的查询操作是:select * from table_emp;

    对于这种查询整个表全部信息的操作,由于列式数据库需要将分散的行进行重新组合,行式数据库效率就高于列式数据库。

    但是,在大数据领域,进行全表查询的场景少之又少,进而我们使用较多的还是列式数据库及列式储存。

存储格式的比较

: SEQUENCEFILE
| TEXTFILE -- (Default, depending on hive.default.fileformat configuration)
| RCFILE -- (Note: Available in Hive 0.6.0 and later)
| ORC -- (Note: Available in Hive 0.11.0 and later)
| PARQUET -- (Note: Available in Hive 0.13.0 and later)
| AVRO -- (Note: Available in Hive 0.14.0 and later)
| JSONFILE -- (Note: Available in Hive 4.0.0 and later)
| INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
  • SEQUENCEFILE: Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。

  • TEXTFILE: textfile为默认格式,存储方式为行存储。数据不做压缩,磁盘开销大,数据解析开销大。

  • RCFILE(Record Columnar File): 一种行列存储相结合的存储方式。

  • ORC: 数据按照行分块,每个块按照列存储,其中每个块都存储有一个索引。hive给出的新格式,属于RCFILE的升级版,性能有大幅度提升,而且数据可以压缩存储,压缩快 快速列存取。

    ORC这种文件格式可以作用于表或者表的分区,可以通过以下几种方式进行指定:

    CREATE TABLE ... STORED AS ORC	(常用)
    ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
    SET hive.default.fileformat=Orc
  • PARQUET: Parquet也是一种行式存储,同时具有很好的压缩性能;同时可以减少大量的表扫描和反序列化的时间。

如果要使用其他格式作为hive表数据的存储格式,则必须先存在一张相同数据的存储格式为TEXTFILE的表table_t0,然后在建表时使用“insert into table table_stored_file_ORC select from table_t0;”创建。或者使用”create table as select from table_t0;”创建。

相同数据,分别以TextFile、SequenceFile、RcFile、ORC、Parquet存储的比较。

  1. 源文件大小

    [hadoop@hadoop data]$ hdfs dfs -du -s -h /data/page_views.dat
    18.1 M 18.1 M /data/page_views.dat
  2. TextFile

    • 建表&加载数据

      create table page_views_text( 
      track_time string,
      url string,
      session_id string,
      referer string,
      ip string,
      end_user_id string,
      city_id string
      )ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
      STORED AS TEXTFilE;

      #加载导入
      load data inpath '/data/page_views.dat' into table page_views_text;
    • 表大小

      18.1 M  18.1 M  /user/hive/warehouse/store_format.db/page_views_text
    • 查询时读取数据量大小(单位字节,下面都用这个SQL测试)

      select count(1) from page_views_text where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";

      HDFS Read: 19024045
  3. SequenceFile

    • 建表

      create table page_views_seq( 
      track_time string,
      url string,
      session_id string,
      referer string,
      ip string,
      end_user_id string,
      city_id string
      )ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
      STORED AS SequenceFile;

      #查询导入
      insert into table page_views_Seq select * from page_views_text;
    • 表大小

      19.6 M  19.6 M  /user/hive/warehouse/store_format.db/page_views_seq
    • 查询时读取数据量大小(字节)

      HDFS Read: 61513817
  4. RcFile

    • 建表(CTAS)

      create table page_views_rcfile
      ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
      STORED AS RcFile
      as select * from page_views_text
    • 表大小

      17.9 M  17.9 M  /user/hive/warehouse/store_format.db/page_views_rcfile
    • 查询时读取数据量大小(字节)

      HDFS Read: 3726738
  5. ORC

    • 建表

      create table page_views_orc
      ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
      STORED AS ORC
      as select * from page_views_text
    • 表大小

      HDFS Read: 1258828
    • 查询时读取数据量大小(字节)

      2.8 M  2.8 M  /user/hive/warehouse/store_format.db/page_views_orc
  6. Parquet

    • 建表

      create table page_views_par
      ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
      STORED AS Parquet
      as select * from page_views_text
    • 表大小

      13.1 M  13.1 M  /user/hive/warehouse/store_format.db/page_views_par
    • 查询时读取数据量大小(字节)

      HDFS Read: 2688348

不同的存储格式不仅表现在存储空间上的不同,对于数据的查询,效率也不一样。因为对于不同的存储格式,执行相同的查询操作,他们访问的数据量大小是不一样的。

不同格式表存储大小的比较

表大小比较

不同格式表读取数据量比较

读取数据量比较

存储格式的应用

原文件还是上面的那个

[hadoop@hadoop data]$ hdfs dfs -du -s -h /data/page_views.dat
18.1 M 18.1 M /data/page_views.dat
  1. ORC+Zlib结合

    create table page_views_orc_zlib
    ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    STORED AS ORC
    TBLPROPERTIES("orc.compress"="ZLIB")
    as select * from page_views_text;

    用ORC+Zlip之后的文件为2.8M

    2.8 M  2.8 M  /user/hive/warehouse/store_format.db/page_views_orc_zlib
  2. Parquet+gzip结合

    set parquet.compression=gzip;
    create table page_views_parquet_gzip
    ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    STORED AS PARQUET
    as select * from page_views_text;

    用Parquet+gzip之后的文件为3.9M

    3.9 M  3.9 M  /user/hive/warehouse/store_format.db/page_views_parquet_gzip
  3. Parquet+Lzo结合

    SET hive.exec.compress.output=true;  
    SET mapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.lzopCodec;
    SET mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec;

    create table page_views_parquet_lzo ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    STORED AS PARQUET
    TBLPROPERTIES("parquet.compression"="lzo")
    as select * from page_views_text;

    用Parquet+Lzo(未建立索引)之后的文件为6.2M

    6.2 M  6.2 M  /user/hive/warehouse/store_format.db/page_views_parquet_lzo

    建立索引(表好像没啥用)

    hadoop jar $HADOOP_HOME/share/hadoop/common/hadoop-lzo.jar com.hadoop.compression.lzo.LzoIndexer /user/hive/warehouse/store_format.db/page_views_parquet_lzo
Author: Tunan
Link: http://yerias.github.io/2018/11/11/hive/12/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.