Hive08-压缩和存储

NiuMT 2020-07-03 20:58:30
Hive

Hadoop 源码编译支持Snappy 压缩

  1. 准备编译环境

    yum install svn
    yum install autoconf automake libtool cmake
    yum install ncurses-devel
    yum install openssl-devel
    yum install gcc*
    
  2. 编译安装snappy

    cd snappy-1.1.3/
    ./configure
    make
    make install
    '查看snappy 库文件
    ls -lh /usr/local/lib |grep snappy
    
  3. 编译安装protobuf

    cd protobuf-2.5.0/
    ./configure
    make
    make install
    '查看protobuf 版本以测试是否安装成功
    protoc --version
    
  4. 编译hadoop native

    cd hadoop-2.7.2-src/
    mvn clean package -DskipTests -Pdist,native -Dtar -Dsnappy.lib=/usr/local/lib -Dbundle.snappy
    

    执行成功后,/opt/software/hadoop-2.7.2-src/hadoop-dist/target/hadoop-2.7.2.tar.gz 即为新生成的支持snappy 压缩的二进制安装包。

Hadoop 压缩配置

MR 支持的压缩编码

压缩格式 工具 算法 文件扩展名 是否可切分
DEFAULT DEFAULT .deflate
Gzip gzip DEFAULT .gz
bzip2 bzip2 bzip2 .bz2
LZO lzop LZO .lzo
Snappy Snappy .snappy

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

压缩格式 对应的编码/解码器
DEFAULT org.apache.hadoop.io.compress.DefaultCodec
Gzip org.apache.hadoop.io.compress.GzipCodec
bzip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compression.lzo.LzopCodec
Snappy org.apache.hadoop.io.compress.SnappyCodec

压缩性能的比较:

压缩算法 原始文件大小 压缩文件大小 压缩速度 解压速度
Gzip 8.3GB 1.8GB 17.5MB/s 58MB/s
bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s
LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s

压缩参数配置

core-site.xml

参数 默认值 阶段 建议
io.compression.codecs org.apache.hadoop.io.compress.DefaultCodec,
org.apache.hadoop.io.compress.GzipCodec,
org.apache.hadoop.io.compress.BZip2Codec,
org.apache.hadoop.io.compress.Lz4Codec
输入压缩 Hadoop 使用文件扩展名判断是否支持某种编解码器

mapred-site.xml

参数 默认值 阶段 建议
mapreduce.map.output.compress false mapper 输出 这个参数设为true启用压缩
mapreduce.map.output.compress.codec org.apache.hadoop.io.
compress.DefaultCodec
mapper 输出 使用LZO、LZ4 或snappy 编解码器在此阶段压缩数据
mapreduce.output.fileoutputformat.
compress
false reducer 输出 这个参数设为true启用压缩
mapreduce.output.fileoutputformat.
compress.codec
org.apache.hadoop.io
.compress. DefaultCodec
reducer 输出 使用标准工具或者编解码器,如gzip和bzip2
mapreduce.output.fileoutputformat.
compress.type
RECORD reducer 输出 SequenceFile 输出使用的压缩类型:NONE 和BLOCK

开启Map 输出阶段压缩

开启map 输出阶段压缩可以减少job 中map 和Reduce task 间数据传输量。具体配置如下:

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

开启Reduce 输出阶段压缩

当Hive 将输出写入到表中时, 输出内容同样可以进行压缩。属性
hive.exec.compress.output 控制着这个功能。用户可能需要保持默认设置文件中的默认值
false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

'开启hive 最终输出数据压缩功能
hive (default)>set hive.exec.compress.output=true;
'开启mapreduce 最终输出数据压缩
hive (default)>set mapreduce.output.fileoutputformat.compress=true;
'设置mapreduce 最终数据输出压缩方式
hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
'设置mapreduce 最终数据输出压缩为块压缩
hive (default)> set mapreduce.output.fileoutputformat.compress.type=BLOCK;
'测试一下输出结果是否是压缩文件
hive (default)> insert overwrite local directory '/opt/module/datas/distribute-result' select * from emp distribute by deptno sort by empno desc;

文件存储格式

Hive 支持的存储数的格式主要有:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET。图中左边为逻辑表,右边第一个为行式存储,第二个为列式存储。

列式存储和行式存储

image-20210114201111218

TEXTFILE 和SEQUENCEFILE 的存储格式都是基于行存储的;

ORC 和PARQUET 是基于列式存储的。

  1. 行存储的特点

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

  2. 列存储的特点

    因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

TextFile 格式

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

Orc 格式

Orc (Optimized Row Columnar)是Hive 0.11 版里引入的新的存储格式。

