大数据-数据倾斜那些事情

    在平时处理大数据量的过程中,会遇到很多数据倾斜的问题,在业务中很多坑也都踩过了,特此记录一下。

   首先,有很多的数据倾斜是是在业务场景中发生的。

   其次就是sql或者代码的问题了。

        以订单数据为例,在之前的例行任务中都是正常运行,但是在某一天搞了一个活动,导致某一个商品的订单数据增加了100倍,然后进行一些group等的操作,这种在处理数据的时候会产生数据倾斜,因为同一个key(商品id)都shuffle到同一个节点上进行运算,其他节点都运算完成,但是这个节点因为数据多的问题,一直在执行,所以会产生数据倾斜。

     解决方案:

      1、调研一下数据的情况,如果数据骤增特别大,导致reduce阶段一直卡在99%或者各种container报错OOM,任务跑不出来,那么这个需要在业务上特殊处理。(如果reduce阶段99%的情况持续时间能接受,其实就不需要特殊处理了,只不过产出时间比较晚而已,可以调整一些参数就行了)

      处理的方法也其实有很多的:

    (1)类似于count(distinct ***)的情况改一下写法,先group by ,再在外层来一次group by聚合。因为count(distinct ***)之后的数据reduce会卡住,同一个数据都在reduce处理,比较慢。两层group by 会有预聚合,数据量表少很多,处理起来更快。

    (2)真实数据就是倾斜很严重。这样的话可以单独先把倾斜的key单独拿出来计算,和其他key再聚合处理。

具体操作:

    订单表(abc.order_detail),要求单个商品的成交量、成交额

      先用sql过滤出来key倾斜的情况:(支付订单的数据表)

WITH big_tmp AS (

select
    item_id,
    count(1) as cnt
from
    abc.order_detail
where
    p_date = '2020-05-01'
group by
    item_id
HAVING
    cnt > 1
)

这个过滤出来的 big_tmp 数据集就是数据量比较大的集合。

   然后在关联的过程中吧 big_tmp 的数据单独计算。

WITH big_tmp AS (

select
    item_id,
    count(1) as cnt
from
    abc.order_detail
where
    p_date = '2020-05-01'
group by
    item_id
HAVING
    cnt > 1
) --所有的大数据量的数据 计算
SELECT
    item_id,
    count(1) AS cnt,
    sum(order_detail.spaend) AS total_spend
FROM
    abc.order_detail
    JOIN big_tmp ON order_detail.item_id = big_tmp.item_id
GROUP BY
    item_id
UNION ALL
    --其他数据量较小的数据 计算
SELECT
    count(1) AS cnt,
    sum(order_detail.spaend) AS total_spend
FROM
    (
        SELECT
            item_id,
            spaend
        FROM
            abc.order_detail
            LEFT JOIN big_tmp ON order_detail.item_id = big_tmp.item_id
        WHERE
            big_tmp.item_id IS NULL -- 过滤掉大数据量的 item_id
    ) small
GROUP BY
    item_id

   这样的话就可以把数据量比较大的 item_id 单独进行计算了。倾斜的情况就会显著缓解。

   如果还有问题,可以把item_id打散,进行hash,最后再把数据聚合起来,这样效率更高。(单独再出一份博客吧)

https://blog.csdn.net/iilegend/article/details/97682621

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值