首页 > 其他分享 >hive数据倾斜优化

hive数据倾斜优化

时间:2023-02-20 05:22:05浏览次数:41  
标签:join 数据 hive +----------+------------+ key 倾斜 优化 id

1、什么是数据倾斜?

由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点

2、主要表现:任务进度长时间维持在 99%或者 100%的附近,查看任务监控页面,发现只有少量 reduce子任务未完成,因为其处理的数据量和其他的 reduce 差异过大。单一 reduce 处理的记录数和平均记录数相差太大,通常达到好几倍之多,最长时间远大于平均时长。

3、容易数据倾斜情况

 

 4、产生数据倾斜的原因:

  • key 分布不均匀
  • 业务数据本身的特性
  • 建表考虑不周全
  • 某些 HQL 语句本身就存在数据倾斜

<1>针对 group by出现数据倾斜

案例场景:某一特殊key值大量出现,语句中仅出现group by,没有相应的聚合函数一起(聚合函数可以在map阶段提前进行聚合,可以降低数据倾斜风险),会造成对应key的reduce出现数据倾斜

解决策略是对key值进行加盐处理:

核心实现思路就是进行两阶段聚合。第一次是局部聚合,先给每个key都打上一个随机数,比如10以内的随机数,此时原先一样的key就变成不一样的了,比如(hello, 1) (hello, 1) (hello, 1) (hello, 1),就会变成(1_hello, 1) (1_hello, 1) (2_hello, 1) (2_hello, 1)。接着对打上随机数后的数据,执行sum,count等聚合操作,进行局部聚合,那么局部聚合结果,就会变成了(1_hello, 2) (2_hello, 2)。然后将各个key的前缀给去掉,就会变成(hello,2)(hello,2),再次进行全局聚合操作,就可以得到最终结果了,比如(hello, 4)。

方案优点:对于聚合类的shuffle操作导致的数据倾斜,效果是非常不错的。通常都可以解决掉数据倾斜,或者至少是大幅度缓解数据倾斜

方案缺点:仅仅适用于聚合类的shuffle操作,适用范围相对较窄。如果是join类的shuffle操作,还得用其他的解决方案。

 

 <2>针对join出现的数据倾斜

方案一:抽样求出引起数据倾斜的key值,进行过滤处理

情景:某张表中数据分布不均,个别key值出现次数占比很大,引起join数据倾斜,例如数据空值或者爬虫IP

处理思路:首先对数据进行抽样,选出key占比较大列表,采取过滤处理,去掉无效值或者加盐等处理,然后先进行局部处理,在整体处理

优点:可以快速解决数据倾斜问题

缺点:应用场景受限,适用于几个key值偏多的情况

方案二:优先使用mapjoin

由于map阶段不会发生数据倾斜,使用mapjoin可以防止数据倾斜,join操作中的表的数据量比较小(比如几百M或者一两G),比较适用此方案。

在 hive 中,直接提供了能够在 HQL 语句指定该次查询使用 map join,map join 的用法是在查询/子查询的SELECT关键字后面添加/*+ MAPJOIN(tablelist) */提示优化器转化为mapjoin(早期的 Hive 版本的优化器是不能自动优化 map join 的)。其中 tablelist 可以是一个表,或以逗号连接的表的列表。tablelist 中的表将会读入内存,通常应该是将小表写在这里。

MapJoin 具体用法:

select /* +mapjoin(a) */ a.id aid, name, age from a join b on a.id = b.id;select /* +mapjoin(movies) */ a.title, b.rating from movies a join ratings b on a.movieid =b.movieid;
n.net/jin6872115/article/details/79878391

在 hive0.11 版本以后会自动开启 map join 优化,

由两个参数控制:set hive.auto.convert.join=true;//设置 MapJoin 优化自动开启

set hive.mapjoin.smalltable.filesize=25000000//设置小表不超过多大时开启 mapjoin 优化

方案优点:对join操作导致的数据倾斜,效果非常好,因为根本就不会发生shuffle,也就根本不会发生数据倾斜。

