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

hive文件类型与压缩 博客分类: 数据仓库 数据仓库数据存储压缩格式数据存储于压缩

程序员文章站 2024-03-15 09:13:17
...

1.概述

    数据仓库在建设使用的过程中,主要消耗的资源包含:CPU、MEMORY、DISK三部分。

  • 数据仓库在计算过程中主要消耗CPU和Memory资源,当然也会消耗一些DISK资源用来存储计算过程中的临时结果。但是主要优化的方向,还是降低CPU和MEMORY的消耗,这方面主要依赖于模型设计的合理性,所以在模型设计阶段增加模型设计review的步骤,保证模型设计的合理性。
  • 数据仓库在数据的存储阶段主要消耗MEMORY和DISK资源。memory资源主要是在NameNode存储文件信息的时候消耗掉;DISK在存储数据的时候消耗掉。在这个阶段需要严格控制HIVE表的的定义,来降低资源的消耗。

    本次主要探讨是数据仓库在数据存储阶段对资源消耗的优化,下面将通过2个方面展开,分别是:数据仓库如何配置,可以实现数据压缩,降低数据的存储量,达到减少对DISK的消耗;数仓表如何设计,可以降低文件信息存储量,达到减少对MEMORY的消耗;

2.数据仓库文件压缩

    hive在存储数据时支持通过不同的文件类型来组织,并且为了节省相应的存储资源,也提供了多种类型的压缩算法,供用户选择。只要是配置正确的文件类型和压缩类型,hive都可以按预期读取并解析数据,不影响上层HQL语句的使用。例如:SequenceFile本身的结构已经设计了对内容进行压缩,所以对于SequenceFile文件的压缩,并不是先生成SequenceFile文件,再对文件进行压缩;而是生成SequenceFile文件时,就对其中的内容字段进行压缩。最终压缩后,对外仍然体现为一个SequenceFile。RCFile、ORCFile、Parquet、Avro对于压缩的处理方式与SequenceFile相同。

    hive支持的文件类型有:TextFile、SequenceFile、RCFile、ORCFile、Parquet、Avro。

    hive支持的压缩算法有:

序号 压缩格式 算法 多文件 可分割性 工具 工具压缩后扩展名
1 DEFLATE DEFLATE .deflate
2 Gzip DEFLATE gzip .gz
3 bzip2 bzip2 bzip2 .bz2
4 LZO LZO lzop .lzo
5 LZ4 ??? ?? ?? ??? ???
6 Snappy ??? ?? ?? ??? ???
7 ZLIB ??? ?? ?? ??? ???
8 ZIP DEFLATE 是,在文件范围内 zip .zip

2.1.TextFile

  • TextFile是hive数据表的默认格式,存储方式:行存储;
  • 可以采用多种压缩方式,但是部分压缩算法压缩数据后生成的文件是不支持split;
  • 压缩后的数据在反序列化过程中,必须逐个字段判断是不是分隔符和行结束符,因此反序列化开销会比SequenceFile高几十倍。

2.1.1.TextFile文件,非压缩

