hive优化和数据倾斜解决方案

Hive优化

  • 一、常见的Hive的优化方式有哪些
  • 二、表的优化
  • 三、如何防止数据倾斜
    • 3.1、产生数据倾斜的原因
    • 3.2、数据倾斜通用的处理方法
    • 3.3、产生数据倾斜的场景和解决方案
      • 3.3.1 group by 产生数据倾斜
      • 3.3.2 select语句中包含 count(distinct)时
      • 3.3.3 大表+小表
      • 3.3.4 大表+大表
      • 3.3.5 空值产生数据倾斜
      • 3.3.6 不同数据类型关联产生数据倾斜
      • 3.3.7 开启负载均衡

一、常见的Hive的优化方式有哪些

  • 开启执行计划
    ➢explain select …
  • Fetch模式
    ➢默认是开启的,开启后在全局查找、字段查找、limit查找等都不走MapReduce
    set hive.fetch.task.conversion=more; 默认为more
  • 本地模式
    ➢数据量小的时候通过本地模式在单台机器上处理所有的任务
//开启本地mr
set hive.exec.mode.local.auto=true;
//设置 local mr 的最大输入数据量,当输入数据量小于这个值时采用 local mr 的方式
//默认为 134217728,即 128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
//设置 local mr 的最大输入文件个数,当输入文件个数小于这个值时采用 local mr 的方式,默认为4 
set hive.exec.mode.local.auto.input.files.max=8;
  • 并行执行
    ➢当某个job包含众多的阶段且这些阶段不是完全互相依赖的,就可以并行执行,以缩短整个job的执行时间
set hive.exec.parallel=true;//打开任务并行执行,默认为false关闭
set hive.exec.parallel.thread.number=16;//设置最大并行度,默认为8
  • 严格模式
    ➢默认是严格模式,是为了防止用户执行会产生意外影响的查询。严格模式可以限制以下几点
    • 不允许扫描所有分区,防止全表扫描消耗过大的资源
    • orderby必须使用limit语句,orderby会将数据分发到同一个Reducer里,强制使用limit可以防止Reducer额外执行很长一段时间
    • 限制笛卡尔积查询。因为Hive不会把where语句转化为on语句
  • JVM重用
    ➢默认配置是使用派生的JVM来执行任务,这种方式下JVM的启动过程会造成很大的开销,尤其是task很多的情况。JVM实例的使用次数可以在hadoop的mapred-site.xml文件中进行配置,通常在10-20之间。
    set mapred.job.reuse.jvm.num.tasks;默认为1
  • 推测执行
    ➢负载不均衡或资源分布不均等原因,任务之间的运行速度不一致。对于明显慢的task,采用推测执行(speculative Execution)机制,推测出拖后腿的任务并启动一个备份任务,和原始任务共同处理同一份数据,最终选用先成功运行完成的计算结果作为最终结果
  • 文件压缩
    ➢针对IO密集型的job,采取文件压缩的方式增加吞吐量和性能,减少载入内存的数据量;计算密集型的job不适合,因为压缩和解压会消耗CPU的使用
    ➢常见的文件存储格式有:TextFile、Sequence Files、RCFile、ORCFile、Parquet
    hive优化和数据倾斜解决方案_第1张图片
  • 合并小文件
    小文件的产生有三个地方,map输入,map输出,reduce输出,小文件过多也会影响hive的分析效率:

设置map输入的小文件合并

set mapred.max.split.size=256000000;  
//一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;
//一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)  
set mapred.min.split.size.per.rack=100000000;
//执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

设置map输出和reduce输出进行合并的相关参数:

//设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true
//设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true
//设置合并文件的大小
set hive.merge.size.per.task = 256*1000*1000
//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000
  • 表的优化

二、表的优化

数据倾斜在后面,此处不包含

  • 大表+大表
    ➢空key过滤或空key转换

  • Count(Distinct)去重统计
    ➢数据量大时,一个Count(Distinct)对应的ReduceTask需要处理的数据量太大,导致job很难完成。因此需要采用先Groupby再count的方式替代

  • 避免笛卡尔积
    ➢Hive只能使用1个Reducer完成笛卡尔积,会导致计算性能变低

  • 行列过滤
    ➢在select中只拿需要的列,尽量不用select *;先子查询,将查询后的表再关联主表,提高效率,如果直接join再用where子句过滤,则会先全表关联再过滤,效率较低

  • 动态分区调整
    ➢不同分区在不同文件夹内,在很多情况下可以避免全表扫描,提高查询效率

  • 谓语下推
    ➢像where等句,提前处理,减少下游语句的负载量

select *
from (
	select id,name
	from test 
	where dt>=20200201 and dt<20200301
)T
inner join test2 on T.id=test2.id;

hive优化和数据倾斜解决方案_第2张图片

三、如何防止数据倾斜

3.1、产生数据倾斜的原因

  • key 分布不均匀
  • 业务数据本身的特性
  • 建表时考虑不周
  • 某些 SQL 语句本身就有

3.2、数据倾斜通用的处理方法

  • 小文件进行合并,减少map数
  • 复杂文件增加map数
  • 设置适当的reduce个数

3.3、产生数据倾斜的场景和解决方案

3.3.1 group by 产生数据倾斜

➢根据业务合理调整分组维度
➢加盐
➢开启Map端聚合参数设置

  • group by时某一个key的数量过多导致对应的reducer负载过大时,采取map端部分聚合的策略。
  • 使用Map Combine进行map预聚合,可以减少磁盘IO传输
//是否在 Map 端进行聚合,默认为 
True set hive.map.aggr = true; 
//在 Map 端进行聚合操作的条目数目 
set hive.groupby.mapaggr.checkinterval = 100000; 
//有数据倾斜的时候进行负载均衡(默认是 false) 
set hive.groupby.skewindata = true;

3.3.2 select语句中包含 count(distinct)时

➢使用sum(1)… group by替代
➢把倾斜的数据单独拿出来处理,最后union回去

3.3.3 大表+小表

➢mapjoin
hive优化和数据倾斜解决方案_第3张图片

3.3.4 大表+大表

➢把左边的join字段拎出来,这样得到的新表就是左边大表的几分之一或者几十分之一,把提取后的小表传到各个节点内存里使用mapjoin。最后通过左边的表leftjoin右边mapjoin的结果就可以了
➢最后leftjoin 左右两个大表,右边大表在经过mapjoin后的join字段和左边的join字段顺序是一一对应的,因此不会发生shuffle也就是单纯的mapjoin了

3.3.5 空值产生数据倾斜

➢id为空的不参与关联

	select * from log a 
	join user b on a.user_id is not null and a.user_id = b.user_id
	union all
	select * from log c 
	where c.user_id is null;

➢给空值分配随机的key值,可以分配“平均值、中位数、随机数”,也可以concat其他列,hash值不一样了就

	select * 
	from log a
	join user b on case when a.user_id is null then concat('hive',rand()) else a.user_id=b.user_id;

3.3.6 不同数据类型关联产生数据倾斜

➢比如说有的表关联字段id是int而另一个是string,join时关联不上就会分到一个分区造成数据倾斜

3.3.7 开启负载均衡

set hive.groupby.skewindata=true;

开启内置分组聚合负载均衡的配置,默认为false;生成2个MR;但缺点是只能针对一列分组,多列分组会报错

你可能感兴趣的:(Hive,数据倾斜,hive)