一起学Hive——总结常用的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中处理。
一起学Hive——总结常用的Hive优化技巧的更多相关文章
- PHP常用的一些优化技巧
PHP常用的一些优化技巧 点击联系老杨 ecshop模板 php 优化技巧 老杨ecshop ecshop二次开发 2013-03-29 0 做为最流行的WEB语言, PHP他的突出优势就是其速度与效 ...
- hive sql常用整理-hive引擎设置
遇到个情况,跑hive级联insert数据报错,可以尝试换个hive计算引擎 hive遇到FAILED: Execution Error, return code 2 from org.apache. ...
- 常用SQL语句优化技巧
除了建立索引之外,保持良好的SQL语句编写习惯将会降低SQL性能问题发生. ①通过变量的方式来设置参数 好:stringsql = "select * from people p where ...
- 常用的7个SQl优化技巧
作为程序员经常和数据库打交道的时候还是非常频繁的,掌握住一些Sql的优化技巧还是非常有必要的.下面列出一些常用的SQl优化技巧,感兴趣的朋友可以了解一下. 1.注意通配符中Like的使用 以下写法会造 ...
- 写好Hive 程序的若干优化技巧和实际案例
使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑.但是一个”好”的Hive程序需要对Hive运行机制有深入的了解,像理解mapreduce作业一样理解Hive QL才能写出正确.高效 ...
- Hadoop Hive概念学习系列之hive里的优化和高级功能(十四)
在一些特定的业务场景下,使用hive默认的配置对数据进行分析,虽然默认的配置能够实现业务需求,但是分析效率可能会很低. Hive有针对性地对不同的查询进行了优化.在Hive里可以通过修改配置的方式进行 ...
- 2 hive的使用 + hive的常用语法
本博文的主要内容有: .hive的常用语法 .内部表 .外部表 .内部表,被drop掉,会发生什么? .外部表,被drop掉,会发生什么? .内部表和外部表的,保存的路径在哪? .用于创建一些临时表存 ...
- Hive中常用的参数配置
-- 查看当前环境参数配置set -v;-- 重置配置为默认值reset; -- 调整map数-- input的文件大小,集群设置的文件块大小,hive中通过set dfs.block.size;命令 ...
- Hive Tunning(二)优化存储
接着上一章我们讲的hive的连接策略,现在我们讲一下hive的数据存储. 下面是hive支持的数据存储格式,有我们常见的文本,JSON,XML,这里我们主要讲一下ORCFile. Built-in F ...
随机推荐
- 前端js区域上下拖拽
先说说需求吧,网页内又上下两个区域,需要做到的功能是,第一个区域A底部的边可以进行拖拽使得区域变大或变小,同时第二个区域B跟着拖动的变化进行自适应. 思路: 1.使用一个假的div定义为那条可进行拖拽 ...
- ORM之自关联、add、set方法、聚合函数、F、Q查询和事务
一.外键自关联(一对多) 1.建表 # 评论表 class Comment(models.Model): id = models.AutoField(primary_key=True) content ...
- 【XSY3042】石像 拓扑排序 状压DP 洲阁筛
题目大意 有 \(n\) 个整数 \(a_1,a_2,\ldots,a_n\),每个数的范围是 \([1,m]\).还有 \(k\) 个限制,每个限制 \(x_i,y_i\) 表示 \(a_{x_i} ...
- vue实战记录(三)- vue实现购物车功能之渲染商品列表
vue实战,一步步实现vue购物车功能的过程记录,课程与素材来自慕课网,自己搭建了express本地服务器来请求数据 作者:狐狸家的鱼 本文链接:vue实战-实现购物车功能(三) GitHub:sue ...
- ajax实现长连接
项目需求:需要实时的读取日志文件里的数据,并且使用Echart实时更新折线图. 使用ajax实现客户端与服务器端的数据传输. 目的:我想通过ajax与服务器建立一个长连接,服务器会不断的传输数据给前台 ...
- Dynamics CRM 日常使用JS整理(一)
整理下平时CRM开发中用到的一些基本的js操作 取值: var oResult = Xrm.Page.getAttribute(sFieldName).getValue(); var oResult ...
- 第三节: Quartz.Net五大构件之Scheduler(创建、封装、基本方法等)和Job(创建、关联等)
一. 五大构件 引言: Quartz.Net的五大构件 1. 调度器:Scheduler 2. 作业任务:Job 3. 触发器: Trigger 4. 线程池: SimpleThreadPoo ...
- Educational Codeforces Round 55 (Rated for Div. 2)
D. Maximum Diameter Graph 题意 给出每个点的最大度,构造直径尽可能长的树 思路 让度数大于$1$的点构成链,考虑是否能在链的两端加度为$1$的点 代码 #include &l ...
- hibernate之Configuration对象
任务:读取主配置信息 1. Configuration config = new Configuration(); 使用hibernate,但并没有读取 2. config.config ...
- idea远程tomcat运行项目
记录一下idea远程tomcat运行项目的配置过程 背景:每次系统修改代码后则需手动打包手动部署到测试服务器上,为了简化这个过程我这里选择尝试一次idea的远程运行功能,结论来讲这玩意配置麻烦,并不算 ...