大数据第五课-Hive调优
一、Fetch抓取
例如:select * from score;
在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台
在hive-default.xml.template文件中 ==hive.fetch.task.conversion默认是more==,老版本hive默认是minimal,该属性修改为more以后,
在全局查找、字段查找、limit查找等都不走mapreduce。
案例实操
把 hive.fetch.task.conversion设置成==none==
set hive.fetch.task.conversion=none; select * from score; select s_id from score; select s_id from score limit 3;
set hive.fetch.task.conversion=more; select * from score; select s_id from score; select s_id from score limit 3;
二、本地模式
Hive可以通过本地模式在单台机器上处理任务。对于小数据集,执行时间可以明显被缩短。
--开启本地模式,并执行查询语句 set hive.exec.mode.local.auto=true; //开启本地mr --设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式, --默认为134217728,即128M set hive.exec.mode.local.auto.inputbytes.max=50000000; --设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式, --默认为4 set hive.exec.mode.local.auto.input.files.max=5; --执行查询的sql语句 select * from student cluster by s_id;
--关闭本地运行模式 set hive.exec.mode.local.auto=false; select * from student cluster by s_id;
三、表的优化
有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。
--开启MapJoin参数设置 set hive.auto.convert.join = true;
并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。
--是否在Map端进行聚合,默认为True set hive.map.aggr = true; --在Map端进行聚合操作的条目数目 set hive.groupby.mapaggr.checkinterval = 100000; --有数据倾斜的时候进行负载均衡(默认是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中),最后完成最终的聚合操作。
四、分区裁剪,列裁剪
-
-
列剪裁
-
只获取需要的列的数据,减少数据输入。
-
-
分区裁剪
-
分区在hive实质上是目录,分区裁剪可以方便直接地过滤掉大部分数据。
-
尽量使用分区过滤
五、并行执行
把一个sql语句中没有相互依赖的阶段并行去运行。提高集群资源利用率
--开启并行执行 set hive.exec.parallel=true; --同一个sql允许最大并行度,默认为8。 set hive.exec.parallel.thread.number=16;
六、严格模式
通过设置属性hive.mapred.mode值为默认是非严格模式nonstrict 。开启严格模式需要修改hive.mapred.mode值为strict
--设置非严格模式(默认) set hive.mapred.mode=nonstrict; --设置严格模式 set hive.mapred.mode=strict;
(1)对于分区表,除非where语句中含有分区字段过滤条件来限制范围,否则不允许执行
--设置严格模式下 执行sql语句报错; 非严格模式下是可以的 select * from order_partition; 异常信息:Error: Error while compiling statement: FAILED: SemanticException [Error 10041]: No partition predicate found for Alias "order_partition" Table "order_partition"
(2)对于使用了order by语句的查询,要求必须使用limit语句
--设置严格模式下 执行sql语句报错; 非严格模式下是可以的 select * from order_partition where month='2019-03' order by order_price; 异常信息:Error: Error while compiling statement: FAILED: SemanticException 1:61 In strict mode, if ORDER BY is specified, LIMIT must also be specified. Error encountered near token 'order_price'
(3)限制笛卡尔积的查询,严格模式下,避免出现笛卡尔积的查询
七、JVM重用
<property> <name>mapreduce.job.jvm.numtasks</name> <value>10</value> <description>How many tasks to run per jvm. If set to -1, there is no limit. </description> </property>
我们也可以在hive当中通过
set mapred.job.reuse.jvm.num.tasks=10;
八、推测执行
<property> <name>mapreduce.map.speculative</name> <value>true</value> <description>If true, then multiple instances of some map tasks may be executed in parallel.</description> </property> <property> <name>mapreduce.reduce.speculative</name> <value>true</value> <description>If true, then multiple instances of some reduce tasks may be executed in parallel.</description> </property>
不过hive本身也提供了配置项来控制reduce-side的推测执行:
<property> <name>hive.mapred.reduce.tasks.speculative.execution</name> <value>true</value> <description>Whether speculative execution for reducers should be turned on. </description> </property>
关于调优这些推测执行变量,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大大。
九、数据压缩
Hive表中间数据压缩
#设置为true为激活中间数据压缩功能,默认是false,没有开启 set hive.exec.compress.intermediate=true; #设置中间数据的压缩算法 set mapred.map.output.compression.codec= org.apache.hadoop.io.compress.SnappyCodec;
Hive表最终输出结果压缩
set hive.exec.compress.output=true; set mapred.output.compression.codec = org.apache.hadoop.io.compress.SnappyCodec;
十、数据倾斜
more