HIVE的基本使用05(HSQL调优)

HIVE的基本使用05(HSQL调优),第1张

HIVE的基本使用05(HSQL调优)

1.fetch抓取

select * from A;这种语句可以直接读取文件,不走MR程序会快很多;

不走MR程序的情况:

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

设置conversion参数后再执行sql:

hive (default)> set hive.fetch.task.conversion=none;

2.本地模式

适用于hive的输入量很少的情况,把数据集中到一台最近的机器上处理。小数据集优化效果明显;

开启本地模式:hive (default)> set hive.exec.mode.local.auto=true; 

执行SQL

关闭本地模式:hive (default)> set hive.exec.mode.local.auto=false; 

自适应开启本地模式:

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;

3.join

小表驱动大表原则;新版本hsql已经被优化;

原因:小表被加载进入内存,大表通过关联条件,跟小表对比;

新版本hive的优化,会通过类似于oracle的表分析数据,自己确定大表还是小表。

4.mapjoin

场景:某张表的某个分区的数据远远高于其他分区,发生数据倾斜;

在map端进行join *** 作:

首先是Task A,它是一个Local Task(在客户端本地执行的Task),负责扫描小表b的数据,将其转换成一个HashTable的数据结构,并写入本地的文件中,之后将该文件加载到DistributeCache中。

接下来是Task B,该任务是一个没有Reduce的MR,启动MapTasks扫描大表a,在Map阶段,根据a的每一条记录去和DistributeCache中b表对应的HashTable关联,并直接输出结果。

案例实 *** :

(1)开启Mapjoin功能

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

执行SQL

5.group by

场景:有一个分组的数据量特别大,就会导致一个reduce的数据处理量特别大,拖慢整个MR程序的运行;此时可以开启group by 的负载均衡参数

实际 *** 作:

(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中),最后完成最终的聚合 *** 作。

6.count(distinct)

场景:直接count(A) 只用一个reduce,数据量大只有一个reduce会非常慢;

实际使用:

SELECt count(id) FROM (SELECt id FROM bigtable GROUP BY id) a;

子查询MR多个reduce处理完成后的结果再去用一个reduce统计;

7.笛卡尔积

避免出现笛卡尔积;

8.分区裁剪列裁剪

用到哪个分区就只取哪个分区的值,用到哪些字段就只取哪些字段,减少MR程序的输入数据量;

9.动态分区调整(复制分区表的时候会用到,可以方便一些)

场景:一张有分区的表,将源数据按照原来的分区,插入到第二张表里,第二张表不用再建立分区了。

实际 *** 作:

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;

实际 *** 作:

set hive.exec.dynamic.partition = true;

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

set hive.exec.max.dynamic.partitions = 1000;

set hive.exec.max.dynamic.partitions.pernode = 100;

set hive.exec.max.created.files = 100000;

set hive.error.on.empty.partition = false;

INSERT overwrite TABLE ori_partitioned_target PARTITION (p_time)

SELECt id, time, uid, keyword, url_rank, click_num, click_url, p_time

FROM ori_partitioned;

注意:在PARTITION (month,day)中指定分区字段名即可;

在SELECt子句的最后几个字段,必须对应前面PARTITION (month,day)中指定的分区字段,包括顺序。

查看分区

hive> show partitions ori_partitioned_target;

10.分桶

11.设置适当的Map数和reduce数(常用记住)

减少map数:

场景:如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

1.小文件合并

set mapred.max.split.size=112345600;

set mapred.min.split.size.per.node=112345600;

set mapred.min.split.size.per.rack=112345600;

set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

这个参数表示执行前进行小文件合并,前面三个参数确定合并文件块的大小,大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),进行合并。

增多map数:

场景:如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,这种情况下,我们要考虑将这一个文件合理的拆分成多个,这样就可以用多个map任务去完成。

set mapreduce.job.reduces =10;

合适的reduce数量:

1)调整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)

2)调整reduce个数方法二

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

设置每个job的Reduce个数

set mapreduce.job.reduces = 15;

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

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

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

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

12.根据执行计划进行调优(会看执行计划,判断调优方式)

1)基本语法

EXPLAIN [EXTENDED | DEPENDENCY | AUTHORIZATION] query

2)案例实 ***

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

hive (default)> explain select * from course;

hive (default)> explain select s_id ,avg(s_score) avgscore from score group by s_id;

(2)查看详细执行计划

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

hive (default)> explain extended select s_id ,avg(s_score) avgscore from score group by s_id;

13.并行执行(常用,在资源比较空闲的时候可以开启)

场景:hsql会有执行计划,把一个sql分成多个阶段,默认一阶段一阶段(阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段)执行。开启并行,在可以同时执行的阶段,hsql就会同时执行   比如union all的情况:

select * from (select * from A union all select * from B);

set hive.exec.parallel=true;              //打开任务并行执行

set hive.exec.parallel.thread.number=16;  //同一个sql允许最大并行度,默认为8。 oracle设置这个只能是双数

14.jvm重用(重要,需要掌握)

场景:task数量特别多,且任务执行时间短,频繁的分配资源初始话会浪费大量的时间。

JVM重用可以使得JVM实例在同一个job中重新使用N次。jvm分配的container资源的重用次数设置。通常在10-20之间,具体多少需要根据具体业务场景测试得出。

实际 *** 作:

Hadoop的mapred-site.xml

  mapreduce.job.jvm.numtasks

  10

  How many tasks to run per jvm. If set to -1, there is

  no limit.

  

在hive当中:

set  mapred.job.reuse.jvm.num.tasks=10;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5679260.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存