每个Orc 文件由1 个或多个stripe 组成,每个stripe 250MB 大小,这个Stripe 实际相当于RowGroup 概念,不过大小由4MB->250MB,这样应该能提升顺序读的吞吐率。每个Stripe 里有三部分组成,分别是Index Data,Row Data,Stripe Footer:

image-20210114201753983

每个文件有一个File Footer,这里面存的是每个Stripe 的行数,每个Column 的数据类型信息等;每个文件的尾部是一个PostScript,这里面记录了整个文件的压缩类型以及FileFooter的长度信息等。在读取文件时,会seek 到文件尾部读PostScript,从里面解析到File Footer长度,再读FileFooter,从里面解析到各个Stripe 信息,再读各个Stripe,即从后往前读。

Parquet 格式

Parquet 是面向分析型业务的列式存储格式,由Twitter 和Cloudera 合作开发,2015 年5月从Apache 的孵化器里毕业成为Apache 顶级项目。

Parquet 文件是以二进制方式存储的,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet 格式文件是自解析的。

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

image-20210114202357559

上图展示了一个Parquet 文件的内容,一个文件中可以存储多个行组,文件的首位都是该文件的Magic Code,用于校验它是否是一个Parquet 文件,Footer length 记录了文件元数据的大小,通过该值和文件长度可以计算出元数据的偏移量,文件的元数据中包括每一个行组的元数据信息和该文件存储数据的Schema 信息。除了文件中每一个行组的元数据,每一页的开始都会存储该页的元数据,在Parquet 中,有三种类型的页:数据页、字典页和索引页。数据页用于存储当前行组中该列的值,字典页存储该列值的编码字典,每一个列块中最多包含一个字典页,索引页用来存储当前行组下该列的索引,目前Parquet 中还不支持索引页。

存储和压缩结合

修改Hadoop 集群具有Snappy 压缩方式

'查看hadoop checknative 命令使用'
[atguigu@hadoop104 hadoop-2.7.2]$ hadoop checknative [-a|-h] check native hadoop and compression libraries availability
'查看hadoop 支持的压缩方式'
[atguigu@hadoop104 hadoop-2.7.2]$ hadoop checknative
17/12/24 20:32:52 WARN bzip2.Bzip2Factory: Failed to load/initialize native-bzip2 library system-native, will use pure-Java version
17/12/24 20:32:52 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
Native library checking:
hadoop: true
/opt/module/hadoop-2.7.2/lib/native/libhadoop.so
zlib: true /lib64/libz.so.1
snappy: false
lz4: true revision:99
bzip2: false

'将编译好的支持Snappy 压缩的hadoop-2.7.2.tar.gz 包导入到hadoop102 的 /opt/software 中'
'进入到/opt/software/hadoop-2.7.2/lib/native 路径可以看到支持Snappy 压缩的动态链接库'
libsnappy.a
libsnappy.la
libsnappy.so -> libsnappy.so.1.3.0
libsnappy.so.1 -> libsnappy.so.1.3.0
libsnappy.so.1.3.0
'拷贝/opt/software/hadoop-2.7.2/lib/native 里面的所有内容到开发集群的/opt/module/hadoop-2.7.2/lib/native 路径上'
'分发集群'
'再次查看hadoop 支持的压缩类型'
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop checknative
17/12/24 20:45:02 WARN bzip2.Bzip2Factory: Failed to load/initialize native-bzip2 library system-native, will usepure-Java version
17/12/24 20:45:02 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
Native library checking:
hadoop: true
/opt/module/hadoop-2.7.2/lib/native/libhadoop.so
zlib: true /lib64/libz.so.1
snappy: true
/opt/module/hadoop-2.7.2/lib/native/libsnappy.so.1
lz4: true revision:99
bzip2: false
'重新启动hadoop 集群和hive'

测试存储和压缩

在实际的项目开发当中,hive 表的数据存储格式一般选择:orc 或parquet。压缩方式一
般选择snappy,lzo。

'创建一个SNAPPY 压缩的ORC 存储方式:
create table log_orc_snappy(
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 orc tblproperties ("orc.compress"="SNAPPY");
'插入数据'
'查看插入后数据'
hive (default)> dfs -du -h /user/hive/warehouse/log_orc_none/;

ORC 存储方式的压缩:

Key Default Notes
orc.compress ZLIB high level compression (one of NONE, ZLIB, SNAPPY)
orc.compress.size 262,144 number of bytes in each compression chunk
orc.stripe.size 67,108,864 number of bytes in each stripe
orc.row.index.stride 10,000 number of rows between index entries (must be >= 1000)
orc.create.index true whether to create row indexes
orc.bloom.filter.columns “” comma separated list of column names for which bloom filter should be created
orc.bloom.filter.fpp 0.05 false positive probability for bloom filter (must >0.0 and <1.0)