• hive单节点数据倾斜解决方法


    一、现象

    map/reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完,此称之为数据倾斜。

    二、具体情况及解决

    1. join的key值发生倾斜

    1) key值包含很多空值或是异常值

    如果需要这些值,可以给这些值赋一些随机值:

    select userid ,name 
    from user_info a
    join (
         select  case  when userid  is  null  then  cast ( rand (47 )*100000  as i nt )
         else userid
         from user_read_log
    ) b  on a .userid  = b .userid

    如果不需要,则要提前过滤掉:

    select userid ,name 
    from user_info a
    join (
         select   userid
         from user_read_log
        where userid is not null
    ) b  on a .userid  = b .userid

    2) key值都是有效值

    设置每个节点的reducer,默认处理1G大小的数据:

    set hive.exec.reducers.bytes.per.reducer = 1000000000;

    如果你的join操作也产生了数据倾斜,那么你可以在hive中设定:

    set hive.optimize.skewjoin = true;  
    set hive.skewjoin.key = skew_key_threshold (default = 100000);

    hive 在运行的时候没有办法判断哪个key会产生多大的倾斜,所以使用这个参数控制倾斜的阈值,如果超过这个值,新的值会发送给那些还没有达到的reduce, 一般可以设置成(处理的总记录数/reduce个数)的2-4倍。

    如果你不知道设置多少,可以就按官方默认的1个reduce只处理1G的算法,那么  skew_key_threshold  = 1G/平均行长, 或者默认直接设成250000000 (差不多算平均行长4个字节)

    2. reduce数太少

    直接设置reduce任务个数:

    set mapred.reduce.tasks=800;

    默认是先设置hive.exec.reducers.bytes.per.reducer这个参数,设置了后hive会自动计算reduce的个数,因此两个参数一般不同时使用。

    3. 对于group by 产生倾斜的问题

    1) 开启map端combiner

    set hive.map.aggr=true;

    不过如果map各条数据基本上不一样,聚合没什么意义,这样,做combiner反而画蛇添足。

    还有另外两个相关参数:

    hive.groupby.mapaggr.checkinterval = 100000 (默认)
    hive.map.aggr.hash.min.reduction=0.5(默认)

    两个参数的意思是:预先取100000条数据聚合,如果聚合后的条数/100000>0.5,则不再聚合。

    2) 开启group by查询数据倾斜优化

    set hive.groupby.skewindata=true;

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

    4. 小表与大表关联

    可以通过mapjoin来优化,将小表刷入内存中:

    set hive.auto.convert.join = true;

    设置刷入内存表的大小(字节):

    set hive.mapjoin.smalltable.filesize = 2500000;

    三、参考

    1. hive-数据倾斜解决详解

    2. Configuration Properties

    3. Hive数据倾斜

    (完)

  • 相关阅读:
    Linux调整时区和同步时间
    wget命令
    apt-get损坏修复
    apt-get卸载命令
    apt-get命令
    ps命令
    卸载Ambari
    YARN Registry DNS启动提示“53端口被占用”错误的解决方法
    反转链表,时间复杂度O(n),空间复杂度O(1)
    简易版之最短距离
  • 原文地址:https://www.cnblogs.com/harrymore/p/9092976.html
Copyright © 2020-2023  润新知