Hive 调优
今天总结本人在使用Hive过程中的一些优化技巧,希望给大家带来帮助。Hive优化最体现程序员的技术能力,面试官在面试时最喜欢问的就是Hive的优化技巧。
技巧1.控制reducer数量
下面的内容是我们每次在hive命令行执行SQL时都会打印出来的内容:
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
很多人都会有个疑问,上面的内容是干什么用的。我们一一来解答,先看
set hive.exec.reducers.bytes.per.reducer=<number>,这个一条Hive命令,用于设置在执行SQL的过程中每个reducer处理的最大字节数量。可以在配置文件中设置,也可以由我们在命令行中直接设置。如果处理的数据量大于number,就会多生成一个reudcer。例如,number = 1024K,处理的数据是1M,就会生成10个reducer。我们来验证下上面的说法是否正确:
- 执行set hive.exec.reducers.bytes.per.reducer=200000;命令,设置每个reducer处理的最大字节是200000。
- 执行sql:
select user_id,count(1) as cnt
from orders group by user_id limit 20;
执行上面的sql时会在控制台打印出信息:
Number of reduce tasks not specified. Estimated from input data size: 159
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
Starting Job = job_1538917788450_0020, Tracking URL = http://hadoop-master:8088/proxy/application_1538917788450_0020/
Kill Command = /usr/local/src/hadoop-2.6.1/bin/hadoop job -kill job_1538917788450_0020
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 159
控制台打印的信息中第一句话:Number of reduce tasks not specified. Estimated from input data size: 159。翻译成中文:没有指定reducer任务数量,根据输入的数据量估计会有159个reducer任务。然后在看最后一句话:number of mappers: 1; number of reducers: 159。确定该SQL最终生成159个reducer。因此如果我们知道数据的大小,只要通过set hive.exec.reducers.bytes.per.reducer命令设置每个reducer处理数据的大小就可以控制reducer的数量。
接着看set hive.exec.reducers.max=<number> 这也是一条Hive命令,用于设置Hive的最大reducer数量,如果我们设置number为50,表示reducer的最大数量是50。
我们来验证下这个说法是否正确:
- 执行命令set hive.exec.reducers.max=8;设置reducer的数量为8。
- 继续执行sql:
select user_id,count(1) as cnt
from orders group by user_id limit 20;
会在控制台打印出如下信息:
Number of reduce tasks not specified. Estimated from input data size: 8
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
Starting Job = job_1538917788450_0020, Tracking URL = http://hadoop-master:8088/proxy/application_1538917788450_0020/
Kill Command = /usr/local/src/hadoop-2.6.1/bin/hadoop job -kill job_1538917788450_0020
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 8
控制台打印的信息中第一句话:Number of reduce tasks not specified. Estimated from input data size: 8。reducer的数据量为8,正好验证了我们的说法。set set hive.exec.reducers.max=8;命令是设置reducer的数量的上界。
最后来看set mapreduce.job.reduces=<number>命令。这条Hive命令是设置reducer的数据,在执行sql会生成多少个reducer处理数据。使用和上面同样的方法来验证set mapreduce.job.reduces=这条命令。
- 执行命令set mapreduce.job.reduces=5;设置reducer的数量为8。
- 继续执行sql:
select user_id,count(1) as cnt
from orders group by user_id limit 20;
会在控制台打印出如下信息:
Number of reduce tasks not specified. Defaulting to jobconf value of: 5
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
Starting Job = job_1538917788450_0026, Tracking URL = http://hadoop-master:8088/proxy/application_1538917788450_0026/
Kill Command = /usr/local/src/hadoop-2.6.1/bin/hadoop job -kill job_1538917788450_0026
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 5
根据Number of reduce tasks not specified. Defaulting to jobconf value of: 5和number of mappers: 1; number of reducers: 5这两句话,可以知道生成5个reducer。
如果我们将数量由5改成15。还是执行select user_id,count(1) as cnt
from orders group by user_id limit 20;SQL,在控制台打印的信息是:
Launching Job 1 out of 1
Number of reduce tasks not specified. Defaulting to jobconf value of: 15
In order to change the average load for a reducer (in bytes):
set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
set mapreduce.job.reduces=<number>
Starting Job = job_1538917788450_0027, Tracking URL = http://hadoop-master:8088/proxy/application_1538917788450_0027/
Kill Command = /usr/local/src/hadoop-2.6.1/bin/hadoop job -kill job_1538917788450_0027
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 15
可见reducer的数量已经由5变为15个。
小结,控制hive中reducer的数量由三种方式,分别是:
set hive.exec.reducers.bytes.per.reducer=<number>
set hive.exec.reducers.max=<number>
set mapreduce.job.reduces=<number>
其中set mapreduce.job.reduces=<number>的方式优先级最高,set hive.exec.reducers.max=<number>优先级次之,set hive.exec.reducers.bytes.per.reducer=<number> 优先级最低。从hive0.14开始,一个reducer处理文件的大小的默认值是256M。
reducer的数量并不是越多越好,我们知道有多少个reducer就会生成多少个文件,小文件过多在hdfs中就会占用大量的空间,造成资源的浪费。如果reducer数量过小,导致某个reducer处理大量的数据(数据倾斜就会出现这样的现象),没有利用hadoop的分而治之功能,甚至会产生OOM内存溢出的错误。使用多少个reducer处理数据和业务场景相关,不同的业务场景处理的办法不同。
技巧2.使用Map join
sql中涉及到多张表的join,当有一张表的大小小于1G时,使用Map Join可以明显的提高SQL的效率。如果最小的表大于1G,使用Map Join会出现OOM的错误。
用法:
select /*+ MAPJOIN(table_a)*/,a.*,b.* from table_a a join table_b b on a.id = b.id
技巧3.使用distinct + union all代替union
如果遇到要使用union去重的场景,使用distinct + union all比使用union的效果好。
distinct + union all的用法:
select count(distinct *)
from (
select order_id,user_id,order_type from orders where order_type='0' union all
select order_id,user_id,order_type from orders where order_type='1' union all
select order_id,user_id,order_type from orders where order_type='1'
)a;
union的用法:
select count(*)
from(
select order_id,user_id,order_type from orders where order_type='0' union
select order_id,user_id,order_type from orders where order_type='0' union
select order_id,user_id,order_type from orders where order_type='1')t;
技巧4.解决数据倾斜的通用办法
数据倾斜的现象:任务进度长时间维持在99%,只有少量reducer任务完成,未完成任务数据读写量非常大,超过10G。在聚合操作是经常发生。
通用解决方法:set hive.groupby.skewindata=true;
将一个map reduce拆分成两个map reduce。
说说我遇到过的一个场景,需用统计某个一天每个用户的访问量,SQL如下:
select t.user_id,count(*) from user_log t group by t.user_id
执行这条语句之后,发现任务维持在99%达到一个小时。后面自己分析user_log表,发现user_id有很多数据为null。user_id为null的数据会有一个reducer来处理,导致出现数据倾斜的现象。解决方法有两种:
1、通过where条件过滤掉user_id为null的记录。
2、将为null的user_id设置一个随机数值。保证所有数据平均的分配到所有的reducer中处理。
转载自:https://www.cnblogs.com/airnew/p/9808514.html
Hive 调优的更多相关文章
- 【Hive六】Hive调优小结
Hive调优 Hive调优 Fetch抓取 本地模式 表的优化 小表.大表Join 大表Join大表 MapJoin Group By Count(Distinct) 去重统计 行列过滤 动态分区调整 ...
- 【Hive】Hive笔记:Hive调优总结——数据倾斜,join表连接优化
数据倾斜即为数据在节点上分布不均,是常见的优化过程中常见的需要解决的问题.常见的Hive调优的方法:列剪裁.Map Join操作. Group By操作.合并小文件. 一.表现 1.任务进度长度为99 ...
- Hive调优笔记
Hive调优 先记录了这么多,日后如果有遇到,再补充. fetch模式 <property> <name>hive.fetch.task.conversion</name ...
- (转) hive调优(2)
hive 调优(二)参数调优汇总 在hive调优(一) 中说了一些常见的调优,但是觉得参数涉及不多,补充如下 1.设置合理solt数 mapred.tasktracker.map.tasks.maxi ...
- (转)hive调优(1) coding调优
hive 调优(一)coding调优 本人认为hive是很好的工具,目前支持mr,tez,spark执行引擎,有些大公司原来封装的sparksql,开发py脚本,但是目前hive支持spark引擎(不 ...
- hive 调优(二)参数调优汇总
在hive调优(一) 中说了一些常见的调优,但是觉得参数涉及不多,补充如下 1.设置合理solt数 mapred.tasktracker.map.tasks.maximum 每个tasktracker ...
- 【Hadoop离线基础总结】Hive调优手段
Hive调优手段 最常用的调优手段 Fetch抓取 MapJoin 分区裁剪 列裁剪 控制map个数以及reduce个数 JVM重用 数据压缩 Fetch的抓取 出现原因 Hive中对某些情况的查询不 ...
- Hive调优相关
前言 Hive是由Facebook 开源用于解决海量结构化日志的数据统计,是基于Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 SQL查询功能. 在资源有限的情况下,提 ...
- hive 调优手段
调优手段 ()利用列裁剪 当待查询的表字段较多时,选取需要使用的字段进行查询,避免直接select *出大表的所有字段,以免当使用Beeline查询时控制台输出缓冲区被大数据量撑爆. ()JOIN避免 ...
- Hive调优
Hive存储格式选择 和Hive 相关优化: 压缩参考 Hive支持的存储数的格式主要有:TEXTFILE .SEQUENCEFILE.ORC.PARQUET. 文件存储格式 列式存储和行式存储 行存 ...
随机推荐
- 函数的学习2——返回值&传递列表——参考Python编程从入门到实践
返回值 函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值.函数的返回值被称为返回值. 1. 简单的返回值 def get_formatted_name(first_name, l ...
- 【Linux】一步一步学Linux——初识Linux命令解析器(10)
目录 00. 目录 01. Shell简介 02. Shell分类 03. 交互式shell和非交互式shell 04. 登录shell和非登录shell 05. Shell类型 06. 参考 00. ...
- Yii2实现手机二维码扫一扫登入
一 建数据表 scancode randnumber字段存储的是一个随机码,可以用uuid token是一个提取用户信息的字段,说白了就是user表的唯一键,如果不担心用户id外泄,用user_id ...
- 【LEETCODE】45、766. Toeplitz Matrix
package y2019.Algorithm.array; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.array * ...
- 2019年北航OO第三次博客总结
一.JML语言理论基础及其工具链 1. JML语言理论基础 JML是用于对Java程序进行规格化设计的一种表示语言,是一种行为接口规格语言(Behavior Interface Specificati ...
- Java并发多线程面试题 Top 50
不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎.大多数待遇丰厚的Java开发职位都要求开发者精通多线程 ...
- weui中的picker使用js进行动态绑定数据
解决方案; picker和Select组件是通过input标签绑定,可以先通过input的父级元素移除input标签,重新插入input标签,最后重新初始化picker或Select组件. <d ...
- 浅谈React编程思想
React是Facebook推出的面向视图层开发的一个框架,用于解决大型应用,包括如何很好地管理DOM结构,是构建大型,快速Web app的首选方式. React使用JavaScript来构建用户界面 ...
- 使用企业证书给iOS应用重签
来源:https://github.com/sailtsao/iReSign 这里有个开源的签名工具,已经修改为支持dylib frameworks等的签名了,使用这个签名不会出现任何问题 iReSi ...
- iOS ANE植入流程
来源:http://www.adsmogo.com/help/iosANE 一.iOS ANE植入流程 Step 1:创建Flex工程 1.1 启动Flash Builder 4.6.0, 选择“Fi ...