大数据之hive倾斜

1、数据倾斜原理

mapreduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长。
这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。

如何将数据均匀的分配到各个reduce中,就是解决数据倾斜的根本所在
1.1、如何找到大key及对应SQL执行代码

1)先找到对应job的url链接
在这里插入图片描述
2)打开链接,找到对应特别慢的task
在这里插入图片描述
在这里插入图片描述
3)打开url链接,查看日志logs
在这里插入图片描述
4)查看具体日志
在这里插入图片描述
在这里插入图片描述
5)通过时间判断是否数据倾斜
在这里插入图片描述
1、 查看日志中执行耗时很长的那个job,看到相关的url,点击到Hadoop的application页面。
2、通过各个task执行耗时情况判断是否数据倾斜

6)通过task的数据量判断数据倾斜
在这里插入图片描述
在这里插入图片描述

普通task counter的数据量
在这里插入图片描述

而task=000021的counter如下,是其他任务的几十倍
在这里插入图片描述
7)找到任务特别慢的那个task,打开对应日志
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
8)确定任务卡住的stage

① 通过jobname确定stage
在这里插入图片描述
9)查看hive的执行计划

explain select...

在这里插入图片描述
在这里插入图片描述
10)结论:连接条件少写了一个导致数据发散

2、group by 倾斜

2.1、数据倾斜原因
	group by 维度过小,某值的数量过多
2.2、解决方式
hive.map.aggr=true     #参数默认开启

3、join数据倾斜

3.1、空值产生的数据倾斜
日志表中的guid缺失

解决方式:
1)guid为空的不参与关联

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

2)赋予空值分新的key值

select
	*
from
	log a
left outer join users b
on
	case
		when a.user_id is null
		then concat(‘hive’, rand())
		else a.user_id
	end = b.user_id;
3.2、维表不小不大,怎么用 map join 解决倾斜问题
使用 map join 解决小表(记录数少)关联大表的数据倾斜问题,这个方法使用的频率非常高,
但如果小表很大,大到map join会出现bug或异常,这时就需要特别的处理。
***不用指定,默认开启
select
	/*+mapjoin(x)*/
	*
from
	log a
left outer join
	(
		select
			/*+mapjoin(c)*/
			d.*
		from
			(
				select distinct user_id from log
			)
			c
		join users d
		on
			c.user_id = d.user_id
	)
	x on a.user_id = b.user_id;
3.3、大表join大表
select id,
from tab1
left join tab2
on t1.id = t2.id
t1和t2进行做关联,以上两个表都是GB级别,左关联为1.6个小时
3.3.1、优化过程 - 类型优化
t1表的id为int类型,t2表的id为string类型,默认的hash操作会按bigint型的id进行分配,
这样会导致所有string类型的ext_field7集中到一个reduce里面。
select id,
from tab1
left join tab2
on t1.id = cast(t2.id as bigint)

优化结果:耗时为1.5小时。

3.3.2、优化过程 - 过滤空值
做进行左关联时空字段的关联操作实际上没有意义,可过滤为空的id
select id,
from tab1
left join tab2
on (t1.id
and t1.id is not null
and t1.id rlike '^[0-9]+$' 
and t1.id = cast(t2.id as bigint))

优化结果:耗时为50分钟

左表关联字段id为无效字段时(为空、字段长度为零、字段填充了非整数),不去关联右表,
由于空字段左关联以后取到的右表字段仍然为null,所以不会影响结果

在左关联中,虽然设置了左表关联字段为空不去关联右表,左表中未关联的记录(id为空)
将会全部聚集在一个reduce中进行处理,体现为reduce进度长时间处在99%。
3.3.3、优化过程 - 随机数补空
select id,
from tab1
left join tab2
on(
    case when (a.idis not null 
        and length(a.id) > 0 
        and a.idrlike '^[0-9]+$') 
    then 
        cast(a.id as bigint) 
    else 
        cast(ceiling(rand() * -65535) as bigint) 
    end = b.id
) 
即使左表的未关联记录,它的key也分布得十分均匀

优化结果:耗时10分钟

3.4、大key导致倾斜
  1. 可以将大key和其他key分开处理,用where条件过滤该key,再union all其他的key,这样效率会更高一些。

  2. 调整reduce的内存大小:

    set mapreduce.reduce.memory.mb=4000;
    set mapreduce.reduce.java.opts=-Xmx4000m;

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随缘清风殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值