黑洞

这里藏着一些独特的想法

0%

Hive中的数据压缩与数据存储格式

数据压缩

Hive的默认执行引擎是MapReduce,因此通常所说的Hive压缩指的是MapReduce中的压缩。

优点:

  • 减少存储磁盘空间,降低单节点的磁盘 IO。
  • 由于压缩后的数据占用的带宽更少,因此可以加快数据在 Hadoop 集群流动
    的速度,减少网络传输带宽。

缺点:

  • 需要花费额外的时间、CPU和内存资源,做压缩和解压缩计算。

mr-compress.jpg

  1. 需要分析处理的数据在进入map 前可以压缩,然后解压处理
  2. map 处理完成后的输出可以压缩,这样可以减少网络 I/O(reduce 通常和 map 不在同一节点上)
  3. reduce 拷贝压缩的数据后进行解压,处理完成后可以压缩存储在 hdfs 上,以减少磁盘占用量。

mr-compress-detail.jpg

Hadoop 中支持的压缩算法

压缩格式 压缩格式所在的类
Zlib 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.LzoCodec
Lz4 org.apache.hadoop.io.compress.Lz4Codec
Snappy org.apache.hadoop.io.compress.SnappyCodec

推荐使用谷歌推出的Snappy压缩算法

设置压缩参数

注意: 本质是MapReduce的压缩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 开启 hive 中间传输数据压缩功能 也就是map的输出压缩
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;

-- 设置Hive的最终输出压缩 也就是Reduce输出压缩
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 最终数据输出压缩为 块压缩 还可以指定RECORD
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

-- 设置orc存储策略为更压缩 compression | speed
set hive.exec.orc.compression.strategy=COMPRESSION;

设置完毕后,使用load语句加载并不能压缩源数据,可以使用ctas语句,因为它经过MapReduce。

1
2
3
4
5
6
--设置完毕之后 只有当HiveSQL底层通过MapReduce程序执行 才会涉及压缩
--已有普通格式的表
select * from student;

--使用ctas语句创建新表 此时 student_snappy 这个表就是被压缩的
create table student_snappy as select * from student;

数据存储格式

列式存储和行式存储

逻辑表中的数据,最终需要落到磁盘上以文件的形式存储。有两种常见的存储形式:行式存储和列式存储。

row-col-layout.jpg

行式存储

  • 优点:

    • 相关的数据是保存在一起,比较符合面向对象的思维,因为一行数据就是一条记录。
    • 这种存储格式比较方便进行 INSERT/UPDATE 操作。
  • 缺点:

    • 如果查询只涉及某几个列,它会把整行数据都读取出来,不能跳过不必要的列读取。当然数据比较少,一般没啥问题,如果数据量比较大就比较影响性能。
    • 由于每一行中,列的数据类型不一致,导致不容易获得一个极高的压缩比,也就是空间利用率不高。
    • 不是所有的列都适合作为索引。

列式存储

  • 优点:

    • 查询时,只有涉及到的列才会被查询,不会把所有列都查询出来,即可以跳过不必要的列查询。
    • 高效的压缩率,不仅节省储存空间也节省计算内存和CPU。
    • 任何列都可以作为索引。
  • 缺点:

    • INSERT/UPDATE 很麻烦或者不方便。
    • 不适合扫描小量的数据。

Hive 支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC(列式存储)、PARQUET(列式存储)。

对于数据分析而言,列式存储显然更符合我们的工作场景。因此,接下来重点讲一下ORC与压缩的共同使用。

存储格式和压缩

创建ORC表文件

1
2
3
4
5
6
7
8
9
10
11
12
13
set hive.exec.orc.compression.strategy=COMPRESSION;
CREATE TABLE log_orc(
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 ;
-- 默认使用Zlib压缩

创建非压缩的ORC表文件

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE log_orc_none(
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"="NONE");
-- 设置为NONE时不使用任何压缩算法

创建使用Snappy压缩的ORC表文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--写入时压缩生效
set hive.exec.orc.compression.strategy=COMPRESSION;
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");
-- 使用Snappy算法压缩

在实际的项目开发当中,hive表的数据存储格式一般选择ORC或PARQUET,压缩方式一般选择Snappy。

如果觉得文章写得不错或对您有帮助,请我喝杯柠檬茶吧!