文档章节

hive join 数据倾斜 真实案例

aibati2008
 aibati2008
发布于 2017/03/21 10:13
字数 1004
阅读 31
收藏 1

Hive或者MR处理数据,不怕数据量大,就怕倾斜。Hive里大表join的时候,数据倾斜就是个很头疼的问题。本博主就遇到了一个真实案例,特意记录下来,有需要的同学可以参考

1.查了5个小时还没结束的sql语句

set mapred.reduce.tasks = 30;
insert overwrite directory 'xxx'
select
cus.idA,cus.name,addr.bb from tableA as cus
join tableB as addr
on cus.idA = addr.idB
  •  

很简单的一个hql语句,优化的空间也不是很大(例子中的addr数据量比cus小,应该讲addr放在前面驱动join)。tableA的量级为亿级,tableB的量级为几百万级别。就这么一个简单的sql,尼玛从上午十点半开始跑,跑到下午三点半还没有跑完。实在受不了了,kill掉了。

2.初步分析

首先上个查询过程中的图 
这里写图片描述

看到这种情况,稍微有点经验的同学第一反应肯定就是:卧槽,这尼玛肯定是数据倾斜了。没错,map早就完工了,reduce阶段一直卡在99%,而且cumulative cpu的时间还一直在增长,说明整个job还在后台跑着。这种情况下,99%的可能性就是数据发生了倾斜,整个查询任务都在等某个节点完成。。。

3.分析那部分数据产生了倾斜

问题既然已经定位了,那接下来就是需要解决问题了。正好不巧的是,集群这几天还出了一些状况。so,首先为了确认到底是集群本身的问题,还是代码的问题,先找了另外两个表,都是亿级数据。这两个表不存在数据倾斜的情况,join一把试了试,两分钟之内结果就出来了。万幸,说明这会集群已经没有问题了,还是查查数据跟代码吧。

代码本身很简单,那就沿着数据倾斜的方向查查吧。因为上面的两个表是根据id关联的,那如果倾斜的话,肯定就是id倾斜了哇。

set mapred.reduce.tasks = 5;
select idA,count(*) as num
from tableA
group by idA
distribute by idA
sort by num desc limit 10
  •  

结果为:

192928  5828529
2000000000496592833 2406289
18000   1706031
4000288 1386324
2000000003624295444 1201178
2000000001720892923 1029475
2000000002292880478 991299
2000000000736661289 881954
2000000000740899183 873487
2000000000575115116 803250
  •  

对于有上亿数据的一个表来说,这数据也算不上倾斜多厉害嘛。最多的一个key也就五百多万不到六百万。好吧,先不管了,再查一把另外一个表

set mapred.reduce.tasks = 5;
select idB,count(*) as num
from tableB
group by idB
distribute by idB
sort by num desc limit 10
  •  

结果也很快出来

192928  383412
18000   60318
617279581   23028
51010262    4643
4000286 3528
2000000000575115116 3218
1366173280  3012
4212339 2972
2000000002025620390 2704
2000000001312577574 2622
  •  

这数据倾斜,也不是特别严重嘛。

不过再把这两个结果一对比,尼玛恍然大悟。两个表里最多的一个key都是192928,一个出现了将近600万次,一个出现了将近40万次。这两个表再一join,尼玛这一个key就是600万*40万的计算量。最要命的是,这计算量都分配给了一个节点。我数学不太好,600万*40万是多少,跪求数学好的同学帮忙计算一下。不过根据经验来看的话,别说5个小时,再添个0也未必能算得完。。。

4.如何解决

既然找到了数据倾斜的位置,那解决起来也就好办了。因为本博主的真正需求并不是真正要算两个表的笛卡尔积(估计实际中也极少有真正的需求算600万*40万数据的笛卡尔积。如果有,那画面太美我不敢看),所以最easy的解决方案,就是将这些key给过滤掉完事:

set mapred.reduce.tasks = 30;
insert overwrite directory 'xxx'
select
cus.idA,cus.name,addr.bb from tableA as cus
join tableB as addr
on cus.idA = addr.idB
where cus.idA not in (192928,2000000000496592833,18000,4000288,2000000003624295444,2000000001720892923,2000000002292880478,2000000000736661289,2000000000740899183,2000000000575115116,617279581,51010262,4000286,1366173280,2000000002025620390,2000000001312577574)
  •  

将此代码重新提交,5min时间,job跑完收工!

本文转载自:http://blog.csdn.NET/bitcarmanlee/article/details/51694101

共有 人打赏支持
aibati2008
粉丝 13
博文 86
码字总数 61386
作品 0
成都
技术主管
私信 提问
几种 hive join 类型简介

作为数据分析中经常进行的join 操作,传统DBMS 数据库已经将各种算法优化到了极致,而对于hadoop 使用的mapreduce 所进行的join 操作,去年开始也是有各种不同的算法论文出现,讨论各种算法的...

大数据之路
2012/10/11
0
0
Hadoop 中的数据倾斜

最近几次被问到关于数据倾斜的问题,这里找了些资料也结合一些自己的理解. 在并行计算中我们总希望分配的每一个task 都能以差不多的粒度来切分并且完成时间相差不大,但是集群中可能硬件不同...

HIVE
2016/07/02
38
0
006.hive语句优化

参考地址:http://www.cnblogs.com/end/archive/2013/01/15/2861448.html hive玩得好不好,在于你对mapreduce理解深不深叻;当然借鉴学习也很重要 倾斜分成group by造成的倾斜和join造成的倾...

片刻
2016/05/04
87
0
Hive 数据倾斜 和常用优化策略

Hive的数据倾斜 数据分布不均匀,造成数据热点,引起性能问题。Jobs 数比较多的作业运行效率相对比较低。主要表现为,任务进度长时间维持在 99%或者 100%的附近,查看任务监控页面,发现只有...

PeakFang-BOK
2018/11/26
0
0
浅析 Hadoop 中的数据倾斜

最近几次被问到关于数据倾斜的问题,这里找了些资料也结合一些自己的理解. 在并行计算中我们总希望分配的每一个task 都能以差不多的粒度来切分并且完成时间相差不大,但是集群中可能硬件不同...

大数据之路
2013/01/09
0
2

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周二乱弹 —— 我敢给你上菜,你敢吃么?

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :分享周深的单曲《缘起 (前世今生版)》人间多的是长了两只脚的恶人, 《缘起 (前世今生版)》- 周深 手机党少年们想听歌,请使劲儿...

小小编辑
48分钟前
57
7
万能的Python,还能用来制作高大上的进度条?

对于开发或者运维来说,使用Python去完成一些跑批任务,或者做一些监控事件是非常正常的情况。那么如何有效的监控任务的进度,除了在任务中加上log外,还能不能有另一种方式来了解任务进展到...

上海小胖
今天
8
0
如何嵌入 HTML 到 iPython notebook的输出

如何嵌入 HTML 到 iPython notebook的输出 iPython notebook中可以嵌入 HTML,也适用于JupyterHub和JupyterLab环境。不仅可以显示常用的HTML标签文本,甚至可以嵌入脚本交互操作和Frame分隔框...

openthings
今天
2
0
四、RabbitMQ3.7在CentOS7下的安装

安装依赖 sudo yum install -y gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf java-1.8.0-openjdk-devel git 创建yum源 vi /etc/yum.repos.d/rabbitmq-erlang.repo [......

XuePeng77
今天
2
0
android 延长Toast的时长

示例:myToast(5000,"hello"); public void myToast(int showTime, String msg) { Toast hello = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT); new CountDownTimer(......

雨焰
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部