Fetch抓取
Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台
在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
2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
</description>
</property>
## 实际操作
hive (sqlfacetest)> set hive.fetch.task.conversion= more;
本地模式
Hive 在集群上查询时,默认是在集群上 N 台机器上运行, 需要多个机器进行协调运行,这 个方式很好地解决了大数据量的查询问题。但是当 Hive 查询处理的数据量比较小时,其实没有必要启动分布式模式去执行,因为以分布式方式执行就涉及到跨网络传输、多节点协调 等,并且消耗资源。这个时间可以只使用本地模式来执行 mapreduce job,只在一台机器上执行,速度会很快
涉及到三个参数的设置
hive.exec.mode.local.auto 默认是false
hive.exec.mode.local.auto.input.files.max 默认是4个
hive.exec.mode.local.auto.inputbytes.max 默认是128M
set hive.exec.mode.local.auto=true 是打开 hive 自动判断是否启动本地模式的开关,但是只 是打开这个参数并不能保证启动本地模式,要当 map 任务数不超过hive.exec.mode.local.auto.input.files.max 的个数并且 map 输入文件大小不超过
hive.exec.mode.local.auto.inputbytes.max 所指定的大小时,才能启动本地模式
hive (sqlfacetest)> set hive.exec.mode.local.auto = true;
严格模式
参数hive.mapred.mode控制着hive的执行模式,如果设置为strict模式,则hive作业禁止3种类型查询
- 分区表中没有分区过滤字段
就是用户不允许扫描所有的分区。进行这个限制的原因是,通常分区表都拥有非常大的数据集,而且数据增加迅速。
如果没有进行分区限制的查询可能会消耗令人不可接受的巨大资源来处理这个表:- 笛卡尔积(必须使用on,where是不可以的)
对关系型数据库非常了解的用户可能期望在执行join查询的时候不使用on语句而是使用where语句,这样关系数据库的执行优化器就可以高效的将where语句转换成那个on语句。
不幸的是,**hive不会执行这种优化,**因此,如果表足够大,那么这个查询就会出现不可控的情况:- order by没有指定limit限制
因为orderby为了执行排序过程会讲所有的结果分发到同一个reducer中
进行处理,强烈要求用户增加这个limit语句可以防止reducer额外执行很长一段时间:
hive (sqlfacetest)> set hive.mapred.mode = strict;
JVM重用设置(JVM启动是很大的开销)
jvm重用是hadoop调优参数的内容,其对hive的性能影响是非常大的,特别是对于针对很多小文件的场景或task特别多的场景,这类场景任务执行的时间都很短。
hadoop默认使用派生的jvm执行mapreduce任务,对于jvm的启动时很大的开销,特别针对于task任务比较多的场景。jvm重用可以使jvm实例在同一个job中运行n次
n的值在hadoop的mapred-site.xml文件进行配置:
<property>
<name> mapred.job.reuse.jvm.num.tasks </name>
<value>10</value>
</property>
也可以在hive.cli中通过set设置
hive (default)> set mapred.job.reuse.jvm.num.tasks=10;
JVM的一个缺点是,开启JVM重用将会一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡“的job中有几个reduce task 执行的时间要比其他reduce task消耗的时间多得多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。
推测执行
在分布式集群环境下,因为程序Bug(包括Hadoop本身的bug),负载不均衡或者资源分布不均等原因,会造成同一个作业的多个任务之间运行速度不一致,有些任务的运行速度可能明显慢于其他任务(比如一个作业的某个任务进度只有50%,而其他所有任务已经运行完毕),则这些任务会拖慢作业的整体执行进度。为了避免这种情况发生,Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
hadoop的推测执行功能由hadoop的mapred-site.xml文件中的2个参数决定:
<property>
<name> mapred.map.tasks.speculative.execution </name>
<value>true</value>
</property>
<property>
<name> mapred.reduce.tasks.speculative.execution</name>
<value>true</value>
</property>
hive本身也有控制推测执行的参数,可以在hive-site.xml文件中配置:
<property>
<name>hive.mapred.reduce.tasks.speculative.execution </name>
<value>true</value>
</property>
通过命令行修改
hive (default)> set mapred.map.tasks.speculative.execution;
mapred.map.tasks.speculative.execution=true
hive (default)> set mapred.reduce.tasks.speculative.execution;
mapred.reduce.tasks.speculative.execution=true
hive (default)> set hive.mapred.reduce.tasks.speculative.execution;
hive.mapred.reduce.tasks.speculative.execution=true
如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大的,因为需要额外开启任务做备份,浪费了很多资源
聚合优化
启用参数:hive.map.aggr=true
默认就是true,Map端部分聚合,相当于Combiner
单个MR运行多个group by(面试有可能会问到)
使用multi group by 之前必须配置参数:
<property>
<name>hive.multigroupby.singlemr</name>
<value>true</value>
</property>
select Provice,city,county,count(rainfall) from area where data=“2018-09-02” group by provice,city,count;
类似于这种
1万+

被折叠的 条评论
为什么被折叠?



