1 Hadoop压缩概述

Hive中的压缩算法与Hadoop中的压缩算法保持一致,可以把Hive当作Hadoop的一个客户端。

2 Hive文件格式

  Hive表中常用的数据存储格式:text file(行式存储)、orc(列式存储)、parquet(列式存储)、sequence file(序列化文件,行式存储)等。

2.1 Text File

  Text File是Hive默认的文件格式,文本文件的一行内容对应hive表中的一行记录,属于行式存储。

--通过建表语句指定文件格式为文本文件:
create table textfile_table(
    ...
)
stored as textfile;

2.2 ORC

2.2.1 ORC概述

  ORC是列式存储的文件格式,可以提高hive读写数据和处理数据的性能。

如何查看hive的表压缩格式 hive文件压缩格式_大数据


  左边为逻辑表。

  右边第一个为行式存储:取文件的一行数据存储到相邻的位置;

  第二个为列式存储:取文件的一列数据存储到相邻的位置。

(1)行式存储特点:

  查询满足条件的一整行数据的时候,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。列式存储查找一行数据时需要去每个字段中找对应的每个列的值。

(2)列式存储特点:

  因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;

  因为每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

2.2.2 ORC文件基本格式

ORC文件结构:

如何查看hive的表压缩格式 hive文件压缩格式_如何查看hive的表压缩格式_02


  每个Orc文件由Header、Body和Tail三部分组成。

(1)Header内容为ORC,用于表示文件类型。

(2)Body由1个或多个stripe组成,每个stripe一般为HDFS的块大小,每一个stripe包含多条记录,这些记录按照列进行独立存储,每个stripe里有三部分组成,分别是Index Data,Row Data,Stripe Footer:
  (i)Index Data:一个轻量级的index,默认是为各列每隔1W行做一个索引。每个索引会记录第n万行的位置,和最近一万行的最大值和最小值等信息(便于进行根据where的值过滤查询)。
  (ii)Row Data:存储具体的数据,按列进行存储,并对每个列进行编码,分成多个Stream来存储。
  (iii)Stripe Footer:存放的是各个Stream的位置以及各column的编码信息。

(3)Tail由File Footer和PostScript组成:
  (i)File Footer中保存了各Stripe的其实位置、索引长度、数据长度等信息,各Column的统计信息等;
  (ii)PostScript记录了整个文件的压缩类型以及File Footer的长度信息等。

ORC文件读取流程:
(1)从文件的最后一个字节开始读Postscript的长度;
(2)找到完整的Postscript信息;
(3)根据File Footer的长度定位到File Footer;
(4)读取stripe信息;
(5)根据索引长度得到Index Data;
(6)根据索引信息拿到对应的列;
(7)根据Stripe Footer解析取的数据信息。

语法:

create table table_name(
    ...
)
stored as orc
--不用谢row format delimited fields terminated by '\t'了,只有在文本文件中才需要写
tblproperties (property_name=property_value,...);    --设置参数

ORC文件格式支持的参数:

如何查看hive的表压缩格式 hive文件压缩格式_如何查看hive的表压缩格式_03


  不能用load往orc表中导入数据,因为load是文本文件移动操作。如果使用load导入数据需要先创建一个普通的表,用load往表中导入数据,再用insert…select…从表中读出数据写入orc表中。

2.3 Parquet

Parquet文件结构:

如何查看hive的表压缩格式 hive文件压缩格式_如何查看hive的表压缩格式_04


(1)文件的首尾都是该文件的Magic Code,用于校验它是否是一个Parquet文件都占 4个字节。首尾中间由若干个Row Group和一个Footer(File Meta Data)组成。

(2)每个Row Group(行组)包含多个Column Chunk(列块),每个Column Chunk包含多个Page。
  (i)行组(Row Group):一个行组对应逻辑表中的若干行。
  (ii)列块(Column Chunk):一个行组中的一列保存在一个列块中。
  (iii)页(Page):一个列块的数据会划分为若干个页。

(3)Footer(File Meta Data)中存储了每个行组(Row Group)中的每个列快(Column Chunk)的元数据信息,元数据信息包含了该列的数据类型、该列的编码方式、该类的Data Page位置等信息。

Parquet文件读取流程:
(1)跳过文件的最后4个字节找到Footer长度;
(2)根据Footer长度拿到完整的Footer信息;
(3)根据Footer里的每个列块的元数据信息找到列块。

语法:

create tabel table_name(
    ...
)
stored as parquet
tblproperties (property_name=property_value,...);

Parquet文件格式支持的参数:

如何查看hive的表压缩格式 hive文件压缩格式_如何查看hive的表压缩格式_05

3 压缩

  在Hive表和计算过程中使用数据压缩考研有效利用磁盘空间和提高查询性能。

3.1 压缩Hive表数据

  对于不同Hive文件格式存储的表,声明数据压缩方式不同。

3.1.1 Text File

  文件类型为Text File的表数据在进行数据压缩时不需要在建表语句中声明,可以直接向表中导入压缩后的文件,HIve在查询数据时可以自动识别压缩格式进行解压。
  在执行导入数据的SQL前,需要设置参数来保证写入表的数据是被压缩的。

--SQL语句的最终输出结果是否压缩:
set hive.exec.compress.output=true;
--输出结果的压缩格式(以snappy为例):
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

3.1.2 ORC

  文件类型为ORC的表数据在进行数据压缩时需要在建表语句中声明压缩格式:

--在建表语句中声明ORC文件的数据压缩:
create table table_name(
    ...
)
stored as orc
tblproperties ("orc.compress"="snappy");

3.1.3 Parquet

  文件类型为Parquet的表数据在进行数据压缩时需要在建表语句中声明压缩格式:

create table table_name(
    ...
)
stored as parquet
tblproperties ("parquet.compression"="snappy");

3.2 计算过程使用压缩

3.2.1 对单个MR的中间结果进行压缩

  单个MR的中间结果指的是Mapper输出的数据,压缩该数据库降低Shuffle阶段的IO压力,配置以下参数:

--开启MapReduce中间数据压缩功能
set mapreduce.map.output.compress=true;

--设置MapReduce中间数据的压缩方式(以snappy为例)
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

3.2.2 对单条SQL语句的中间结果进行压缩

  一个SQL数据可能通过MR进行计算,单条SQL语句的中间结果指两个MR之间的临时数据,配置以下参数:

--是否对两个MR之间的临时数据进行压缩
set hive.exec.compress.intermediate=true;

--设置两个MR之间的压缩格式(以snappy为例)
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;