精华内容
下载资源
问答
  • HIVE数据倾斜

    2021-02-26 15:52:05
    数据倾斜后续详细写 HIVE数据倾斜这篇文章写的不错,转存
    展开全文
  • Hive数据倾斜

    2020-11-20 17:54:39
    Hive数据倾斜 数据倾斜原因 由于数据分布不均匀,造成数据大量的集中到一点,使某个reduce的数据输入量远远大于其他reduce数据的输入量 数据倾斜表现 任务进度长时间维持在99%(或100%),查看任务监控页面,发现...

    Hive数据倾斜

    数据倾斜原因

    由于数据分布不均匀,造成数据大量的集中到一点,使某个reduce的数据输入量远远大于其他reduce数据的输入量

    数据倾斜表现

    任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。

    为什么会产生数据倾斜问题

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

    数据倾斜解决办法

    1、参数调节

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

    有数据倾斜的时候进行负载均衡,当选项设定位true,生成的查询计划会有两个MR Job。
    第一个MR Job中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;
    第二个MR Job再根据预处理的数据结果按照Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个Reduce中),最后完成最终的聚合操作。

    2、SQL语句调节

    场景一、两表join时关联字段为null

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

    解决方法1: 过滤掉值为null的key,不参与关联

    Select * From log a 
    Join hy_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 :加盐,给值为null的key赋新值

    Select *  
    from log a 
    left outer join hy_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);
    
    场景三、join时产生数据倾斜

    1、小表 join 大表
    小表join大表时使用MapJoin,顾名思义,就是在Map阶段进行表之间的连接 MapJoin通常用于一个很小的表和一个大表进行join的场景。而不需要进入到Reduce阶段才进行连接。这样就节省了在Shuffle阶段时要进行的大量数据传输。从而起到了优化作业的作用。
    在这里插入图片描述MapJoin简单说就是在Map阶段将小表读入内存,顺序扫描大表完成Join。
    上图是Hive MapJoin的原理图(引用Facebook工程师Liyin Tang的一篇介绍Join优化的slice)从图中可以看出MapJoin分为两个阶段:
    1.通过MapReduce Local Task,将小表读入内存,生成HashTableFiles上传至Distributed Cache中,这里会对HashTableFiles进行压缩
    2.MapReduce Job在Map阶段,每个Mapper从Distributed Cache读取HashTableFiles到内存中,顺序扫描大表,在Map阶段直接进行Join,将数据传递给下一个MapReduce任务。

    2、大表 join 大表

    把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null 值关联不上,处理后并不影响最终结果。

    3、count distinct大量相同特殊值:

    count distinct 时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

    select cast(count(distinct user_id)+1 as bigint) as user_cnt
    
    from tab_a
    
    where user_id is not null and user_id <> ''
    
    展开全文
  • hive数据倾斜

    千次阅读 2020-12-15 12:26:50
    hive数据倾斜 1. join时产生数据倾斜 1.1 小表join大表 使用mapjoin 1.2 大表join大表 1.2.1 key为空值造成的影响 空值太多join时,会把所有key为空值的数据发送到同一个reduce中,发生数据倾斜 解决方法: 空值不重要...

    hive数据倾斜

    1. join时产生数据倾斜

    1.1 小表join大表

    使用mapjoin,左边小表,右边大表,在map端进行join,把小表放到了内存,然后扫描大表进行join.没有shuffle,不走reduce.
    开启参数:

    set hive.auto.convert.join = true0.11版本后默认是true)
    set hive.mapjoin.smalltable.filesize=25000000(设置小表的大小,默认就是25M)
    

    1.2 大表join大表

    1.2.1 key为空值造成的影响

    空值太多join时,会把所有key为空值的数据发送到同一个reduce中,发生数据倾斜

    解决方法:

    • 空值不重要的情况,先把空值过滤掉,在进行join
    select * from logs
    join user 
    on logs.uid is not null and logs.uid=user.uid;
    
    • 空值不能过滤,使用case when 对空值附上随机值,然后进行join,这样会把所有key为空值的数据发送到不同的reduce中去处理.
    select
    *
    from logs
    left join user
    on case when logs.uid is null then concat('',round(rand()*1000)) else logs.uid=user.uid;
    

    1.2.2 热点key

    可以将热点数据和非热点数据分别进行处理,最后再合并到一起.

    1.3 不同数据类型join

    比如log表中的uid类型为int,也有string类型.user表中的uid类型为string.

    <1>解决

    将log表中uid为int类型的数据转换成string,然后进行join

    select
    *
    from log
    join user
    on cast(log.uid as string)=user.uid;
    

    2. group by 产生数据倾斜

    2.1 开启数据倾斜的负载均衡

    默认为false,改为true

    set hive.groupby.skewindata=true;
    

    任务执行的时候会有两个mr,

    第一个mr任务会把map输出的结果集合随机分配到所有reduce中,做部分聚合;

    第二个mr任务会根据预处理的结果按照 group by key 分布到reduce中,完成最终的聚合操作.

    2.2 两阶段聚合(给分组key拼接随机数聚合一次,去除随机数再聚合一次)

    产生的原因:
    key.hashcode()%numReduce 值相同的就分到了同一个reduce中

    当某个分组key数据特别大的时候 group by 阶段就会发生数据倾斜.

    原始Hql:

    select
    works,
    count(1) as user_cts
    from other
    group by works;
    

    <1>解决

    给原分组key添加随机数聚合一次,然后再去掉随机数再聚合一次

    通过控制给key拼接上的随机数的大小范围来控制热点key分发到不同reduce的范围

    SELECT
    split(t.total)[0] as works,
    sum(t.cts) as user_cts
    FROM
    (
       SELECT
       CONCAT(works,'_',ROUND(RAND()*1000)) as total,
       count(1) as cts
       from other group by CONCAT(works,'_',ROUND(RAND()*1000))
    ) t
    group by split(total,'_')[0];
    
    展开全文
  • HIVE 数据倾斜

    2018-10-09 14:52:05
    HIVE 数据倾斜 1. 什么是数据倾斜 由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点 2. 产生数据倾斜的原因 A:key 分布不均匀 一个表很小,但是key集中;分发到某一个或者几个Reduce上的数据远高于平均...

    HIVE 数据倾斜

    1. 什么是数据倾斜

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

    2. 产生数据倾斜的原因

    A:key 分布不均匀
    一个表很小,但是key集中;分发到某一个或者几个Reduce上的数据远高于平均值。

    B:业务数据本身的特性

    C:建表考虑不周全

    D:某些 HQL 语句本身就存在数据倾斜

    group by
    数据维度非常的小,某值的数据非常多;处理某值的reduce非常耗时。

    count distinct
    某特殊值多,处理此特殊值的reduce非常的耗时

    3. 数据倾斜的解决方案

    1.参数调节

    Map端部分聚合,相当于Combiner
    hive.map.agge=true

    hive.groupby.skewindata=true
    有数据倾斜的时候进行负载均衡,当选项设定为true,生成的查询计划会有两个MR Job中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;

    第二个MR Job再根据预处理按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key 被分布到同一个Reduce中),最后完成最终的聚合操作。

    2.SQL语句调节如何Join:
    选择join key均匀的表作为驱动表,做好剪裁和filter操作,以致两表连接的时候数据量相对较小。

    大小表Join:使用map join 让小的维度表(1000条一下的记录)先进内存,在map端完成reduce,直接拿另一表中的数据与内存中的数据进行匹配。

    大表Join大表:把空值的key变成字符串加上随机数,把倾斜的数据分布到不同的reduce上去,由于null关联不上并不影响最终的输出结果。

    count distinct 大量相同的特殊值:将空值情况单独处理,如果是计算count distinct,
    直接过滤,最后的结果加上1;如果还有其它计算,需要group by,可以先将空值记录单独处理,然后再和其它的结果进行union。

    group by维度过小:采用count() group by方式来替换count(distinct)完成计算。

    4.典型的业务场景

    1.空值产生数据倾斜场景:日志中经常会有数据丢失,例如日志中的user_id,
    如果去其中的user_id和用户表中的user_id进行关联的话,就会产生数据倾斜的问题。
    解决方法1: user_id不参与关联
    select * from log a join 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 users b on case when a.user_id is null then concat(‘hive’,rand() )
    else a.user_id end = b.user_id;

    2.不同数据类型关联产生数据倾斜场景:
    用户表中user_id为int,log表中的user_id为int和string。当按照user_id进行两个表的join操作的时候,默认的hash操作会按照int类型的id进行分配,这样导致所有的string类型的数据都进入同一个reduce之中,
    解决的方法如下,把所有的数字类型转换为string的类型:
    select * from users a left outer join logs b on a.usr_id = cast(b.user_id as string)

    3.map join 解决大小表结合的问题场景:A表中有100行的数据,B表中30亿的数据解决方法:

    select /+ mapjoin(A)/ f.a,f.b from A t join B f on ( f.a=t.a and f.ftime=20110802)
    map join 中还可以进行不等值的链接操作,这样可以节省很多的时间,避免笛卡尔积。

    4.案例场景:某一特殊key值大量出现,语句中仅出现groupby,没有相应的聚合函数一起
    (聚合函数可以在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)。

    展开全文
  • hive 数据倾斜

    2019-10-17 16:56:05
    hive上执行脚本,数据一直跑不出,询问dba说可能是数据倾斜的问题,需要优化脚本(之前脚本可以正常执行),最后发现join表的重复数据过多造成的。网上看了下倾斜,简单总结下。 一、 概念 由于数据分布不均,造成...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,113
精华内容 845
关键字:

hive数据倾斜