欢迎投稿

今日深度:

Hive 优化,

Hive 优化,


1)优化的宏观角度

        架构:这个是最重要的,是全局的

        1. 分区表:线上环境是普遍存在的,数据量大,不做好合适的分区会导致查询性能极致下降

        2. 合理利用中间结果集

            说明:假如sql1子查询包含:select a,b,c,z from xxx group ... 

                      假如sql2子查询包含:select a,b,c,d,e,f from xxx group ....

                      这时候可以梳理SQL之间的“血缘关系”

                      创建一张临时表 create table tmp_1 as select a,b,c,d,e,f,z from xxx group ....

                      这时候,sql1子查询可以:select a,b,c,z from tmp_1 group ...

                                   sql2子查询可以:select a,b,c,d,e,f from tmp_1 group ....

             优点:大大减少IO,充分利用好了中间结果集

             缺点:依赖性提高了,需要梳理一遍血缘关系    

             总结:虽然梳理血缘关系可能会耗费大量工作和时间,但是执行效果是显著提升的。(麻烦,但效果好)


        语法层面:SQL

 执行计划

        参数:

            set hive.auto.convert.join = true;    (0.13.0 默认true)

                -- common join 转 map join 

            set hive.mapred.reduce.tasks.speculative.execution = true;    (默认ture)

                -- 推测式执行: 同一时间多个相同的task(task是原子性),谁先跑完就采用谁的结果,即:长尾作业

                -- 要按实际考虑,假如集群负载已很高,这个参数建议关闭为好

            set mapred.job.reuse.jvm.num.tasks = 8;

                -- mapreduce中每个task都是进程,启动和销毁都需要大量时间

                -- 通过jvm复用后,进程跑完不销毁,第二个task接着用。能节省很多启动销毁时间

                -- 如果设置成-1,那么只要是同一个job的task,都可以按顺序在一个JVM上连续执行

            set mapred.reduce.tasks = 10

                -- reduce数过少,会导致作业执行慢;rudece数过多,会造成小文件多

                -- 默认值是-1,但不一定是最好效果

                -- 这个参数不是固定的,要根据文件生成情况调整,如果文件过大,就继续放大该配置

            set hive.exec.reducers.bytes.per.reducer = 256 000 000

                -- 该参数是:每一个reduce处理多少个字节数

                -- 0.14.0版本之前大概是1G,0.14.0版本之后,默认是256M。即进来文件是1G,就有4个reduce


2)Column Pruning  列裁剪

    1. 说明:假设表有100个字段,常用的只有几个字段,建议在查询时指定字段。

    2. 对于行式存储文件(text文本),查几个字段和查100个字段,并没有本质区别

    3. 对于列式存储文件(orc/parquet),性能会有大大的改变


3)Partition Pruning 分区裁剪


4)join

    big join smal==> mapjoin(工作中不常见)

    big join big ==> bucket(分桶)

    如:分区下面放桶

        t1/pt=20180117/
    000000
    000001
    000002
    ....
    000031
t2/pt=20180117/
    000000
    000001
    000002
    ....

    000031

    说明:假如t1的桶000000的ID 和 t2的桶000000的ID 想同,join就是桶与桶之间的join。

    注意:桶的数量一般使用2的n次方


5)order by 全局排序

    order by 只有1个reduce,(两个的话是做不到排序的),所以生成慎用,1个reduce容易产生数据倾斜


6)sort by 局部排序

    每个reduce内部排序

    Q:假设sort by 有100个task输出,如果一定要全局排序,该怎么办?

    A:??????


7)数据倾斜

    1. 产生原因:就是数据分布不均匀(即:key不均匀)。

        在做join和groupby和count(distinct xxx)的时候,比如:

        1亿  1000w是有userid的,9000w是没有userid

        9000w ===> task (绝大部分的作业跑起来很快,但是有个别作业1-2 非常慢,UI:卡在99%)

        数据量小:可以跑完,但是慢;    数据量大:根本就跑不玩 oom    

    2. 解决数据倾斜:-- key打散

        set hive.groupby.skewindata = true;

            -- 默认为false,这个参数的原理就是以下key打散的原理

        set hive.map.aggr = true;

            -- 默认为true,在group by 查询的时候,决定是否在map端聚合

            -- map端聚合对于mapreduce是combiner的API(本地聚合,小型reduce)

    3. key如何打散: 

        -- udf   写一个UDF,把key进来,再加上一个随机数,返回 key_random

    4. 去掉打散key的随机数

        -- 也是udf   把key_random的random去掉,返回key

www.htsjk.Com true http://www.htsjk.com/hive/37471.html NewsArticle Hive 优化, 1)优化的宏观角度         架构:这个是最重要的,是全局的         1. 分区表:线上环境是普遍存在的,数据量大,不做好合适的分区会导致查询性能极致下降  ...
相关文章
    暂无相关文章
评论暂时关闭