Hive提供三种可以改变环境变量的方法,分别是:

(1)修改${HIVE_HOME}/conf/hive-site.xml配置文件;

      所有的默认配置都在${HIVE_HOME}/conf/hive-default.xml文件中,如果需要对默认的配置进行修改,可以创建一个hive-site.xml文件,放在${HIVE_HOME}/conf目录下。里面可以对一些配置进行个性化设定。这里做的配置都全局用户都生效,而且是永久的

(2)命令行参数;

在启动Hive cli的时候进行配置,可以在命令行添加-hiveconf param=value来设定参数;这一设定对本次启动的会话有效,下次启动需要重新配置。

(3)在已经进入cli时进行参数声明。

可以在HQL中使用SET关键字设定参数,这种配置也是对本次启动的会话有效,下次启动需要重新配置。在HQL中使用SET关键字还可以查看配置的值。

  set后面什么都不添加,这样可以查到Hive的所有属性配置。

上述三种设定方式的优先级依次递增。即参数声明覆盖命令行参数,命令行参数覆盖配置文件设定。

   Hive-05 参数调优

  服务器和客户端中都要进行配置;

https://www.cnblogs.com/ITtangtang/p/7683028.html

1. 执行计划(Explain)

1基本语法

EXPLAIN [EXTENDED | DEPENDENCY | AUTHORIZATION] query

2案例实操

(1)查看下面这条语句的执行计划

没有生成MR任务的

hive (default)>  explain select * from emp;

Fetch Operator

Explain
STAGE DEPENDENCIES:
  Stage-0 is a root stage

STAGE PLANS:
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        TableScan
          alias: emp
          Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: empno (type: int), ename (type: string), job (type: string), mgr (type: int), hiredate (type: string), sal (type: double), comm (type: double), deptno (type: int)
            outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5, _col6, _col7
            Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
            ListSink
View Code

有生成MR任务的

hive (default)> explain select deptno, avg(sal) avg_sal from emp group by deptno;

 Map Operator Tree:

  Reduce Operator Tree:

    Select Operator

              File Output Operator

 

  Fetch Operator

 

Explain
STAGE DEPENDENCIES:
  Stage-1 is a root stage
  Stage-0 depends on stages: Stage-1

STAGE PLANS:
  Stage: Stage-1
    Map Reduce
      Map Operator Tree:
          TableScan
            alias: emp
            Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
            Select Operator
              expressions: sal (type: double), deptno (type: int)
              outputColumnNames: sal, deptno
              Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
              Group By Operator
                aggregations: sum(sal), count(sal)
                keys: deptno (type: int)
                mode: hash
                outputColumnNames: _col0, _col1, _col2
                Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
                Reduce Output Operator
                  key expressions: _col0 (type: int)
                  sort order: +
                  Map-reduce partition columns: _col0 (type: int)
                  Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
                  value expressions: _col1 (type: double), _col2 (type: bigint)
      Execution mode: vectorized
      Reduce Operator Tree:
        Group By Operator
          aggregations: sum(VALUE._col0), count(VALUE._col1)
          keys: KEY._col0 (type: int)
          mode: mergepartial
          outputColumnNames: _col0, _col1, _col2
          Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: _col0 (type: int), (_col1 / _col2) (type: double)
            outputColumnNames: _col0, _col1
            Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
            File Output Operator
              compressed: false
              Statistics: Num rows: 1 Data size: 7020 Basic stats: COMPLETE Column stats: NONE
              table:
                  input format: org.apache.hadoop.mapred.SequenceFileInputFormat
                  output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
                  serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        ListSink
View Code

(2)查看详细执行计划

hive (default)> explain extended select * from emp;

hive (default)> explain extended select deptno, avg(sal) avg_sal from emp group by deptno;

 

2. Fetch抓取

Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文

件,然后输出查询结果到控制台。

hive-default.xml文件中

   hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

   set hive.fetch.task.conversion.threshold=1073741824,可调整阈值,默认1G,小于1G才会使用Fatch抓取模式;

Fetch抓取
 set hive.fetch.task.conversion=none;  
