[Hive09]Hive基础调优

优化的三个角度:

架构:分区表、合理利用中间结果集

SQL:执行计划

参数:reduce join转map join

      A。column pruning(列裁剪)

            查询的时候需要哪些列,直接查这些列即可,不要全局查询。

           能使用 select a,b,c from xxx,尽量不要使用select * from xxx。

      B。parrtition pruning(分区裁剪)          

          查询的时候需要哪些分区,直接查这些分区即可,不要全局查询。

           能使用 select * from table_name where partition_date='2018-04-10' ; ,尽量不要使用select * from table_name ; 。

      C。对表或分区进行分桶(大表join大表)

            2张表对于连接的字段进行分桶,处理左边表内某个桶的Mapper他知道右边表内对应的行在对应的桶内,因此Mapper只需要获取那个桶,然后取得数据进行JOIN

     D。合理利用中间结果集
        SQL1包含:   select a,b,c,z from xxx group ...   
        SQL2包含:select a,b,c,d,e,f from xxx group ....
 
        我们可以在sql1和sql2执行之前先创建临时表
            create table tmp_1 as select a,b,c,d,e,f,z from xxx group ....

        然后再执行SQL1和SQL2。

        这种方式可以大大地降低I/O,但依赖性加强了。

     E。对大表join小表将reduce join转成map join 

           将小表数据直接通过collect算子拉取到Driver端的内存中来,然后对其创建一个Broadcast变量;接着对大表执行map类算子,在算子函数内,从Broadcast变量中获取较小表的全量数据,与小表的每一条数据按照连接key进行比对,如果连接key相同的话,那么就将两个表数据用你需要的方式连接起来。

 F。启用推测式执行

            一个作业的执行时间取决于最后一个task执行情况,如果最后一个或几个task所在机器负载较高,这就可能会大大增加作业的运行时间,形成长尾作业。我们可以设定一个阈值,比如最后一个或几个task执行时间超得过已经执行时间的 百分之多少的时候,在 另一台或几台低负载机器启动最后一个或几个task,哪边先执行完则采用哪边的结果。

           无论是什么框架,只要问到长尾作业如何解决,就是采用这种 方式。

        关键参数:hive.mapred.reduce.tasks.speculative.execution  是否打开推测式执行,默认为true(打开)

              小伙伴们查一下这个参数对应的阈值是多少哟,去源码里面找

                如果整个集群负载都特别大,这种方式就要慎重啦。 

   G。jvm复用

         MapReduce的每个task都是一个进程,进程的启用和销毁都需要大量时间,启用jvm复用,则下一个task执行直接使用上一个task占用的进程即可,这样可以大大地提升作业的性能。

        jvm复用在Hive只要打开一个参数即可。

       set  mapred.job.reuse.jvm.num.tasks=10;默认值为1,表示一个JVM可以顺序执行的tsak数量为1。

   H。reducer数量优化

       reducer数量过多可能造成小文件过多,reducer数量过少可能造成作业运行太慢。所以合理地配置reducer的数量很重要。

       关键参数1:mapred.reduce.tasks  默认值-1,表示hive会自动设置reducer的数量。(这个参数肯定是要调整的)

      关键参数2:hive.exec.reducers.bytes.per.reducer 0.14版本之后默认值为256MB,表示每一个reducer处理的数据量

  I。排序优化       

       Order By(全局排序):会将所有的数据在一个reducer上执行,得到的结果是整体有序的。但是由于不能并发执行,所以效率比较低。只有一个reducer,作业跑不出来,而且很可能数据倾斜。

       Sort By(局部排序):排序操作在多个reducer上执行,得到的结果是局部有序(一个reducer内)的,但是整体数据不一定是严格有序的。另外,这个语句还可能造成数据的重叠和丢失。由于MapReduce是采用Hash的方式来组织数据的,所以当使用Sort By时,一个reducer的输出会覆盖另一个reducer的数据。

        Distribute By:为Sort By而生!它可以修正SortBy带来的负面作用,避免数据的覆盖和丢失。Distribute By将保证具有相同的指定关键字的记录进入到同一个reducer进行处理,这样就可以避免reducer在输出数据时将不同reducer的记录放到同一个位置,从而造成数据的覆盖!

      J。设置数据负载均衡

          hive和其它关系数据库一样,支持count(distinct)操作,但是对于大数据量中,如果出现数据倾斜时,会使得性能非常差,解决办法为设置数据负载均衡,其设置方法为设置hive.groupby.skewindata参数。改参数默认值为false,设置为true可以解决一般的数据倾斜问题。当然,如果对于group by导致的数据倾斜,则最好还要设置hive.map.aggr参数(对应MR中的combiner),启用该参数执行聚合操作会先在map端进行一次聚合。

     K。predicate pushdown(ppd谓词下压)

        hive.optimize.ppd:是否支持谓词下推,默认开启;所谓谓词下推,将外层查询块的 WHERE 子句中的谓词移入所包含的较低层查询块(例如视图),从而能够提早进行数据过滤以及有可能更好地利用索引。

       hive.optimize.ppd.storage:谓词下推开启时,谓词是否下推到存储handler,默认开启,在谓词下推关闭时不起作用;

       hive.ppd.recognizetransivity:在等值join条件下是否产地重复的谓词过滤器,默认开启;

     L。压缩调优:

                [Hive08]

     M。存储格式调优:

                [Hive09]

猜你喜欢

转载自blog.csdn.net/pengzonglu7292/article/details/81352275
今日推荐