暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

HIVE中数据倾斜原理及优化方案

数据森麟 2020-12-14
584

公众号后台回复“图书“,了解更多号主新书内容

 作者:顾先生

 来源:顾先生的数据挖掘


在开始前,我们先复习下HIVE的原理

HIVE原理

我把HIVE原理知识点做成了思维导图的形式,大家可以点击大图,也在公众号(顾先生的数据挖掘)后台回复“数据倾斜”获取高清原图。
                     
了解完HIVE的知识后,我们进入到数据倾斜部分,我们从数据倾斜的定义开始。

什么是数据倾斜?

在hive中的hive阶段跑完了,reduce阶段一直卡在99%,很大情况是发生了数据倾斜,整个任务在等待某个节点跑完。

一般来说,在分布式处理数据的时候,我们希望分配到每个节点的数据量能够大致相同,但实践过程中往往会出现大部分数据集中到某个节点的情况,导致所有节点都要等他处理完才能进行下一步行动。

数据倾斜分哪几类以及如何优化?

开发人员首先要确认几点:
  1. 需要计算的指标真的需要从数据仓库的公共明细层来自行汇总吗?数据团队开发的公共汇总层是否可以满足其要求了?

  2. 真的需要扫描这么多分区吗?能扫描一周的就不扫描一年的。

  3. 尽量不要使用select * from table这样的词语,能指定哪一列就用那一列,尽量添加过滤条件。

  4. 输入文件不要大量小文件,小文件可以先合并成大文件。


如果以上问题都排完雷了,数据倾斜问题依然存在,那我们继续往下看~

HIVE优化可以分成和join有关的优化场景无关的优化场景。
其中和join无关的优化场景包括group bycount distinct导致的倾斜优化和join有关的优化场景包括大表join小表的优化和大表join大表的优化。

我们一项一项来~

一:join无关的优化场景

1.group by引起的倾斜优化


这个很容易理解:
比如按照经销商的供应商来做group by,那么有些大经销商就有很多订单,而一些小经销商只有几个订单,那么分配给发大经销商的reduce task就有许多订单,所以造成数据倾斜。

应对措施也非常简单,设置一下参数就行:

set hive.map.aggr = true
set hive.groupby.skewindata = true

此时hive在数据倾斜的时候会进行负载均衡,生两个mapreduce,第一个相同的groupby key有可能会分配到不同的reduce中,达到均衡的目的。第二个根据预处理结果groupby key将结果分布到reduce中。

2.count distinct的优化


在开发过程中,要小心使用count distinct。举个栗子

select count(distinct user) from table

由于必须要去重了,所以hive会把所有的map阶段输出都放在一个reduce上,造成性能问题,所以通过group by再count进行优化。如下所示:
    select count(*)
    from
    (
    select user
    from table
    group by user
    ) tmp

    用group by去重,再用count计算行数目。


    二:和join有关的优化场景

    1.map join(大表join小表优化)的优化


    举个栗子:有两个表,一个是供应商,一个是订单,供应商的表不会很大,因为供应商就这么点儿人,而订单的表就很大了。两个表join一下,就是一个很经典的大表join小表问题。

    而且由于现实问题的二八定律,所以订单大多集中在少部分供应商上面(做生意嘛,旱的旱死涝的涝死),所以加剧了数据倾斜。

    这个问题可以通过添加mapjoin hint的方式来优化

    select *+mapjoin(b小表)*/

    这样将小表在map阶段直接复制到每个map的任务节点,然后每个map任务点执行lookup小表即可。

    2.map join(大表join大表优化)无法解决的优化


    这个也很好理解的,如有两个表,A表表示买家卖家的交易汇总表,B表表示卖家的段位评级。想要获得卖家在各个级别卖家的成交比例。

    如某个买家:金冠店:40%,皇冠店:30%,钻石店:20%,星级店:10%

    这两个表都会很大,超过mapjoin1G的限制,所以需要找其他方法解决。

    具体解决方案有四个,一个一个来:

    方案1:转化为mapjoin
    此思路有两种途径:限制行和列

    限制行的思路是比如不需要join b表全部,只需要join a表中存在的就行,比如过滤掉90天内没交易过的卖家

    限制列的思路是只取需要的字段

    方案2:join时候用case when语句
    解决场景是倾斜的值明确且数量很少,如用null引起的值。

    核心是将这些倾斜的值发放到随机的reduce,具体做法是在join时对这些特殊的值concat随机数,从而达到随即分发的目的。如:

    on (case when a.user_id is null then concat('hive',rand()) else a.user_id end) = b.user_id

    在hive中已经做了优化,如直接设置

    set hive.optimize.skewinfo=table_b:(seller_id)[('0')('1')]
    set hive.optimize.skewjoin=true

    方案3:倍数b表,在取模join
    通俗地说就是专用方案,比如大卖家肯定会倾斜,反正会倾斜,不如我直接先把它放大个1000倍,这样分发的数目就稀释了1000倍。

    专用方案:
    或者说上面我们把每条数据都放大了1000倍,其实这是不需要的,我们只需要找出大卖家并放大倍数即可。

    具体方法是建立一个临时表,存放每日最新大卖家,并预先膨胀好预定的倍数(如本例的1000倍)。在AB表之间建立一个join列,如果是大卖家,concat一个随机分配正整数,如果不是,保持不变。

    方案4:动态一分为二
    最彻底的方式就是动态一分为二,将倾斜和不倾斜的值分开处理,如果不倾斜的直接正常join,如果倾斜的找出来做mapjoin,最后结果union all即可

    我把HIVE中数据倾斜原理及优化方案的知识点做成了思维导图的形式,大家可以点击大图,也在公众号(顾先生的数据挖掘)后台回复“数据倾斜”获取高清原图。

                         
    本文主要介绍了 Hive SQL 优化的各种方法。首先概要介绍了数据倾斜的概念,然后对 Hive SQL 优化进行了概要性介绍,在此基础上分别介绍了 join 无关的优化场景:group by 的倾斜优化count distinct 优化,然后重点介绍了 mapjoin 的优化以及 mapjoin法解决的场景的优化mapjoin 无法解决的优化共有4种方案,实际项目中,大家可以根据情况选用适合自己的优化方案。


    ◆ ◆ ◆  ◆ 

    麟哥新书已经在京东上架了,我写了本书:《拿下Offer-数据分析师求职面试指南》,目前京东正在举行100-40活动,大家可以用相当于原价5折的预购价格购买,还是非常划算的:






    数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。


    管理员二维码:

    猜你喜欢

     !原来爬取B站弹幕这么简单

     厉害了!麟哥新书登顶京东销量排行榜!

     笑死人不偿命的知乎沙雕问题排行榜

     用Python扒出B站那些“惊为天人”的阿婆主!

     你相信逛B站也能学编程吗

    文章转载自数据森麟,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论