把hive.fetch.task.conversion设置成none,然后执行查询语句,都会执行mapreduce程序。 select * from emp; // number of mappers: 1; number of reducers: 0

set hive.fetch.task.conversion=more;
把hive.fetch.task.conversion设置成more,然后执行查询语句,如下查询方式都不会执行mapreduce程序。 select * from emp;

3. 本地模式

大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,

有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务消耗的时间可能会比实际job的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器

上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

可通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化,默认是false。

set hive.exec.mode.local.auto=true;  //开启本地mr
set hive.exec.mode.local.auto.inputbytes.max=50000000; //设置local mr的最大输入数据量,当输入数据量小于这个值时采用local,  mr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.input.files.max=10;   //设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local,  mr的方式,默认为4
当一个job满足如下条件才能真正使用本地模式:
  1.job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)
  2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)
  3.job的reduce数必须为0或者1
可用参数hive.mapred.local.mem(默认0)控制child jvm使用的最大内存数。

4. 并行执行

Hive会将一个查询转化成一个或者多个阶段。这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能需要的其他阶段。

默认情况下,Hive一次只会执行一个阶段。不过,某个特定的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整

个job的执行时间缩短。不过,如果有更多的阶段可以并行执行,那么job可能就越快完成。

       通过设置参数hive.exec.parallel值为true,就可以开启并发执行。不过,在共享集群中,需要注意下,如果job中并行阶段增多,那么集群利用率就会增加。

set hive.exec.parallel=true;              //打开任务并行执行
set hive.exec.parallel.thread.number=16;  //同一个sql允许最大并行度,默认为8。
当然,得是在系统资源比较空闲的时候才有优势,否则,没资源,并行也起不来。

 

5. 合理设置Map及Reduce数

Reduce的个数对整个作业的运行性能有很大影响。如果Reduce设置的过大,那么将会产生很多小文件,对NameNode会产生一定的影响,而且整个作业的运行时间未必会减少;如果

Reduce设置的过小,那么单个Reduce处理的数据将会加大,很可能会引起OOM异常。

1)通常情况下,作业会通过input的目录产生一个或者多个map任务。

主要的决定因素有:input的文件总个数,input的文件大小,集群设置的文件块大小。

2)是不是map数越多越好?

答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑

处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

3)是不是保证每个map处理接近128m的文件块,就高枕无忧了?

答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去

做,肯定也比较耗时。针对上面的问题2和3,我们需要采取两种方式来解决:即减少map数和增加map数;

5.1 复杂文件增加Map数

当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数来使得每个map处理的数据量减少,从而提高任务的执行效率。

增加map的方法为:根据computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M公式,调整maxSize最大值。让maxSize最大值低于blocksize就可以增

加map的个数。

1.执行查询
hive (default)> select count(*) from emp;
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1

2.设置最大切片值为100个字节
hive (default)> set mapreduce.input.fileinputformat.split.maxsize=100;
hive (default)> select count(*) from emp;
Hadoop job information for Stage-1: number of mappers: 6; number of reducers: 1

5.2 小文件进行合并

配置Map输入合并
  -- 每个Map最大输入大小,决定合并后的文件数
set mapred.max.split.size=256000000;
-- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并 set mapred.min.split.size.per.node=100000000;
-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并 set mapred.min.split.size.per.rack=100000000;
-- 执行Map前进行小文件合并; 在map执行前合并小文件,减少map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。
-- HiveInputFormat没有对小文件合并功能。 set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 配置在Map-Reduce任务结束时合并小文件 我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并: set hive.merge.mapfiles=true //在map-only job后合并文件,默认true,在map-only任务结束时合并小文件
set hive.merge.mapredfiles=true //在map-reduce job后合并文件,默认false,设为true 在map-reduce任务结束时合并小文件
set hive.merge.size.per.task=true //合并后每个文件的大小,默认268435456,合并文件的大小,默认256M
set hive.merge.smallfiles.avgsize=true //平均文件大小,是决定是否执行合并操作的阈值,默认16777216,当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge Hive在对结果文件进行合并时会执行一个额外的map-only脚本,mapper的数量是文件总大小除以size.per.task参数所得的值,触发合并的条件是:   根据查询类型不同,相应的mapfiles/mapredfiles参数需要打开;   结果文件的平均大小需要大于avgsize参数的值。