--创建一个表,格式为文本文件:
CREATE EXTERNAL TABLE student_text (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--导入数据到此表中,将启动MR任务
INSERT OVERWRITE TABLE student_text SELECT * FROM student;

    可以看到生成的数据文件的格式为非压缩的文本文件:

hdfs dfs -cat /user/hive/warehouse/student_text/000000_0
 
1001810081,cheyo
1001810082,pku
1001810083,rocky
1001810084,stephen
2002820081,sql
2002820082,hello
2002820083,hijj
3001810081,hhhhhhh
3001810082,abbbbbb

2.1.2.TextFile文件,Deflate压缩

--创建一个表,格式为文件文件:
CREATE TABLE student_text_def (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--设置压缩类型为Gzip压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.DefaultCodec;
--导入数据:
INSERT OVERWRITE TABLE student_text_def SELECT * FROM student;
--查看数据
SELECT * FROM student_text_def;

     查看数据文件,可以看到数据文件为多个.deflate文件

hdfs dfs -ls /user/hive/warehouse/student_text_def/
-rw-r--r--   2015-09-16 12:48 /user/hive/warehouse/student_text_def/000000_0.deflate
-rw-r--r--   2015-09-16 12:48 /user/hive/warehouse/student_text_def/000001_0.deflate
-rw-r--r--   2015-09-16 12:48 /user/hive/warehouse/student_text_def/000002_0.deflate

2.1.3.TextFile文件,Gzip压缩

--创建一个表,格式为文件文件:
CREATE TABLE student_text_gzip (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--设置压缩类型为Gzip压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
 
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
--导入数据:
INSERT OVERWRITE TABLE student_text_gzip SELECT * FROM student;
--查看数据
SELECT * FROM student_text_gzip;

     查看数据文件,可以看到数据文件为多个.gz文件。解压.gz文件,可以看到明文文本:

hdfs dfs -ls /user/hive/warehouse/student_text_gzip/
-rw-r--r--  2015-09-15 10:03 /user/hive/warehouse/student_text_gzip/000000_0.gz
-rw-r--r--  2015-09-15 10:03 /user/hive/warehouse/student_text_gzip/000001_0.gz
-rw-r--r--  2015-09-15 10:03 /user/hive/warehouse/student_text_gzip/000002_0.gz

2.1.4.TextFile文件,Bzip2压缩

--创建一个表,格式为文件文件:
CREATE TABLE student_text_bzip2 (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--设置压缩类型为Bzip2压缩:
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec;
--导入数据
INSERT OVERWRITE TABLE student_text_bzip2 SELECT * FROM student;
--查看数据:
SELECT * FROM student_text_bzip2;

     查看数据文件,可看到数据文件为多个.bz2文件。解开.bz2文件,可以看到明文文本:

hdfs dfs -ls /user/hive/warehouse/student_text_bzip2
-rw-r--r--  2015-09-15 10:09 /user/hive/warehouse/student_text_bzip2/000000_0.bz2
-rw-r--r--  2015-09-15 10:09 /user/hive/warehouse/student_text_bzip2/000001_0.bz2
-rw-r--r--  2015-09-15 10:09 /user/hive/warehouse/student_text_bzip2/000002_0.bz2

2.1.5.TextFile文件,Lzo压缩

--创建表
CREATE TABLE student_text_lzo (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--设置为LZO压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec;
--导入数据
INSERT OVERWRITE TABLE student_text_lzo SELECT * FROM student;
--查询数据
SELECT * FROM student_text_lzo;

 查看数据文件,可以看到数据文件为多个.lzo压缩。解开.lzo文件,可以看到明文文件。(需要安装lzop库)

2.1.6.TextFile文件,Lz4压缩

--创建表
CREATE TABLE student_text_lz4 (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--设置为LZ4压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.Lz4Codec;
--导入数据
INSERT OVERWRITE TABLE student_text_lz4 SELECT * FROM student;

    查看数据文件,可看到数据文件为多个.lz4压缩。使用cat查看.lz4文件,可以看到是压缩后的文本。

hdfs dfs -ls /user/hive/warehouse/student_text_lz4
-rw-r--r-- 2015-09-16 12:06 /user/hive/warehouse/student_text_lz4/000000_0.lz4
-rw-r--r-- 2015-09-16 12:06 /user/hive/warehouse/student_text_lz4/000001_0.lz4
-rw-r--r-- 2015-09-16 12:06 /user/hive/warehouse/student_text_lz4/000002_0.lz4

2.1.7.TextFile文件,Snappy压缩

--创建表
CREATE TABLE student_text_snappy (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
--设置压缩
SET hive.exec.compress.output=true;
SET mapred.compress.map.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression=org.apache.hadoop.io.compress.SnappyCodec;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
SET io.compression.codecs=org.apache.hadoop.io.compress.SnappyCodec;
--导入数据
INSERT OVERWRITE TABLE student_text_snappy SELECT * FROM student;
--查询数据
SELECT * FROM student_text_snappy;

     查看数据文件,可看到数据文件多个.snappy压缩文件。使用cat查看.snappy文件,可以看到是压缩后的文本:

hdfs dfs -ls /user/hive/warehouse/student_text_snappy
Found 3 items
-rw-r--r--   2015-09-15 16:42 /user/hive/warehouse/student_text_snappy/000000_0.snappy
-rw-r--r--   2015-09-15 16:42 /user/hive/warehouse/student_text_snappy/000001_0.snappy
-rw-r--r--   2015-09-15 16:42 /user/hive/warehouse/student_text_snappy/000002_0.snappy

2.2.SequenceFile文件

    SequenceFile是Hadoop API提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用hadoop的标准Writable接口实现序列化和反序列化。它与Hadoop API中的MapFile是互相兼容的。hive中的SequenceFile继承自hadoop API的SequenceFile,不过它的key为空,使用value存放实际的值,这样是为了避免MR在运行map阶段的排序过程。

  • SequenceFile是一种二进制文件,以<key,value>的形式序列化到文件中。存储方式:行存储;
  • 支持三种压缩类型:None、Record、Block。默认采用Record,但是Record压缩率低;一般建议使用Block压缩;
  • 优势是文件和Hadoop API的MapFile是相互兼容的。

2.2.1.SequenceFile,Deflate压缩

--创建一个表,格式为文件文件:
CREATE TABLE student_seq_def (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS SEQUENCEFILE;
--设置压缩算法为Deflate压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.DeflateCodec;
--设置压缩类型为block
SET mapred.output.compression.type=BLOCK
--导入数据:
INSERT OVERWRITE TABLE student_seq_def SELECT * FROM student;
--查看数据
SELECT * FROM student_seq_def;

    查看数据文件,是一个密文的文件。

hdfs dfs -ls /user/hive/warehouse/student_seq_def/
-rw-r--r--  /user/hive/warehouse/student_seq_def/000000_0

2.2.2.SequenceFile,Gzip压缩

--创建一个表,格式为文件文件:
CREATE TABLE student_seq_gzip (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS SEQUENCEFILE;
--设置压缩类型为Gzip压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
--设置压缩类型为block
SET mapred.output.compression.type=BLOCK
--导入数据:
INSERT OVERWRITE TABLE student_seq_gzip SELECT * FROM student;
--查看数据
SELECT * FROM student_seq_gzip;

    查看数据文件,是一个密文的文件,无法通过gzip解压:

hdfs dfs -ls /user/hive/warehouse/student_seq_gzip/
-rw-r--r--  /user/hive/warehouse/student_seq_gzip/000000_0

2.3.RcFile

    存储方式:数据按行分块,每块按列存储。结合了行存储和列存储的有点:

  • 首先RCFile保证同一行的数据位于同一节点,因此元组重构开销很低
  • 其次像列存储一样,RCFile能够利用列维度的数据压缩,并且能跳过不必要的列读取

    RCFile的一个行组包括三部分:

  1. 第一部分是行组头部的【同步标识】,主要用于分割HDFS块中的两个连续行组;
  2. 第二部分是行组的【元数据头部】,用户存储行组单元的信息,包括行组中的记录数、每个列的字节数、列中每个域的字节数;
  3. 第三部分是【表格数据段】,即实际的列存储数据。在该部分中,同一列的所有域顺序存储。

    实际的存储如下图:

hive文件类型与压缩
            
    
    博客分类: 数据仓库 数据仓库数据存储压缩格式数据存储于压缩
 数据追加:RCFile不支持任意方式的数据写操作,仅提供一种追加接口,这是因为底层的HDFS当前仅仅支持数据追加写文件尾部。

    行组大小:行组变大有助于提高数据压缩的效率,但是可能会损害数据的读取性能,因为这样增加了 Lazy 解压性能的消耗。而且行组变大会占用更多的内存,这会影响并发执行的其他MR作业。 考虑到存储空间和查询效率两个方面,Facebook 选择 4MB 作为默认的行组大小,当然也允许用户自行选择参数进行配置。

2.3.1.RcFile,Gzip压缩

CREATE TABLE student_rcfile_gzip (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS RCFILE;
 
--设置压缩类型为Gzip压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
SET io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;
--导入数据:
INSERT OVERWRITE TABLE student_rcfile_gzip SELECT id,name FROM student;
--查看数据
SELECT * FROM student_rcfile_gzip;

2.4.ORCFile

    ORCFile有自己的参数设置压缩格式,一般不使用上述Hive参数设置压缩参数。参考文档:LanguageManual ORC

  • 存储方式:数据按行分块,每块按照列存储;
  • 压缩快 快速列存取
  • 效率比RCFile高,是RCFile的改良版本。

2.4.1.ORCFile,Zlib压缩

--创建表
CREATE TABLE student_orcfile_zlib (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS ORCFILE TBLPROPERTIES ("orc.compress"="ZLIB");
 
--导入数据
INSERT OVERWRITE TABLE student_orcfile_zlib SELECT id,name FROM student;
--查询数据
SELECT * FROM student_orcfile_zlib;

2.4.2.ORCFile,Snappy压缩

--创建表
CREATE TABLE student_orcfile_snappy2 (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS ORCFILE TBLPROPERTIES ("orc.compress"="SNAPPY");
 
--导入数据
INSERT OVERWRITE TABLE student_orcfile_snappy2 SELECT id,name FROM student;
--查询数据
SELECT * FROM student_orcfile_snappy2;

2.4.3.不推荐

    一般不推荐使用下述方式。采用下述方式压缩后,结果与上面同类型压缩(Snappy)不同。

--创建表
CREATE TABLE student_orcfile_snappy (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS ORCFILE;
--设置压缩
SET hive.exec.compress.output=true;
SET mapred.compress.map.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression=org.apache.hadoop.io.compress.SnappyCodec;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
SET io.compression.codecs=org.apache.hadoop.io.compress.SnappyCodec;
--导入数据
INSERT OVERWRITE TABLE student_orcfile_snappy SELECT id,name FROM student;
--查询数据
SELECT * FROM student_orcfile_snappy;

2.5.Parquet

2.5.1.Parquet,Snappy压缩

--创建表
CREATE TABLE student_parquet_snappy (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS PARQUET;
--设置压缩
SET hive.exec.compress.output=true;
SET mapred.compress.map.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression=org.apache.hadoop.io.compress.SnappyCodec;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
SET io.compression.codecs=org.apache.hadoop.io.compress.SnappyCodec;
--导入数据
INSERT OVERWRITE TABLE student_parquet_snappy SELECT id,name FROM student;
--查询数据
SELECT * FROM student_parquet_snappy;

2.6.Avro

2.6.1.Avro,Snappy压缩

--创建表
CREATE TABLE student_avro_snappy (id STRING, name STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS AVRO;
--设置压缩
SET hive.exec.compress.output=true;
SET mapred.compress.map.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression=org.apache.hadoop.io.compress.SnappyCodec;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
SET io.compression.codecs=org.apache.hadoop.io.compress.SnappyCodec;
--导入数据
INSERT OVERWRITE TABLE student_avro_snappy SELECT id,name FROM student;
--查询数据
SELECT * FROM student_avro_snappy;

2.7.不同压缩算法比较

压缩算法
TextFile
Parquet格式
ORCFile
RCFile
不压缩 119.2G 54.1G 20.0G 98G
snappy 30.2G 23.6G 13.6G 27.0G
Gzip 18.8G 14.1G 不支持 15.2G
ZLib 不支持 不支持 10.1G 不支持

3.数仓表分区优化

    数据仓库创建数仓表时,ETL开发人员基于使用习惯和处理的方便性,经常创建多层分区,来存储数据。但是过多的分区会消耗NameNode大量的资源,并且也会引入小文件的问题。所以对于创建数仓表的分区,要求如下:

  • 对于统计数据表、数据量不大的基础表、业务上无累计快照和周期性快照要求的数据表,尽可能的不创建分区,而采用数据合并回写的方式解决;
  • 对于一些数据量大的表,如果需要创建分区,提高插叙过程中数据的加载速度,尽可能的只做天级分区。而对于卖点的原始数据,这种特大的数据量的,可以采用小时分区。对于月分区,坚决去掉。
  • 对于一些周期快照和累计快照的表,我们尽可能只创建日分区。
  • hive文件类型与压缩
            
    
    博客分类: 数据仓库 数据仓库数据存储压缩格式数据存储于压缩
  • 大小: 174.4 KB