Hive调优(配置、表优化、MR优化等)

一.配置优化

1.Fetch

  • 概念:Hive中某些查询可以不必进行MR运算,比如select X from table,简单的读取和输出table对应目录下的文件,可以不必使用到MR。

  • 此时可以查看hive.fetch.task.conversion的设置,可以看到

<property>
    <name>hive.fetch.task.conversion</name>
    <value>more</value>
    <description>
      Expects one of [none, minimal, more].
      Some select queries can be converted to single FETCH task minimizing latency.
      Currently the query should be single sourced not having any subquery and should not have
      any aggregations or distincts (which incurs RS), lateral views and joins.
      0. none : disable hive.fetch.task.conversion
      1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only 所有的都要走MR
      2. more    : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
   </description>
 </property>
       
          
          
/*
	none:不开启hive.fetch.task.conversion,也就是所有情况都启用MR
	
	minimal:对于简单查询(select  *)、或者对分区列的过滤,以及使用limit时,不会启用MR
	
	more:简单查询(select  *)、过滤查找、limit查找,都不会触发MR(范围更广,它还包括时间戳、虚拟的列)
*/
  • 更改配置

    可以进入hive控制台,输入set hive.fetch.task.conversion进行查看当前的设置,老版本默认minimal,现在默认为more。手动更改,使用命令set hive.fetch.task.conversion=more

在这里插入图片描述


2.本地模式

  • 概念:有的Hive数据量非常小,那么就直接在本地执行,而不用提交集群了。通过本地模式在单台机器上处理任务,对于小的数据集,可以明显缩短执行时间。

  • 开启方式

    set hive.exec.mode.local.auto = true

  • 开启条件(需要满足2个条件,可以手动更改)

    1. 使用命令 set hive.exec.mode.local.auto.inputbytes.max 查看数据大小上限(默认128MB)

      在这里插入图片描述

    2. 使用命令 set hive.exec.mode.local.auto.input.files.max 查看文件数量上限(默认4)

      在这里插入图片描述


二.表的优化

1.小表、大表 join

将key相对分散,并且数据量小的表放在join的左边,可以有效减少内存溢出发生的机率(新版的hive已经对此进行优化,放在左或右已经没有明显区别,但习惯还是将小表写在前面)。


2.大表、大表 join

  • 提前进行空key过滤,减少join的次数

  • 如果空key是需要保留数据,则需要赋一个随机值,避免所有空key分配到一个reduce中,发生数据倾斜

    insert overwrite into customer
    
    select p.* from person p
    join temp t
    on
    -- 在这里进行判断,通过拼接‘p’和‘随机数’进行赋值
    case when p.id is null then concat('p',rand()) else p.id end = t.id;
    

3.Map Join

  • 概念:可以使用map join让小的维度表(1000条以下的记录数)先进入内存,在map端完成reduce

  • 开启方式:set hive.auto.convert.join = true

  • 开启条件

    文件大小不能超过25MB,可以通过 set hive.mapjoin.smalltable.filesize 查看,也可以手动更改

    在这里插入图片描述


4.Group By的map端聚合

  • 概念:很多聚合操作在map端进行了部分聚合,最后在reduce端得出最终结果;group by可以使用map端作为第一级聚合,但通常需要消耗更多的内存。

  • 开启方式

    //是否在map端进行聚合,默认true
    set hive.map.aggr;
    
    //在map端进行聚合操作的数目,默认100000
    set hive.groupby.mapaggr.checkinterval;
    
    //是否在数据倾斜时进行负载均衡,默认false
    set hive.groupby.skewindata;
    

5.Count去重

  • count(distinct):在数据量不大的情况下,使用distinct没有问题,但数据量过大的情况下,开销太大会导致job无法完成。
  • count + group by:时间可能不如distinct快,并且多使用了一个job,但是在数据量很大的情况下也能够保证任务顺利完成。

6.避免笛卡尔积

在没有需求的情况下,尽量避免使用笛卡儿积,因为很容易会造成非常大的开销。所以在join的时候,避免使用无效的on条件,


7.行列过滤

  • 列过滤:少用select *,只取需要的列

  • 行过滤:在分区剪裁中,如果将副表过滤条件写在where后面,那么就会先进行全表关联然后再过滤。所以,恰当的写法为,先通过子查询后,再进行关联,比如

    select 
    	a.id,
    	a.name,
    	b.city 
    from a
    join 
    	-- 先进行过滤
    	(select id,city from b where id < 10)
    on
    a.id = b.id
    

8.动态分区

  • 概念:hive可以自动给数据进行分区,同时还可以将数据插入到相应分区中。但默认时静态分区(strict),需要手动来配置。

  • 开启方式

    set hive.exec.dynamic.partition.mode = nonstrict;

    hive.exec.dynamic.partition =true;

    set hive.exec.max.dynamic.partitions = 1000;(所有MR节点上,最大动态分区数,默认1000)

    set hive.exec.max.dynamic.partitions.pernode = 500;(每个节点动态分区最大数值,默认100)

  • 测试

    -- 创建一张动态分区表
    create table temp_par(
        name string,
        age int
    )
    partitioned by (id int)
    row format delimited 
    fields terminated by '\t';
    
    -- 插入数据(需要按照字段顺序,并且分区字段一定是最后一个数值)
    insert into table temp_par partition(id) values("zhangsan",22,4);
    
    -- 自定义字段插入数据(这样就可以不对应顺序插入)
    insert into table temp_par partition(id) (id,name,age) values(3,"lisi",19);
    

三.MR优化

  • 对于数据需要有一定的了解,为任务分配合适的map数量,也可以设置最大切片数量等。同时,也需要设置合理的reduce数量,每个reduce处理数据默认是256MB,每个任务再大的reduce数默认是1009。通过set mapreduce.job.reduces的值可以调整每个job的reduce个数。

  • 另外,过多的reduce启动和初始化也会消耗时间和资源,并且reduce数决定了输出文件数,如果生成很多小文件,这些文件作为下一个任务的输入,则也需要注意小文件过多的问题。


四.并行执行

  • 概念:开启并行执行,在资源充足的情况下,可以让多个没有依赖的阶段一块儿执行,那么job的执行速度也能够提升。

  • 开启方式

    -- 开启并行执行,默认为false
    set hive.exec.parallel = true;
    
    -- 同一个sql允许最大并行度,默认为8
    set hive.exec.parallel.thread.number = 16;
    

五.严格模式

  • 概念:hive限制了一些语句的执行,以防止用户执行可能意想不到的有不良影响的语句。

  • 开启方式

    set hive.mapred.mode = strict

<property>
  <name>hive.mapred.mode</name>
  <value>nonstrict</value>
  <description>The mode in which the Hive operations are being performed.
     In strict mode, some risky queries are not allowed to run. They include:
       Cartesian Product.
       No partition being picked up for a query.
       Comparing bigints and strings.
       Comparing bigints and doubles.
       Orderby without limit.
  </description>
</property>
           
           
/*
	限制笛卡尔积
	对于分区表的执行命令,where后未包含分区字段过滤条件,不允许执行
	使用了orderby的查询,要求必须有limit语句
*/

六.JVM重用

  • 概念:JVM重用是对于Hadoop调优参数的内容,Hadoop默认使用派生JVM来执行map和reduce任务,JVM的启动过程可能占用了大量开销。开启JVM重用,可以使得JVM实例能够使用多次,使用次数可以在自行设置,通常在10—20之间。

  • 开启方式

    1. 在mapred-site.xml中设置

      <property>
        <name>mapreduce.job.jvm.numtasks</name>
        <value>10</value>
        <description>How many tasks to run per jvm. If set to -1, there is
        no limit. 
        </description>
      </property>
      
    2. set mapreduce.job.jvm.numtasks = 10;(默认是1)

  • 适用场景:有过多的小文件的生成、过多的task的场景。


七.推测执行

  • 概念:在分布式环境下,如果出现同一个作业多个任务之间运行速度不一致,有些任务明显慢于其他任务,则这些任务会拖慢整体执行速度。为了避免这种情况,Hadoop采用推测执行机制,它根据一定算法推测出运行慢的任务,并开启一个备份任务与原始任务同时处理一份数据,并最终选用先成功完成的任务计算结果为最终结果。

  • 特点:以资源换取时间,消耗更多的资源

  • 开启方式

    1. Hadoop可以更改配置文件进行开启

    2. hive也提供了配置项目来控制reduce-side的推测执行

      hive.mapred.reduce.tasks.speculative.execution = true

猜你喜欢

转载自blog.csdn.net/qq_40579464/article/details/105739275