跳到主要内容

Hive_Optimization

MapJoin​

当处理的数据量比较小的时候,可以采取 map join ,此时 hive 会将小表全部加载至内存中在 map 端进行 join 从而避免在 reducer 处理数据,如不符合 map join 条件,hive 解析器会将 join 操作转换为 common join 即在 reduce 端进行 join 这样会增加数据倾斜的概率。

行列过滤​

由于生产中 hive 分区表的数据通常会有亿级的数据量,此时合适的行列过滤操作对于数据处理来讲是非常必要的 对于列来讲,只拿需要的列,使用分区过滤,避免使用 select * 对于行来讲,在分区裁剪中,在进行外关联时,如果将副表的过滤条件写在 where 后面,那么就会先全表关联,再进行过滤操作。

列式存储​

对于大数据存储来将,合适的列存储格式是十分必要的

采用分区技术​

合理设置Map数​

mapred.min.split.size: 指的是数据的最小分割单元大小;min的默认值是1B

mapred.max.split.size: 指的是数据的最大分割单元大小;max的默认值是256MB

通过调整max可以起到调整map数的作用,减小max可以增加map数,增大max可以减少map数。

需要提醒的是,直接调整mapred.map.tasks这个参数是没有效果的。

https://www.cnblogs.com/swordfall/p/11037539.html

合理设置Reduce数​

Reduce个数并不是越多越好

(1)过多的启动和初始化Reduce也会消耗时间和资源;

(2)另外,有多少个Reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

在设置Reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的Reduce数;使单个Reduce任务处理数据量大小要合适;

小文件如何产生的?​

(1)动态分区插入数据,产生大量的小文件,从而导致map数量剧增;

(2)reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的);

(3)数据源本身就包含大量的小文件。

小文件解决方案​

(1)在Map执行前合并小文件,减少Map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能。

(2)merge // 输出合并小文件

SET hive.merge.mapfiles = true; -- 默认true,在map-only任务结束时合并小文件
SET hive.merge.mapredfiles = true; -- 默认false,在map-reduce任务结束时合并小文件
SET hive.merge.size.per.task = 268435456; -- 默认256M
SET hive.merge.smallfiles.avgsize = 16777216; -- 当输出文件的平均大小小于16m该值时,启动一个独立的map-reduce任务进行文件merge

(3)开启JVM重用

set mapreduce.job.jvm.numtasks=10

开启map端combiner(不影响最终业务逻辑)​

set hive.map.aggr=true;

压缩(选择快的)​

设置map端输出、中间结果压缩。(不完全是解决数据倾斜的问题,但是减少了IO读写和网络传输,能提高很多效率)

set hive.exec.compress.intermediate=true --启用中间数据压缩
set mapreduce.map.output.compress=true --启用最终数据压缩
set mapreduce.map.outout.compress.codec=…; --设置压缩方式

采用tez引擎或者spark引擎​

通过配置 hive on tez 或者 hive on spark 提升数据处理效率