zoukankan      html  css  js  c++  java
  • HIVE- 数据倾斜

    数据倾斜就是由于数据分布不均匀,数据大量集中到一点上,造成数据热点。大多数情况下,分为一下三种情况:

    1.map端执行比较快,reduce执行很慢,因为partition造成的数据倾斜。

    2.某些reduce很快,某些reduce很慢,也是因为partition造成的数据倾斜。 

    3.某些map执行很快,某些map执行很慢,这是因为数据本身的分布的不合理性造成的。 

    造成上面reduce和map任务运行很缓慢本质上就两种情况:

    第一:reduce缓慢是因为partition造成滴; 
    第二:map端缓慢是因为数据本身的分布不合理性。

    下面介绍map缓慢和reduce缓慢

    Reduce端缓慢:两个table的join操作会造成数据倾斜,会造成reduce缓慢,这个相对比较好解决,我们不是有三种解决join性能的方案吗?mapjoin,common join,smbJoin可以解决数据倾斜。另外,有些情况下造成的reduce缓慢无法解决,因为数据本身也不是服从均匀分布。大多数还是高斯分布。 
    reduce性能本质上是由于groupby操作导致的,而count(distinct)内部本质也是有groupby实现

    map端缓慢:这种情况是由于每条数据的相对位置造成的。有两种方案:

    第一:设置在map端聚合,set hive.map.aggr=true 可以减小压力(默认开启) 
    第二:可以set hive.groupby.skewindata=true(默认关闭),此时hive的执行在MR后台会存在两个map一个reduce,第一个map本质上就是先对数据进行shuffle,第二个map就可以对shuffle之后的数据进行操作。

    join和Group的优化 
    2.1 对于普通的join操作,会在map端根据key的hash值,shuffle到某一个reduce上去,在reduce端做join连接操作,内存中缓存join左边的表,遍历右边的表,一次做join操作。所以在做join操作时候,将数据量多的表放在join的右边。 
    当数据量比较大,并且key分布不均匀,大量的key都shuffle到一个reduce上了,就出现了数据的倾斜。 

    在map端产生join

             mapJoin的主要意思就是,当链接的两个表是一个比较小的表和一个特别大的表的时候,我们把比较小的table直接放到内存中去,然后再对比较大的表格进行map操作。join就发生在map操作的时候,每当扫描一个大的table中的数据,就要去去查看小表的数据,哪条与之相符,继而进行连接。这里的join并不会涉及reduce操作。map端join的优势就是在于没有shuffle,


    2.2 对于Group操作,首先在map端聚合,最后在reduce端坐聚合,hive默认是这样的,以下是相关的参数 
    · hive.map.aggr = true是否在 Map 端进行聚合,默认为 True 
    · hive.groupby.mapaggr.checkinterval = 100000在 Map 端进行聚合操作的条目数目

    当然有的hive操作,不存在数据倾斜的问题,比如数据聚合类的操作,像sum、count,因为已经在map端做了聚合操作了,到reduce端的数据相对少一些,所以不存在这个问题。

    空值数据倾斜

    场景:如日志中,常会有信息丢失的问题,比如全网日志中的user_id,如果取其中的user_id和bmw_users关联,会碰到数据倾斜的问题。

    解决方法1 user_id为空的不参与关联

    Select * From log a
    
    Join bmw_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 bmw_users b 
    
    on case when a.user_id is null then concat(‘dp_hive’,rand() ) else a.user_id end = b.user_id; 

    结论:方法2比方法效率更好,不但io少了,而且作业数也少了。方法1 log读取两次,jobs是2。方法2 job数是1 。这个优化适合无效id(比如-99,’’,null等)产生的倾斜问题。把空值的key变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。附上hadoop通用关联的实现方法(关联通过二次排序实现的,关联的列为parition key,关联的列c1和表的tag组成排序的group key,根据parition key分配reduce。同一reduce内根据group key排序)

    不同数据类型关联产生数据倾斜

    场景:一张表s8的日志,每个商品一条记录,要和商品表关联。但关联却碰到倾斜的问题。s8的日志中有字符串商品id,也有数字的商品id,类型是string的,但商品中的数字id是bigint的。猜测问题的原因是把s8的商品id转成数字id做hash来分配reduce,所以字符串id的s8日志,都到一个reduce上了,解决的方法验证了这个猜测。

    解决方法:把数字类型转换成字符串类型

    Select * from s8_log a
    
    Left outer join r_auction_auctions b
    
    On a.auction_id = cast(b.auction_id as string);
  • 相关阅读:
    轨迹纠偏算法
    OpenStreetMap
    postgres create new super user
    postgis docker
    scala 命令台参数解析
    book
    Microsoft 365:OneDrive新特性,跨部门共享和协作
    2020年6月Microsoft 365 新功能速递
    Microsoft 365 解决方案:未经身份验证的用户上载文档小技巧 (2)
    Microsoft 365 解决方案:外部用户无法打开Microsoft Teams下录制的视频
  • 原文地址:https://www.cnblogs.com/RzCong/p/7775854.html
Copyright © 2011-2022 走看看