Hive, 大数据

hive-09 压缩和存储

Hadoop压缩配置

MR支持的压缩编码

压缩格式算法文件扩展名是否可切分
DEFLATEDEFLATE.deflate
GzipDEFLATE.gz
bzip2bzip2.bz2
LZOLZO.lzo
SnappySnappy.snappy

为了支持多种压缩/解压算法,Hadoop引入了编码/解码器

压缩格式对应的编码/解码器
DEFLATEorg.apache.hadoop.io.compress.DefaultCodec
gziporg.apache.hadoop.io.compress.GzipCodec
bzip2org.apache.hadoop.io.compress.BZip2Codec
LZOcom.hadoop.compression.lzo.lzopCpdec
Snappyorg.apache.hadoop.io.compress.SnappyCodec

压缩参数配

开启Map输出阶段压缩(MR引擎)

中间过程压缩

开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量

  • 开启hive中间传输数据压缩功能
    • set hive.exec.compress.intermediate=true;
  • 开启mapreduce中map输出压缩功能
    • set mapreduce.map.output.compress=true
  • 设置mapreduce中map输出数据的压缩方式
    • set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec
  • 执行查询语句
    • select count(ename) name from emp;

开启Reduce输出阶段压缩

最终输出压缩

当hive将输出写入到表中时,输出内容同样可以进行压缩。

  • 开启hive最终输出数据压缩功能
    • set hive.exec.compress.output=true
  • 开启mapreduce最终输出数据压缩
    • set mapreduce.output.fileoutputformat.compress=true
  • 设置mapreduce最终数据输出压缩方式
    • set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec
  • 设置mapreduce最终数据输出压缩为块压缩
    • set mapreduce.output.fileoutputformat.compress.type=BLOCK
  • 测试
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress=true;
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
INSERT OVERWRITE DIRECTORY '/test/res'
SELECT *
FROM emp DISTRIBUTE BY deptno SORT BY empno DESC;

文件存储格式

Hive支持的存储数据的格式主要有:TEXTFILE、SEQUENCEFILE、ORC、PARQUET

列式存储和行式存储

extFile格式

默认格式,数据不做压缩,磁盘开销大,数据解析开销大,可结合Gzip和bzip2使用,但Gzip格式hive不会对数据进行切分,从而无法对数据进行并行操作

Orc格式

Orc:Optimized Row Columnar 是Hive1.0引入的新的存储格式

每个Orc由1和或多个stripe组成

每个stripe一般为HDFS的块大小

每一个stripe包含多条记录

这些记录按照列进行独立存储

每个stripe有三部分组成:index Data,Row Data,Stripe Footer

  • index Data:一个轻量级的index,默认是每隔1w行做一个索引,这里做的索引应该只是记录某行的各个字段在RowData中的offset
  • Row Data:存的是具体的数据,先去部分行,然后对这些行按列进行存储,对每个列进行编码,分成多个Stream来存储
  • Stripe Footer:存的是各个Stream的类型,长度等信息
    • 每个文件有一个FileFooter 这里面存的是每个Stripe的行数,每个Column的数据类型等信息
    • 每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等
    • 在读取文件是会seek到文件尾部读PostScript从里面解析到FileFooter的长度,再读FileFooter,从里面解析到各个Striper信息,再读各个Striper,即从后往前读

Parquet格式

spark默认文件格式parquet,解析做了特殊处理,运行效率会更高

Parquet文件是以二进制方式存储的,所以是不可以直接读取的,文件包括该文件的数据和元数据

Parquet格式文件是自解析的

  • 行组Row Group 每一个行组包含一定的行数,在一个HDFS文件中至少存储一个行组,类似于orc的stripe的概念
  • 列块Column Chunk 在一个行组中每一列保存在一个列块中
    • 行组中的所有列连续的存储在这个行组文件中
    • 一个列块中的值都是相同类型的
    • 不同的列块可能使用不同算法进行压缩
  • 页 page 每一个列块划分为多个页
    • 一个页就是最小的编码单位
    • 在同一个列块的不同页可能使用不同的编码方式

通常情况下,在存储Parquet数据的时候回按照Block大小设置行组的大小,由于一般情况下,每一个Mapper任务处理数据的最小单位是一个Block,这样可以把每一个行组由一个Mapper任务处理,增大任务执行并行度

创建一个ZLIB压缩的ORC存储方式

CREATE TABLE log_orc_zlib(
    name string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS orc
TBLPROPERTIES('orc.compress'='ZLIB')

创建一个SNAPPY压缩的parquet存储方式

CREATE TABLE log_parquet_snappy(
    name string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS parquet
TBLPROPERTIES('parquet.compress'='snappy')

推荐ORC结合snappy