表数据优化
1 文件格式
文件格式 | 优点 | 缺点 | 应用场景 |
---|---|---|---|
TextFile | 1)是最常用且默认的格式 2)不需要经过处理,可以直接cat查看 3)可以使用任意的分隔符进行分割 4)便于和其他工具(Pig, grep, sed, awk)共享数据 5)可以搭配Gzip、Bzip2、Snappy等压缩一起使用 | 1)耗费存储空间,I/O性能较低 2)结合压缩时Hive不进行数据切分合并,不能进行并行操作,查询效率低 3)按行存储,读取列的性能差 | 1)适合于小量数据的存储查询 2)一般用于做第一层数据加载和测试使用 |
SequenceFile | 1)以二进制的KV形式存储数据,与底层交互更加友好,性能更快 2)可压缩、可分割,优化磁盘利用率和I/O 3)可并行操作数据,查询效率高 4)SequenceFile也可以用于存储多个小文件 | 1)存储空间消耗最大 2)与非Hadoop生态系统之外的工具不兼容 3)构建SequenceFile需要通过TextFile文件转化加载。(即只能通过insert+select写入) | 适合于小量数据,但是查询列比较多的场景 |
Parquet | 1)更高效的压缩和编码 2)可用于多种数据处理框架 | 不支持update, insert, delete, ACID | 适用于字段数非常多,无更新,只取部分列的查询 |
ORC | 1)列式存储,存储效率非常高 2)可压缩,高效的列存取 3)查询效率较高,支持索引 4)支持矢量化查询 | 1)加载时性能消耗较大 2)需要通过text文件转化生成 3)读取全量数据时性能较差 | 适用于Hive中大型的存储、查询 |
2 数据压缩
2.1 概述
- 数据压缩对于节省资源、最小化磁盘I/O和网络传输非常有帮助
- 在任意MapReduce阶段启用压缩都可以改善端到端处理时间并减少I/O和网络流量
优点:
1)减小文件存储所占空间
2)加快文件传输效率,从而提高系统的处理速度
3)降低IO读写的次数
缺点:对文件解压,加重CPU负荷,压缩算法越复杂,解压时间越长
Hadoop中各种压缩算法对比:
2.2 压缩配置
-- 配置MapReduce
--开启输出压缩
set mapreduce.output.fileoutputformat.compress=true;
--配置压缩类型为Snappy
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 配置Hive
-- 中间结果压缩
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
-- 输出结果压缩
set hive.exec.compress.output=true;
-- 举例
-- 1)创建表,指定为textfile格式,并使用snappy压缩
create table tb_sogou_snappy
stored as textfile
as select * from tb_sogou_source;
-- 2)创建表,指定为orc格式,并使用snappy压缩
create table tb_sogou_orc_snappy
stored as orc tblproperties ("orc.compress"="SNAPPY")
as select * from tb_sogou_source;
3 存储优化
3.1 避免小文件生成
-- 如果hive的程序,只有maptask,将MapTask产生的所有小文件进行合并
set hive.merge.mapfiles=true;
-- 如果hive的程序,有Map和ReduceTask,将ReduceTask产生的所有小文件进行合并
set hive.merge.mapredfiles=true;
-- 每一个合并的文件的大小
set hive.merge.size.per.task=256000000;
-- 平均每个文件的大小,如果小于这个值就会进行合并
set hive.merge.smallfiles.avgsize=16000000;
3.2 读取小文件
-- 设置Hive中底层MapReduce读取数据的输入类:将所有文件合并为一个大文件作为输入
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
3.3 ORC文件索引
ORC提供了两种索引机制:Row Group Index 和 Bloom Filter Index可以帮助提高查询ORC文件的性能,避免不必要的数据扫描。
3.3.1 Row Group Index
1)当查询中有<,>,=的操作时,会根据min/max值,跳过扫描不包含的stripes
2)每个stripe建立的包含min/max值的索引,就称为Row Group Index行组索引
3)建立ORC格式表时,指定表参数’orc.create.index’=’true’之后,便会建立Row Group Index
4)向表中加载数据时,必须对需要使用索引的字段进行排序
5)这种索引主要用于数值型字段的范围查询过滤优化上
-- 开启索引配置
set hive.optimize.index.filter=true;
-- 创建表,并指定构建索引
create table tb_sogou_orc_index
stored as orc tblproperties ("orc.create.index"="true")
as select * from tb_sogou_source
distribute by stime
sort by stime;
-- 当进行范围或者等值查询(<,>,=)时就可以基于构建的索引进行查询
select count(*) from tb_sogou_orc_index where stime > '12:00:00' and stime < '18:00:00';
3.3.2 Bloom Filter Index
- 通过表参数”orc.bloom.filter.columns”=”columnName……”来指定为哪些字段建立BloomFilter索引
- 当查询条件中包含对该字段的=号过滤时候,先从BloomFilter中获取以下是否包含该值,如果不包含,则跳过该stripe
-- 创建表,并指定构建索引
create table tb_sogou_orc_bloom
stored as orc tblproperties ("orc.create.index"="true","orc.bloom.filter.columns"="stime,userid")
as select * from tb_sogou_source
distribute by stime
sort by stime;
-- stime的范围过滤可以走row group index,userid的过滤可以走bloom filter index
select
count(*)
from tb_sogou_orc_index
where stime > '12:00:00' and stime < '18:00:00'
and userid = '3933365481995287' ;
3.4 ORC矢量化查询
-- 按照每批1024行读取数据
-- 必须以ORC格式存储数据
set hive.vectorized.execution.enabled = true;
set hive.vectorized.execution.reduce.enabled = true;