Hive的调优

Hive作为数据仓库的管理工具,经常处理大量数据,但是又基于hadoop平台的,底层运行的是mapreduce,所以它在分布式处理大量数据的优势就很明显,但是优势又往往是劣势所在.
没有哪款软件是完美的,所以hive在实时处理的短板就交给后续 的Impala给补齐吧.
在此不讨论实时处理的范畴,只是简单介绍几种Hive在查询数据上的优化小知识.

第一种方式:Fecth抓取
作用:改变查询的底层运行方式,减少不必要的mapreduce流程,比如一些查询语句
select * from score.等等这类型简单查询可以通过直接读取文件就可以得到结果的查询语句,就不必要使用mapreduce程序来运行,减少资源的分配调度时间等
设置不执行mapreduce程序:set hive.fetch.task.conversion=more;
设置执行mapreduce程序:set hive.fetch.task.conversion=none;

第二种方式:本地模式
作用:在处理小数据集的时候,使用本地模式,在单台机器上处理任务,会缩短任务的执行时间
开启本地模式:set hive.exec.mode.local.auto=true;
关闭本地模式:set hive.exec.mode.local.auto=false;

第三种方式:MapJoin
作用:在小表关联大表的情况下,在map阶段可以通过把小表加载到分布式缓存上,然后在处理大表的map阶段的时候就可以把小表加载下来使用,这样就减少了reduce阶段的任务,避免数据倾斜,使用Hive可以直接设定即可,比使用API容易许多.
1.设定自动选择MapJoin: set hive.auto.convert.join = true;
2.设置大表和小表的阈值,默认是25M:set hive.mapjoin.smalltable.filesize=25123456;

第四种方式:GroupBy分组
作用:默认情况下,map阶段的相同key都会把value发送给reduce进行合并,如果某一个key的数据比较大,容易产生数据倾斜,所以分组就是为了把数据的聚合在map阶段进行,最后再把结果交给reduce统一处理.
1.开启map端的聚合功能(默认是开启的):set hive.map.aggr = true;
2.设置在map进行聚合的条目数量(具体数值根据数据量自行选择):set hive.groupby.mapaggr.checkinterval = 10000;
3.设置在数据倾斜的时候采用负载均衡:set hive.groupby.skewindata = true;
开启负载均衡后会生成两个MR job 任务
第一个job任务的map阶段的输出结果会随机的分配到不同reduce中,可能相同key的数据也不一定就在同一个reduce中
第二个job任务才会根据分组把相同的key的value都放在同一个reduce上完成聚合

第五种方式:Count(distinct)
Count(distinct)语句是先进行去重再统计数量的,distinct只能放在同一个reduce中处理,不然的话去重效果就没有,结果就没有意义了,在这种时候如果该数据量非常大,去重任务全部集中在一个reduce中,数据倾斜性就太大,效率很低.所以解决方法就是分组后再统计
示例代码:
1.优化前:select count(distinct s_id) from score;
2.优化后:select count(s_id) from (select id from score group by s_id) a;
优化后的代码虽然会启用多一个子任务/job任务来执行分组,但是在数据量大的情况下是值得的.

第六种方式:避免笛卡尔积
笛卡尔积产生的原因主要是在做内/外连接的时候没有加上on条件,导致查询结果的数据量成倍增长,很多不必要的数据也会生成,冗余性太高,所以一定要避免笛卡尔积 的查询方式.

第七种方式:动态分区调整
目的:简单来说就是为了满足在表之间部分/全部拷贝数据的时候把分区规则也一并拷贝过去,新表在加载的时候就无须再指定分区规则了.
参数设置:
1.开启动态分区功能(默认true,开启)
set hive.exec.dynamic.partition=true;
2.设定为非严格模式,因为只有在nonstrict模式下所有分区字段才可以使用动态分区
set hive.exec.dynamic.partition.mode=nonstrict;
3.设置在所有MR节点上最大一共可以创建多少个动态分区(数量都是根据数据需求而定)
set hive.exec.max.dynamic.partitions=1000;
4.设置单个MR节点上最多可以创建多少个动态分区(数量根据实际数据而定)
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;

第八种方式:并行执行
Hive在执行的时候会将查询分为多个阶段,比如MR阶段,抽样阶段,合并以及limit阶段等等.如果一个job任务分为多个阶段,同时每个阶段之间又不相互依赖,可以并行执行的,这样开启并行执行机会减少执行时间,越多并行执行时间就越快.充分提高集群的利用率.
前提:在资源充裕的时候才能发挥并行的优势,否则并行跑不起来也是白费.
参数设置:
set hive.exec.parallel = true;

第九种方式:严格模式
严格模式相对非严格模式来说,就是限制了查询语句的语法结构等,避免执行一些不好的查询语句,浪费资源
系统默认是非严格模式,开启方式:
set hive.mapred.mode = strict; #开启严格模式
set hive.mapred.mode = nostrict; #开启非严格模式
严格的示例:
1. 对于分区表,在where语句中必须含有分区字段作为过滤条件来限制范围,否则不允许执行 .
2. 对于使用了order by语句的查询,要求必须使用limit语句 .
3. 限制笛卡尔积的查询 .

第十种方式:JVM重用
JVM重用有点类似连接池技术,减少虚拟机的频繁开启和关闭所消耗的资源.Hadoop的默认配置通常是使用派生JVM来执行map和Reduce任务的。这时JVM的启动过程可能 会造成相当大的开销,尤其是执行的job包含有成百上千task任务的情况。JVM重用可以使得 JVM实例在同一个job中重新使用N次。
设置重用:
set mapred.job.reuse.jvm.num.tasks=10;
这个数值通常是10-20之间,具体最佳值需要在具体业务场景中测试才可得知.
这种方式也有缺点:开启的JVM会占用插槽,直到任务执行完成才会释放,所以一定程度上影响了资源的利用.

第十一种方式:推测执行
推测执行就是对可能发生bug/负载不均衡/资源分配不均等造成任务的执行缓慢的这些任务,给他们开启一个备份任务,让他们同事执行该任务,最后以最先出结果的为准.避免因任务执行卡顿而消耗大量时间.
参数设置:
set mapred.map.tasks.speculative.execution=true
set mapred.reduce.tasks.speculative.execution=true
set hive.mapred.reduce.tasks.speculative.execution=true;
注意几点推测任务的缺陷:
1.如果用户对于运行时的偏差非常敏 感的话,那么可以将这些功能关闭掉。
2.如果用户因为输入数据量很大而需要执行长时间的 map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值