方案缺点:适用场景较少,因为这个方案只适用于一个大表和一个小表的情况。毕竟我们需要将小表进行内存加载,此时会比较消耗内存资源,每个节点驻留一份小表的全量数据。如果小表数据比较大,比如10G以上,那么就可能发生内存溢出了。因此并不适合两个都是大表的情况。

方案三:处理大表文件,使其变为可加载到内存的小表

场景:

select * from log a left outer join users b on a.user_id = b.user_id;

users 表有 600w+的记录,把 users 分发到所有的 map 上也是个不小的开销,而且 map join不支持这么大的小表。如果用普通的 join,又会碰到数据倾斜的问题。

解决思路:

select /*+mapjoin(x)*/* from log aleft 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 = x.user_id;

优点:可以有效解决大表join大表的数据倾斜

缺点:应用受限,log 里 user_id 有上百万个,这就又回到原来 map join 问题。所幸,每日的会员 uv不会太多,有交易的会员不会太多,有点击的会员不会太多,有佣金的会员不会太多等等。所以这个方法能解决很多场景下的数据倾斜问题

方案四:采样倾斜key并分拆join操作

方案适用场景:两个Hive表进行join的时候,如果数据量都比较大,那么此时可以看一下两个Hive表中的key分布情况。如果出现数据倾斜,是因为其中某一个Hive表中的少数几个key的数据量过大,而另一个Hive表中的所有key都分布比较均匀,那么采用这个解决方案是比较合适的。

方案实现思路:

对包含少数几个数据量过大的key的那个表,通过sample算子采样出一份样本来,然后统计一下每个key的数量,计算出来数据量最大的是哪几个key。
然后将这几个key对应的数据从原来的表中拆分出来,形成一个单独的表,并给每个key都打上n以内的随机数作为前缀,而不会导致倾斜的大部分key形成另外一个表
接着将需要join的另一个表,也过滤出来那几个倾斜key对应的数据并形成一个单独的表,将每条数据膨胀成n条数据,这n条数据都按顺序附加一个0~n的前缀,不会导致倾斜的大部分key也形成另外一个表。
再将附加了随机前缀的独立表与另一个膨胀n倍的独立表进行join,此时就可以将原先相同的key打散成n份,分散到多个task中去进行join了。
而另外两个普通的表就照常join即可。
最后将两次join的结果使用union算子合并起来即可,就是最终的join结果。
方案优点:对于join导致的数据倾斜,如果只是某几个key导致了倾斜,采用该方式可以用最有效的方式打散key进行join。而且只需要针对少数倾斜key对应的数据进行扩容n倍,不需要对全量数据进行扩容。避免了占用过多内存。

方案缺点:如果导致倾斜的key特别多的话,比如成千上万个key都导致数据倾斜,那么这种方式也不适合。

解决方案五:使用随机前缀和扩容RDD进行join
方案适用场景:如果在进行join操作时,表中有大量的key导致数据倾斜,那么进行分拆key也没什么意义,此时就只能使用最后一种方案来解决问题了。

方案实现思路:

该方案的实现思路基本和“解决方案四”类似,首先查看Hive表中的数据分布情况,找到那个造成数据倾斜的Hive表,比如有多个key都对应了超过1万条数据。
然后将该表的每条数据都打上一个n以内的随机前缀。
同时对另外一个正常的表进行扩容,将每条数据都扩容成n条数据,扩容出来的每条数据都依次打上一个0~n的前缀。
最后将两个处理后的表进行join即可。
方案优点:对join类型的数据倾斜基本都可以处理,而且效果也相对比较显著,性能提升效果非常不错。

方案缺点:该方案更多的是缓解数据倾斜,而不是彻底避免数据倾斜。而且需要对整个表进行扩容,对内存资源要求很高。

方案六:增加并行度

场景:两个大表,数据分布均匀,为了提高效率,使用mapjoin,采用切分大表的方法

采用将大表切分为小表,然后进行连接

原始测试表

+----------+------------+
| test.id | test.name |
+----------+------------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
+----------+------------+

将其切分为两个:

select * from test tablesample(bucket 1 out of 2 on id);

