#hive优化
1、Hive优化之减少数据扫描量
大数据主要特点就是数据量大,减少数据的扫描可以节省非常多的时间(像我们在学习阶段都学过的分区和分桶,就是这个原理)
1.1分区表
1.2分桶表
1.3矢量化读取
默认的读取为一行一行的读,一行一行的处理
开启矢量化读取,转变为一批一批的读,一批一批的处理,一批是1024行。
set hive.vectorized.execution.enabled=true;
必须是ORC存储格式才能使用
1.4读取零拷贝
示例: A表有 a,b,c,d,e 五个字段
select a,b,b from A where b=xxx and c between xx and xxx;
默认读取是把表中的所有数据都读到内存当中
如果开启读取零拷贝, 在读取数据的时候, 就不会将d和e这两个字段读取到内存中
2、hive优化之数据倾斜
2.1group by造成的倾斜
方案一:使用combiner(map端提前聚合)
set hive.map.aggr=true; 开启map端提前聚合操作(combiner)
在map端提前聚合,将聚合后的结果传给reduce以此降低数据倾斜风险
方案二:大combiner(负载均衡模式)
set hive.groupby.skewindata=true;
使用两个MR,第一个MR将数据均匀的落在的reducr上,进行聚合操作,形成局部结果
再运行第二个MR读取第一个MR运行的结果,通过相同key发往同一个reduce的方案,完成最终的聚合操作
注意:使用第二种方案后,不能再进行多列的多个distinct去重处理。
1、select ip ,count(distinct uid) from log group by ip;
2、select ip ,count(distince uid uname) from log group by ip;
3、select ip ,count(distince uid),count(distinct uname) from log group by ip;
1和2都可以运行,3会报错
2.2.join造成的倾斜
方案一:使用map join ,bucket map join ,SMB join
但是方案一条件太苛刻,有了方案二
方案二:将那些容易产生数据倾斜的key的值,剔除出去,单独找一个MR来运行。
处理方案一:知道数据倾斜的key值,在编译的时候处理
配置:
set hive.optimize.skewjoin.compiletime=true;
建表:
CREATE TABLE list_bucket_single (key STRING, value STRING)
-- 倾斜的字段和需要拆分的key值
SKEWED BY (key) ON (1,5,6)
-- 为倾斜值创建子目录单独存放
[STORED AS DIRECTORIES];处理方案二:不知道那些key值会出现数据倾斜问题,在运行时处理
运行期解决方案:
配置:
set hive.optimize.skewjoin=true; 是否开启运行期倾斜解决join
set hive.skewjoin.key=100000; 当key出现多少个的时候, 认为有倾斜说明:
在执行的过程中, hive会记录每一个key出现的次数, 当出现次数达到设置的阈值后, 认为这个key有倾斜的问题, 直接将这个key对应数据排除掉, 单独找一个MR来处理即可
建议:
如果提前知道表中有那些key有倾斜, 直接使用编译期即可
如果仅知道一部分, 对于其他key无法保证, 建议编译期和运行期同时开启