Hive数据倾斜的刨析和解决
1.Hive Sql执行原理
首先我们执行的一个个Hive Sql,他是怎么执行的呢? (https://blog.****.net/Mirror_w/article/details/89461885这里有详细原理详解)
1.首先客户端Client,提交一个Sql查询任务
2.客户端通过Thrift Srever服务与Driver进行通信,将执行任务发送给Driver驱动
3.Driver驱动会将Sql同过解析器进行解析,解析成一个逻辑执行计划,然后与源数据库进行通信,比如提交一个(select * from student),会执行from后面的表明,拿着student去元数据库中找这个student是否存在,如果不存在直接抛异常信息。
如果存在返回表的元数据信息
4.Driver拿到student的元数据信息之后,进行查询优化,将数据返回(这是简单的select * from 表明这种任务,不会转成MR),
5.如果是复杂的查询,比如 select sum(1) from student1 left join score on a.id=b.id, 这样的任务会将Sql通过解析器解析成逻辑执行计划,然后由优化器解析成查询计划树,然后最终转成MR任务,去后台跑一个MR任务。
6.MR任务完成后会将结果发送给Driver,Driver将结果数据发送给Client。
2.优化MR
由Hive Sql执行原理可知,优化Hive Sql,归根结底还是优化MR。
1.业务逻辑的优化
在不影响业务逻辑的前提下,避免使用重复子查询,重复使用select查询,可以线将多次依赖的数据,储存成中间表。或者临时表。
2.数据优化
造成数据倾斜,大多数是key值分布不均匀或者小文件过多,首先在不影响业务逻辑的前提的下,过滤掉造成数据倾斜的key或者空值。对于小文件过多的原因,首先可以在落表的时候将小文件进行合并(当然原表是自己落地的话)。其次小文件过多可以提高并行度,当然可以在map端进行参数优化。
3.参数优化
1)合并小文件
set hive.merge.mapfiles=true //map端进行小文件合并
set hive.map.aggr=true //map端进行聚合
set hive.groupby.skewindata=true (默认关闭) //有数据倾斜时进行负载均衡机制
2)设置task个数
set hive.map.tasks //设置map端task的个数
set hive.mappred.reduce.tasks //设置reduce端task的个数
3)join优化
小表 join 大表 //将小表加载到内存去join大表
使用mapjoin将小表加载的内存