欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

存储格式在Hive的应用

程序员文章站 2023-12-30 22:23:16
...

介绍

  • 存储按存储方式的不同可分为两类,一是行式存储,二是列式存储,对相同的原文件使用不同的存储格式可以减少不等的存储空间,并且在读取相同的原文件时,拉取的数据量会有较大差别,这样会减少磁盘的IO,从而缩短任务消耗的时间。存储一般会配合压缩一起使用,这样可以进一步减少存储空间和磁盘IO。
  • 行式存储:
    优点,一行记录的所有字段可以存储在同一个block中,这样在查询所有字段信息时可以直接获取。
    缺点,由于一行记录的所有字段数据类型不尽相同,所有压缩性能较低,并且在查询特定字段信息时,需要获取所有字段信息,这样会增加网络的IO

  • 列式存储:
    优点,按列存储的每一列的数据类型相同,压缩性能较好,在查询特定字段信息时可以直接拉取需要信息,减少读取不必要的信息
    缺点,行的重组性能较低。

Hive中的存储格式

  • 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)
    | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

TEXTFILE:文本文件

  • 存储方式:行存储
  • 默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。
  • 创建方式:
    textfile格式为hive中默认格式,创建方式可以有三种
    方式一

    1. CREATE TABLE tt (
    2. id int,
    3. name string
    4. ) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";
    

方式二

    1. CREATE TABLE tt2 (
    2. id int,
    3. name string
    4. ) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    5. STORED AS TEXTFILE;

方式三:

    1. CREATE TABLE tt3 (
    2. id int,
    3. name string
    4. ) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    5. STORED AS 
    6. INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
    7. OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'; #存储格式的底层方法

Sequencefile:二进制文件

  • 存储说明
    存储格式在Hive的应用
    Record:存储SequenceFile通用的KV数据格式,Key和Value都是二进制变长的数据。Record表示Key和Value的byte的总和。
    Sync:主要是用来扫描和恢复数据的,以至于读取数据的Reader不会迷失。
    Header:存储了如下信息:文件标识符SEQ,key和value的格式说明,以及压缩的相关信息,metadata等信息。
    metadata:包含文件头所需要的数据:文件标识、Sync标识、数据格式说明(含压缩)、文件元数据(时间、owner、权限等)、检验信息等。

  • 存储方式:行存储;

  • SequenceFile是Hadoop API 提供的一种二进制文件,它将数据(key,value)的形式序列化到文件里。这样的二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。
    Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,只是它的key为空。使用value 存放实际的值。 这样是为了避免MR 在执行map 阶段的排序过程。
  • SEQUENCEFILE比TextFile 多了一些冗余信息,所以要大一些。
  • 创建Sequencefile表并与textfile比较

    1. create table page_views_seq(
    2. track_time string,
    3. url string,
    4. session_id string,
    5. referer string,
    6. ip string,
    7. end_user_id string,
    8. city_id string
    9. )ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    10. STORED AS SEQUENCEFILE;
    

    load textfile格式文件进入到sequencefile表并不可行,这时需要使用insert 语句

    1. insert into table page_views_seq select * from page_views; 
    

    文件大小比较

    1. TextFile存储格式的大小
    2. [[email protected] ~]$ hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views
    3. 18.1 M   /user/hive/warehouse/hive.db/page_views
    4. SEQUENCEFILE存储格式的大小
    5. [[email protected] ~]$ hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views_seq 
    6. 19.6 M   /user/hive/warehouse/hive.db/page_views_seq
    7. 原始大小
    8. [[email protected] ~]$ du -sh data/page_views.dat
    9. 19M     data/page_views.dat
    

Rcfile

  • 存储说明
    存储格式在Hive的应用
    这个架构是利用了先行式存储再列式存储的方式。在每个row group中为列式存储,相对于sequenceFile的大小,有一定优势,大概比textFile小10%。
    当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。须要说明的是。RCFile在map阶段从远端拷贝仍然是拷贝整个数据块,而且复制到本地文件夹后,RCFile并非真正直接跳过不须要的列,并跳到须要读取的列, 而是通过扫描每个row group的头部定义来实现的。
    可是在整个HDFS Block 级别的头部并未定义每个列从哪个row group起始到哪个row group结束。所以在读取全部列的情况下。RCFile的性能反而没有SequenceFile高。

  • 创建并比较

    1. create table page_views_rcfile(
    2. track_time string,
    3. url string,
    4. session_id string,
    5. referer string,
    6. ip string,
    7. end_user_id string,
    8. city_id string
    9. )ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    10. STORED AS RCFILE;
    

    插入数据:

    1. insert into table page_views_rcfile select * from page_views;
    

    查看大小:

    1. hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views_rcfile
    2. 17.9 M  /user/hive/warehouse/hive.db/page_views_rcfile
    

