zoukankan      html  css  js  c++  java
  • hive案例

    数据倾斜:

    操作
    • Join on a.id=b.id
    • Group by
    • Count Distinct count(groupby)
    • 原因
    • key分布不均导致的
    • 人为的建表疏忽
    • 业务数据特点
    • 症状
    • 任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。
    • 查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。
    • 倾斜度
    • 平均记录数超过50w且最大记录数是超过平均记录数的4倍。Null 50w 10w
    • 最长时长比平均时长超过4分钟,且最大时长超过平均时长的2倍。
    • 万能方法
    • hive.groupby.skewindata=true

      原因
    • Hive在进行join时,按照join的key进行分发,而在join左边的表的数据会首先读入内存,如果左边表的key相对分
    散,读入内存的数据会比较小,join任务执行会比较快;而如果左边的表key比较集中,而这张表的数据量很大,
    那么数据倾斜就会比较严重,而如果这张表是小表,则还是应该把这张表放在join左边。
    • 思路
    • 将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率
    • 使用map join让小的维度表先进内存。
    • 方法
    • Small_table join big_table

     原因
    • 日志中有一部分的userid是空或者是0的情况,导致在用user_id进行hash分桶的时候,会将日志中userid为0或者
    空的数据分到一起,导致了过大的斜率。
    • 思路
    • 把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不
    影响最终结果。

    • 方法 -0 2 -1 2 -2 3 -0 -1 -2 -
    • on case when (x.uid = '-' or x.uid = '0‘ or x.uid is null) then concat(‘-',rand()) else x.uid end =f.user_id;

    案例
    • Select * from dw_log t join dw_user t1 on t.user_id=t1.user_id
    • 现象:两个表都上千万,跑起来很悬 1,2,3,4,5,2,3,4 2,3,4
    • 思路
    • 当天登陆的用户其实很少
    • 方法
    • Select/*+MAPJOIN(t12)*/ *
    • from dw_log t11
    • join (
    • select/*+MAPJOIN(t)*/ t1.*
    • from (
    • select distinct user_id from dw_log --group by user_id
    • ) t
    • join dw_user t1
    • on t.user_id=t1.user_id
    • ) t12
    • on t11.user_id=t12.user_id

    原因
    • 做count distinct时,该字段存在大量值为NULL或空的记录。
    • 思路
    • 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 <> ''

    案例
    • Select day,count(distinct session_id),count(distinct user_id) from log a group by day
    • 问题
    • 同一个reduce上进行distinct操作时压力很大
    • 方法
    select day,
    count(case when type='session' then 1 else null end) as session_cnt,
    count(case when type='user' then 1 else null end) as user_cnt
    from (
    select day,session_id,type
    from (
    select day,session_id,'session' as type
    from log
    union all
    elect day user_id,'user' as type
    from log
    ) group by day,session_id,type
    ) t1 group by day;

  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    ThinkCMF X1.6.0-X2.2.3框架任意内容包含漏洞分析复现
    Apache Solr Velocity模板注入RCE漏洞复现
    WebShell代码分析溯源(十一)
  • 原文地址:https://www.cnblogs.com/taozizainali/p/9010629.html
Copyright © 2011-2022 走看看