Hive5:Hive优化

作者: 勇于自信 | 来源:发表于2020-04-29 11:45 被阅读0次

    Map优化

    1. 通过调整脚本的参数来设置map的个数,和设置block大小,block是影响map个数的关键因素

    直接设置map个数:set mapred.map.tasks=10

     2.为了任务加快,有一些任务可以考虑开启compiners:
    
      Hive.map.aggr=true
    

    Reduce优化:

    1.提交sql,设置的参数

    原因:有一个reduce个数的计算公式,这个公式依赖于这个参数

    Reduce个数=InputFileSize(整个文件数据的大小)/bytes per reducer(每一个reduce处理的大小)

    这个参数就是设置分母

    2.直接设置reduce的个数:

    In order to change the average load for a reducer (in bytes):
    set hive.exec.reducers.bytes.per.reducer=<number>
    如果大于<number>,就会多生成一个reduce
    <number> =1024 <1k 一个reduce
    1m 10个reduce

    set hive.exec.reducers.bytes.per.reducer=20000;
    select user_id,count(1) as order_cnt
    from orders group by user_id limit 10;
    --结果number of mappers: 1; number of reducers: 1009

    In order to limit the maximum number of reducers:
    set hive.exec.reducers.max=<number>
    set hive.exec.reducers.max=10;
    -- number of mappers: 1; number of reducers: 10

    In order to set a constant number of reducers:
    set mapreduce.job.reduces=<number>
    set mapreduce.job.reduces=5;
    --number of mappers: 1; number of reducers: 5
    set mapreduce.job.reduces=15;
    --number of mappers: 1; number of reducers: 15
    对你当前窗口,或者执行任务(脚本)过程中生效

    3.对于没有group by,又做了count这样聚合的函数的时候它最后跑出来的reduce个数就是一个

    4.分区优化:

    ​减少不必要的数据过滤。

    5.笛卡尔积优化:

    用where取代on

    6.map join优化:

    Map join:类似一种检索配置文件的形式

    例如:A是一个文件,B是一个文件,A.join B

    如果A是小表,考虑是否可以将A放入内存,只遍历大表B,大表可以帮忙做一个性能的提升。

    如何知道哪个是小表和大表:

    MAPJOIN(tablelist)明确mapjoin里是小表

    /*+ STREAMTABLE(a) */ a是大表

    类似map join 放到select中的,区别:它是指定大表
    select /+STREAMTABLE(pr)/ ord.order_id,pr.product_id,pro.aisle_id
    from orders ord
    join priors pr on ord.order_id=pr.order_id
    join products pro on pr.product_id=pro.product_id
    limit 10;

    7.union/union all优化:

    union all / distinct == union
    --运行时间:74.712 seconds 2job
    select count(distinct *)
    from (
    select order_id,user_id,order_dow from orders where order_dow='0' union all
    select order_id,user_id,order_dow from orders where order_dow='0' union all
    select order_id,user_id,order_dow from orders where order_dow='1'
    )t;

    --运行时间122.996 seconds 3 job
    select count(*)
    from(
    select order_id,user_id,order_dow from orders where order_dow='0' union
    select order_id,user_id,order_dow from orders where order_dow='0' union
    select order_id,user_id,order_dow from orders where order_dow='1')t;

    8.两个不同任务来自一张表的优化:

    从公共表取数据写到另外一张表里,例如:

    9.执行hive任务的时候会产生一些临时中间文件,中间小的文件比较多,如何对多个小文件进行合并:

    配置参数:map阶段,reduce结果做合并,每个任务预期合并的size大小

    10.数据倾斜问题优化:

    假设数据源存在数据倾斜问题(有的key的记录多,有的key的记录少,记录多的跑到同一个

    Reduce里,会导致一个reduce特别慢,key的分布不均匀)

    优化方法:

    10.1.Mr:对key做改写来解决类似问题

    10.2.Hive:hive.groupby.skewindata这个参数会帮你完成一定的负载均衡

    如果在不导致reduce一直失败起不来的时候,就不用这个变量
    如果确实出现了其中一个reduce的处理数据量太多,导致任务一直出问题,运行时间长。这种情况需要设置这个变量。

    10.3 '-' ,where age<>'-' 直接丢掉这个数据
    select age,count(1) group by age where age<>'-'

    怎么定位具体哪几个key发生倾斜?
    sample(简单采样)

    10.4 空间换时间

    案例: 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
    select day user_id,'user' as type
    from log
    ) • group by day,session_id,type
    ) t1
    group by day

    11.sql语句优化

    例如如下两个sql语句:

    第一条sql语句在join后再进行过滤,相当于做了两步。

    第二条sql语句在join过程中就对条件进行了预先过滤。

    12.并行执行MapReduce优化,如下图:

    例如每个圆形就是一个MapReduce,橙色部分需要依赖别人,蓝色部分没有相互依赖关系的节点就可以尽可能地单独执行。

    那么蓝色的MapReduce就可以同时执行,就是并行。设置并行执行的方法:

    开启并行的方法:Set hive.exec.parallel设置为true

    同步执行hive的多个阶段,hive在执行过程,将一个查询转化成一个或者多个阶段。某个特
    定的job可能包含众多的阶段,而这些阶段可能并非完全相互依赖的,也就是说可以并行执行
    的,这样可能使得整个job的执行时间缩短。
    hive执行开启:
    set hive.exec.parallel=true

    13.大小表关联的优化:
    原理:
    Hive在进行join时,按照join的key进行分发,而在join左边的表的数据会首先读入内存,如果左边表的key相对
    分散,读入内存的数据会比较小,join任务执行会比较快;而如果左边的表key比较集中,而这张表的数据量很大,那么数据倾斜就会比较严重,而如果这张表是小表,则还是应该把这张表放在join左边。

    优化思路:
    将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率
    使用map join让小的维度表先进内存。
    方法:
    Small_table join big_table

    14.分组的特殊值处理优化:
    原理:例如日志中有一部分的userid是空或者是0的情况,导致在用user_id进行hash分桶的时候,会将日志中userid为0或者空的数据分到一起,导致了过大的斜率。
    优化思路:
    把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
    方法:
    on case when (x.uid = '-' or x.uid = '0‘ or x.uid is null) then concat('dp_hive_search',rand()) else x.uid
    end = f.user_id;

    1. 大大表关联的优化:
      案例:Select * from dw_log t join dw_user t1 on t.user_id=t1.user_id
      现象:两个表都上千万,跑起来很悬

    思路:
    当天登陆的用户其实很少,将绝大部分没用的用户的基础信息过滤掉,结合业务的特点,将大表变成小表
    方法:
    Select/+MAPJOIN(t12)/ *
    from dw_log t11
    join (
    select/+MAPJOIN(t)/ t1.*
    from (
    select 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

    1. 聚合时存在大量特殊值的优化
      原因:
      做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 <> ''

    相关文章

      网友评论

        本文标题:Hive5:Hive优化

        本文链接:https://www.haomeiwen.com/subject/tqjgwhtx.html