ORC

  • 存储说明
    存储格式在Hive的应用

ORC文件:保存在文件系统上的普通二进制文件,一个ORC文件中可以包含多个stripe,每一个stripe包含多条记录,这些记录按照列进行独立存储,对应到Parquet中的row group的概念。
文件级元数据:包括文件的描述信息PostScript、文件meta信息(包括整个文件的统计信息)、所有stripe的信息和文件schema信息。
stripe:一组行形成一个stripe,每次读取文件是以行组为单位的,一般为HDFS的块大小,保存了每一列的索引和数据。
stripe元数据:保存stripe的位置、每一个列的在该stripe的统计信息以及所有的stream类型和位置。
row group:索引的最小单位,一个stripe中包含多个row group,默认为10000个值组成。
stream:一个stream表示文件中一段有效的数据,包括索引和数据两类。索引stream保存每一个row group的位置和统计信息,数据stream包括多种类型的数据,具体需要哪几种是由该列类型和编码方式决定。

  • ORC 简介
    ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度。和Parquet类似,它并不是一个单纯的列式存储格式,仍然是首先根据行组分割整个表,在每一个行组内进行按列存储。ORC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗,目前也被Spark SQL、Presto等查询引擎支持,但是Impala对于ORC目前没有支持,仍然使用Parquet作为主要的列式存储格式。2015年ORC项目被Apache项目基金会提升为Apache*项目。ORC具有以下一些优势:

    1. ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。
    2. 文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
    3. 提供了多种索引,row group index、bloom filter index。
    4. ORC可以支持复杂的数据结构(比如Map等)
  • ORC文件读取

    1. 读取ORC文件是从尾部开始的,第一次读取16KB的大小,尽可能的将Postscript和Footer数据都读入内存。文件的最后一个字节保存着PostScript的长度,它的长度不会超过256字节,PostScript中保存着整个文件的元数据信息,它包括文件的压缩格式、文件内部每一个压缩块的最大长度(每次分配内存的大小)、Footer长度,以及一些版本信息。在Postscript和Footer之间存储着整个文件的统计信息(上图中未画出),这部分的统计信息包括每一个stripe中每一列的信息,主要统计成员数、最大值、最小值、是否有空值等。

    2. 接下来读取文件的Footer信息,它包含了每一个stripe的长度和偏移量,该文件的schema信息(将schema树按照schema中的编号保存在数组中)、整个文件的统计信息以及每一个row group的行数。

    3. 处理stripe时首先从Footer中获取每一个stripe的其实位置和长度、每一个stripe的Footer数据(元数据,记录了index和data的的长度),整个striper被分为index和data两部分,stripe内部是按照row group进行分块的(每一个row group中多少条记录在文件的Footer中存储),row group内部按列存储。每一个row group由多个stream保存数据和索引信息。每一个stream的数据会根据该列的类型使用特定的压缩算法保存。

  • 几种创建ORC格式的方式

    1. CREATE TABLE ... STORED AS ORC
    2. ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC 
    3. SET hive.default.fileformat=Orc
    
  • 修改ORC格式参数可在HQL语句中的TBLPROPERTIES字段以key-value方式修改
    存储格式在Hive的应用
    总结: ORC能很大程序的节省存储和计算资源,但它在读写时候需要消耗额外的CPU资源来压缩和解压缩,当然这部分的CPU消耗是非常少的。
    对性能提升的另一个方面是通过在ORC文件中为每一个字段建立一个轻量级的索引,来判定一个文件中是否满足WHERE子句中的过滤条件。比如:当执行HQL语句”SELECT COUNT(1) FROM lxw1234_orc WHERE id = 0”时候,先从ORC文件的metadata中读取索引信息,快速定位到id=0所在的offsets,如果从索引信息中没有发现id=0的信息,则直接跳过该文件。

  • ORC的压缩比
    存储格式在Hive的应用

  • 创建ORC格式表

    1. create table page_views_orc_zlib
    2. ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    3. STORED AS ORC 
    4. TBLPROPERTIES("orc.compress"="ZLIB")
    5. as select * from page_views;
    
    6. [[email protected] ~]$ hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views_orc_zlib
    7. 2.8 M  /user/hive/warehouse/hive.db/page_views_orc_zlib
    

Parquet

  • Parquet 存储格式现在为apache一个*项目,它可以使用在hadoop 生态的大多数软件中。
  • parquet 使用列式存储,其性能可以个ORC比肩,可支持多种压缩技术。

  • 创建parquet格式表

    1. create table page_views_parquet
    2. ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    3. STORED AS PARQUET 
    4. as select * from page_views;
    

使用Bzip2压缩

    1. set parquet.compression=gzip;
    2. create table page_views_parquet_gzip
    3. ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
    4. STORED AS PARQUET 
    5. as select * from page_views;
相关标签: storage

上一篇:

下一篇: