关于Hive的一些优化

关于Hive的优化(仅供参考) :

    1、关于join中 出现数据倾斜的操作 : 

             这里我们需要设置两个参数 : 

            1.1、hive.optimize.skewjoin=true; 解释 : 如果join中出现了数据倾斜,应该设置成true。

            1.2、set hive.skewjoin.key=1000000; 解释 : 这是join的键对应的记录条数超过这个值则会进行优化。而这个优化的措施是 : 正常只有一个job来执行任务的,优化后会出现两个job来执行任务。当数据量达到1000000以上的时候 , hive会在启动一个job , 然后将原有的数据的key加上一个随机数将数据打乱。这样数据就会分到不同的节点上去计算。       

            最后在原有打乱的基础上在做一次运算,然后在启动一个job, 恢复原来的key, 在做一次运算。

      2、关于maojoin的操作 : 

             2.1、其实maojoin的优化很简单, 就是将我们的小表加载到缓存中, 这样所有的节点都可以访问到这个小表(有点像广播变量)。 怎么样开启这种方式呢?

             set hive.auto.convert.join=true; 解释: hive.mapjoin.smalltable.filesize默认是25MB。什么意思呢?这个值是自己判断的, 就是当表格文件小于25MB的时候, 会自动启动mapjoin。(建议自己手动启动!)

             手动启动方式:select /*+ maojoin(A)*/ f.a,f.b from A t join B f on (f.a=t.b and f.ftime=20110802) 

   其中A是小表, B是大表, 这样我们是让join发生在map端。

         注意 : Mapjoin使用的场景

              1、关联操作中有一张小表    2、不等值的连接操作  3、mapjoin最好是手动操作

     3、对于bucket join的操作 :

            3.1、两个表以相同的方式划分桶。

            3,2、两个表的桶的个数是倍数关系。

       例子: creat table order(cid int,price float) clustered by (cid) into 30 buckets;

                creat table customer(cid int,price string) clustered by (cid) into 60 buckets;                                                  select price from order t join customer s on t.cid=s.id;

    4、关于where和join的操作

            4.1、优化前 : select o* from order o join customer c on o.cid=d.id where o.time='2017-01-01';        优化后 : select o.* from (select cid from order where time='2017-01-01')o join customer c on o.cid=c.id; 

        解释 :优化前是先join后在where进行过滤的 , 这样并没有减轻reduce的压力。 优化后是在mao端执行where, 过滤数据, 然后在join的。这样大大降低了计算量。

    5、关于group by的操作 :

            5.1、hive.groupby.skewindata=true; 解释 : 如果group by过程中出现数据倾斜 , 应该设置成true。                    5.2、set hive.groupby.maoagger.checkinterval=1000000; 解释 : group 对应的键对应的记录数超过这个值则会进行优化,优化方案跟上面一样, 也会运行来年各个job。

    6、对于HIVE表的操作 :

            6.1、分区 : '表'相当于一个大目录,分区就是在这个大目录下面创建一个个的小目录。而且分区字段不能是表中已经存在的字段 , 分区的字段不是真实存在的 , 这会显示给你看也可以查询, 但是不会存在表中。

          分区分为静态分区和动态分区 :                                                                                                                  静态分区 : 就是在建表的时候指定分区。                                                                                                            动态分区 : set hive.exec.dynamic.partition=true;                                                                                                              set hive.exec.dynamic.partition.mode=nonstrict;                                                                                   下面这个设置的默认值是strict 。 描述 :strict是避免分区字段全部都是动态的 , 也就是至少一个分区字段是有指定值的。我们一般用nonstrict ,就是所有的分区字段都可以是动态的。

    7、下面是通过对hive job的优化来优化hive

       7.1、并行化执行 : ive执行过程中的job是按照默认的顺序来执行的,如果没有太大的依赖关系,最好并行执行,减少执行的时间, 每个查询被hive转化成多个阶段,有些阶段关联性不大,则可以并行执行,减少执行时间。                                                                                                                                                                            set hive.exec.parallel=true;

          set hive.exec.parallel.thread.numbe=16(默认8);

        7.2、本地化执行 : 首先开启本地化执行 : set hive.exec.mode.local.auto=true;                                                         当一个job满足如下条件的时候才会真正使用本地模式来执行 :
                    1、job的输入数据大小必须小于参数 :
                     hive.exec.mode.local.auto.inputbytes.max        (默认是128MB)
                     2、job的map数必须小于参数:
                      hive.exec.node.local.auto.tasks.max            (默认是4)

                     3、job的reduce必须是0或者是1。

        7.3、job合并输入的小文件
             在集群中面临这样的问题, 就是集群中有很多的小文件 , 这样会启动很多的(FileinputFormat会调用getsplit()方法对文件进行split , 而spilt的个数决定了map的个数), 而且这小文件执行的时间短, 甚至还没有我们调用资源用的时间多 , 造成了集群资源的严重浪费。

            解决 : set hive.input.format=oar.apache.hadoop.hive.ql.io.CombineHiveInputForma          这样做以后,就会把多个split分片合并成一个。 而合并的文件数由mapred.max.split.size限制的大小来决定

        7.4、job合并输出小文件 :
                小文件的输出虽然不占用多大的磁盘空间 但是不要忘记无论多小的文件都会在HDFS的namenode上面存在一条元数据记录下来.很浪费资源。
         解决 : set hive.merge.smallfiles.avgsize=256000000;当输出文件平均大小小于该值,启动新job合并文件

                  set hive.merge.size.per.task=64000000;设定合并之后的文件大小  

         7.5、JVM的重利用 :  
               JVM的重用是可以使得JVM实例在同一个JOB中重新实用N次
                       方法 : set mapred.job,reduse.jvm.num.tasks=10; 
               JVM的重用对hive的性能有很大的影响, 特别是对小文件的场景或者是task特别多场景 , 可以有效地减少执行时间。 
        7.6、关于数据的压缩 :   
              两种压缩方式 : 中间压缩和最终压缩 :  

             中间压缩 ;  减少网络传输的数据量,中间压缩,不需要压缩效果特别好 , 选择一个节省CPU耗时的压缩方式就行。
            set hive.exec.compress.intermediate=true;
            set hive.intermedia.compression.codec=org.apache.hadoop.io.compress.SnappyCode;
            set hive.intermedia.compression.type=BLOCK;(按照块进行压缩)
              hive查询的最总输出结果的压缩 : 这个阶段可以选择一个压缩效果比价好的 , 这样可以境地集群存储的数据量, 占用较小的空间。
            set hive.exec.compress.ouput=true;
             set mapred.output.compresssion.codec=org.apache.hadoop.io.compress.GzipCodec;
            set hive.intermedia.compression.type=BLOCK;

                    


仅供参考!

猜你喜欢

转载自blog.csdn.net/weixin_41928342/article/details/80013105