+----------+------------+
| test.id | test.name |
+----------+------------+
| 2 | bb |
| 4 | dd |
+----------+------------+
select * from test tablesample(bucket 2 out of 2 on id);

+----------+------------+
| test.id | test.name |
+----------+------------+
| 1 | aa |
| 3 | cc |
+----------+------------+
切分为四个:
jdbc:hive2://hadoop02:10000> select * from test tablesample(bucket 1 out of 4 on id);

+----------+------------+
| test.id | test.name |
+----------+------------+
| 4 | dd |
+----------+------------+
jdbc:hive2://hadoop02:10000> select * from test tablesample(bucket 2 out of 4 on id);
+----------+------------+
| test.id | test.name |
+----------+------------+
| 1 | aa |
+----------+------------+
jdbc:hive2://hadoop02:10000> select * from test tablesample(bucket 3 out of 4 on id);

+----------+------------+
| test.id | test.name |
+----------+------------+
| 2 | bb |
+----------+------------+
jdbc:hive2://hadoop02:10000> select * from test tablesample(bucket 4 out of 4 on id);
+----------+------------+
| test.id | test.name |
+----------+------------+
| 3 | cc |
+----------+------------+

解释:tablesample(bucket 3 out of 4 on id),其中tablesample为关键字,bucket 关键字,3为要去的分表,4为拆分表的数目,id拆分依据;

标签:join,数据,hive,+----------+------------+,key,倾斜,优化,id
From: https://www.cnblogs.com/wdh01/p/17100061.html

相关文章

  • 15.Rac 性能的优化
    Rac设计优化思路如果可能,业务进行分割如果可能,限制并行在一个实例上运行Interconnect速度尽可能的快Sequence仅可能cache多一些表空间的Readonly对于小表,尽可能减......
  • spring,自定义注解,工厂模式,策略模式优化 if else,jdk1.7
    最近项目中使用mqtt监听消息,再根据消息做各种处理,使用大量的ifelse,代码异常难维护,参考的地址找不到了。。。 以下为实现:接收mqtt的接口类packagecom.mhm.mqttlistener;im......
  • JVM系统优化实践(1):JVM概览
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~这是多年之前做过的学习笔记,今天再翻出来,觉得仍然是记忆犹新。「独乐乐不如众乐乐」,就拿出来分享给「众乐乐」吧。目前大......
  • JVM系统优化实践(1):JVM概览
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~   这是多年之前做过的学习笔记,今天再翻出来,觉得仍然是记忆犹新。「独乐乐不如众乐乐」,就拿出来分享给「众乐乐」吧......
  • 如何系统地优化页面性能
    页面优化,其实就是要让页面更快地显示和响应。由于一个页面在它不同的阶段,所侧重的关注点是不一样的,所以如果要讨论页面优化,就要分析一个页面生存周期的不同阶段。通常一个页......
  • DX12 绘制几何体和优化渲染循环
    几何图形辅助结构体​ 随着项目越来越复杂,顶点和索引也会愈来愈多,因此我们可以选择创建一个结构体专门来管理所有的几何体几何图形辅助结构有何好处?管理几何体方便......
  • m基于GA遗传优化的多因素加权竞价博弈频谱分配算法matlab仿真
    1.算法描述假设有M个用户均为MIMOFullDuplex,N个频率,1<N<M,设计算法实现M个用户与N个频率的匹配。由于在一个MIMO系统中,用户数量M大于可用的频谱个数N,因此,必有一部分用......
  • m基于GA遗传优化的多因素加权竞价博弈频谱分配算法matlab仿真
    1.算法描述       假设有M个用户均为MIMOFullDuplex,N个频率,1<N<M,设计算法实现M个用户与N个频率的匹配。        由于在一个MIMO系统中,用户数量M大于可......
  • 【路径规划】基于遗传算法求解单向交通流分配优化问题附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 一步一步教你Nginx优化和防盗链
         Nginx优化和防盗链一、在Centos01上安装Nginx,设置根目录/www/使用域名www.stz.con访问1、在Centos01上安装Nginx依赖程序1)挂载系统光盘配置本地yum仓库[......