5.3 合理设置Reduce数

1.调整reduce个数方法一

(1)每个Reduce处理的数据量默认是256MB

  hive.exec.reducers.bytes.per.reducer=256000000

(2)每个任务最大的reduce数,默认为1009

  hive.exec.reducers.max=1009

(3)计算reducer数的公式

  N=min(参数2,总输入数据量 / 参数1)

2.调整reduce个数方法二

  在hadoop的mapred-default.xml文件中修改

  设置每个job的Reduce个数

  set mapreduce.job.reduces = 15;

3.reduce个数并不是越多越好

  1)过多的启动和初始化reduce也会消耗时间和资源;

  2)另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

  在设置reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的reduce数;使单个reduce任务处理数据量大小要合适;

reduce数量由以下三个参数决定:

  • mapred.reduce.tasks ( 强制指定reduce的任务数量,默认为-1 )
  • hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为256000000)
  • hive.exec.reducers.max(每个任务最大的reduce数,默认为1009)

计算reducer数的公式很简单 N = min ( hive.exec.reducers.max ,总输入数据量/ hive.exec.reducers.bytes.per.reducer )

6. 表的优化

6.1 小表join 大表 MapJoin

将key相对分散,并且数据量小的表放在join的左边,可以使用map join让小的维度表先进内存。在map端完成join。

如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加

载到内存在map端进行join,避免reducer处理。

Hive-05 参数调优

1.开启MapJoin参数设置

(1)设置自动选择Mapjoin

set hive.auto.convert.join = true;  // 默认为true

(2)大表小表的阈值设置(默认25M一下认为是小表):

set hive.mapjoin.smalltable.filesize=25000000;

key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用map join让小的维度表(1000条以下的记录条数)先进内存。

在map端完成reduce。

实际测试发现:新版的hive已经对小表JOIN大表和大表JOIN小表进行了优化。小表放在左边和右边已经没有明显区别。

Hive0.11之后 set hive.auto.convert.join=true 默认是true,即开启了map join的优化;

hive.mapjoin.smalltable.filesize=25000000   通过配置该属性来确定使用该优化的表的大小,如果表的大小小于此值(25M)就会被加载进内存中

Hive-05 参数调优
创建大表、小表、join后的表、加载数据、
hive (default)> create table bigtable(
              > id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string)
              > row format delimited fields terminated by '\t';
OK
Time taken: 0.103 seconds
hive (default)> create table smalltable(
              > id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string)
              > row format delimited fields terminated by '\t';
OK
Time taken: 0.109 seconds
hive (default)> create table jointable(
              > id bigint, time bigint, uid string, keyword string, url_rank int, click_num int, click_url string)
              > row format delimited fields terminated by '\t';
OK
Time taken: 0.486 seconds
hive (default)> load data local inpath '/opt/module/datas/bigtable' into table bigtable;
Loading data to table default.bigtable
Table default.bigtable stats: [numFiles=1, totalSize=120734753]
OK
Time taken: 1.26 seconds
hive (default)> load data local inpath '/opt/module/datas/smalltable' into table smalltable;
Loading data to table default.smalltable
Table default.smalltable stats: [numFiles=1, totalSize=12018355]
OK
Time taken: 3.736 seconds
hive (default)> set hive.auto.convert.join=false; 关闭mapjoin功能(默认是打开的)
小表join大表
hive (default)> insert overwrite table jointable select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url from smalltable s left join bigtable b on s.id=b.id;
Time taken: 40.392 seconds
大表join小表
hive (default)> insert overwrite table jointable select b.id, b.time, b.uid, b.keyword, b.url_rank, b.click_num, b.click_url from bigtable b left join smalltable s on b.id=s.id;
Time taken: 39.82 seconds
View Code

相关文章: