Hive调优

作者: 康俊1024 | 来源:发表于2019-08-26 11:48 被阅读0次
    1. Fetch抓取(Hive可以避免进行MapReduce)
      Hive中对某些情况的查询可以不必使用MapReduce计算。(计算需要时间)
      例如:SELECT * FROM user; Hive可以简单地读取user对应的存储目录下的文件,然后输出查询结果到控制台。
      在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走MapReduce。
    <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>
    
    1. 本地模式
      当Hive的输入数据量非常小的情况下,为查询触发执行任务时消耗的时间可能会比实际job的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显缩短。
      可以设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。
    set hive.exec.mode.local.auto=true;  //开启本地MR
    //设置local MR的最大输入数据量,当输入数据量小于这个值时采用local  MR的方式,默认为134217728,即128M
    set hive.exec.mode.local.auto.inputbytes.max=51234560;
    //设置local MR的最大输入文件个数,当输入文件个数小于这个值时采用local MR的方式,默认为4
    set hive.exec.mode.local.auto.input.files.max=10;
    
    1. 并行执行
      Hive会将一个查询转化成一个或多个阶段。可能是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能需要的其他阶段。默认情况下,Hive一次只会执行一个阶段。不过有的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整个job的执行时间缩短。
      可以设置参数hive.exec.parallel值为true开启并发执行。不过,在共享集群中,如果job中并行阶段增多,那么集群利用率就会增加。在系统资源比较空闲的时候才有优势,否则,没资源,并行也起不来。
    set hive.exec.parallel=true;              //打开任务并行执行
    set hive.exec.parallel.thread.number=16;  //同一个sql允许最大并行度,默认为8。
    
    1. 严格模式
      Hive提供了严格模式,可以防止用户执行那些可能意向不到的不好的影响的查询。
      通过设置属性hive.mapred.mode的值,默认是非严格模式nonstrict 。开启严格模式需要修改hive.mapred.mode值为strict,开启严格模式可以禁止3种类型的查询。
    <property>
        <name>hive.mapred.mode</name>
        <value>strict</value>
      </property>
    
    • 分区表上没有指定了分区(分区表数量很大)
    • 没有limit限制的order by语句
    • 笛卡尔积:JOIN时没有ON语句
    1. 动态分区
      以第一个表的分区规则,来对应第二个表的分区规则,将第一个表的所有分区,全部拷贝到第二个表中来,第二个表在加载数据的时候,不需要指定分区了,直接用第一个表的分区即可。
    (1)开启动态分区功能(默认true,开启)
    set hive.exec.dynamic.partition=true;
    (2)设置为非严格模式(动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。)
    set hive.exec.dynamic.partition.mode=nonstrict;
    (3)在所有执行MR的节点上,最大一共可以创建多少个动态分区。
    set  hive.exec.max.dynamic.partitions=1000;
    (4)在每个执行MR的节点上,最大可以创建多少个动态分区。该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。
    set hive.exec.max.dynamic.partitions.pernode=100
    (5)整个MR Job中,最大可以创建多少个HDFS文件。
    在linux系统当中,每个linux用户最多可以开启1024个进程,每一个进程最多可以打开2048个文件,即持有2048个文件句柄,下面这个值越大,就可以打开文件句柄越大
    set hive.exec.max.created.files=100000;
    (6)当有空分区生成时,是否抛出异常。一般不需要设置。
    set hive.error.on.empty.partition=false;
    
    1. 推测执行
      它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
      设置开启推测执行参数:Hadoop的mapred-site.xml文件中进行配置
    <property>
      <name>mapreduce.map.speculative</name>
      <value>true</value>
    </property>
    <property>
      <name>mapreduce.reduce.speculative</name>
      <value>true</value>
    </property>
    

    hive本身也提供了配置项来控制reduce-side的推测执行

      <property>
        <name>hive.mapred.reduce.tasks.speculative.execution</name>
        <value>true</value>
      </property>
    
    1. 分组(Group By)
      默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。
      并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。
    (1)是否在Map端进行聚合,默认为True
    set hive.map.aggr = true;
    (2)在Map端进行聚合操作的条目数目
    set hive.groupby.mapaggr.checkinterval = 100000;
    (3)有数据倾斜的时候进行负载均衡(默认是false)
    set hive.groupby.skewindata = true;
    

    当设定为 true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。

    1. 小文件进行合并
      在Map执行前合并小文件,可以减少Map数。
    hive.merg.mapfiles=true:合并map输出
    hive.merge.mapredfiles=false:合并reduce输出
    hive.merge.size.per.task=256*1000*1000:合并文件的大小
    hive.mergejob.maponly=true:如果支持CombineHiveInputFormat则生成只有Map的任务执行merge
    hive.merge.smallfiles.avgsize=16000000:文件的平均大小小于该值时,会启动一个MR任务执行merge。
    
    1. 适当的增加Map数
      当input的文件很大,任务逻辑复杂,Map执行非常慢的时候,可以考虑增加Map数,来使得每个Map处理的数据量减少,从而提高任务的执行效率。控制map数量需要遵循两个原则:使大数据量利用合适的map数;使单个map任务处理合适的数据量;
      set mapreduce.job.reduces =10;
    2. 调整reduce数
    • 调整reduce个数方法一
    (1)每个Reduce处理的数据量默认是256MB
    hive.exec.reducers.bytes.per.reducer=256123456
    (2)每个任务最大的reduce数,默认为1009
    hive.exec.reducers.max=1009
    (3)计算reducer数的公式
    N=min(参数2,总输入数据量/参数1)
    
    • 调整reduce个数方法二
      在hadoop的mapred-default.xml文件中修改
      设置每个job的Reduce个数
      set mapreduce.job.reduces = 15;
      reduce个数并不是越多越好,启动和初始化reduce会消耗时间和资源;有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;在设置reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的reduce数;使单个reduce任务处理数据量大小要合适;

    相关文章

      网友评论

        本文标题:Hive调优

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