文档章节

HIVE的优化技巧整理

胡德军
 胡德军
发布于 2016/07/06 11:52
字数 3196
阅读 83
收藏 1
点赞 0
评论 0

hive SQL 的优化的优化措施主要有三个方面

1.针对MR中单个步骤的优化

2.针对MR全局的优化

3.针对整个查询(多MR Job)的优化

1.MR单个步骤优化。调整Mapred.max.split.size。

A.Map阶段的优化(Map phase) Map阶段的优化,主要是确定合适的Map数。 Mapred.min.split.size指的是数据的最小分割单元大小。 Mapred.max.split.size指的是数据的最大分割单元大小。 dfs.block.size指的是HDFS设置的数据块大小。 Mapred.max.split.size=256000000 依据MAP TASK的执行时间来决定是否增加MAP split的大小。如果MAP执行时间过长(分钟级),那么可以增加MAP 的数量来减少单个MAP的执行时间。如果单个MAP的执行时间较低(如10~20s),那么没有必要进行MAP数优化

B.Reduce 阶段的优化(Reduce phase)。调整Hive.exec.Reducers.bytes.per.Reducer。 Mapred.Reduce.tasks参数从而直接指定Reduce的个数.估算Reduce的数量公式为 num_Reduce_tasks = min[${Hive.exec.Reducers.max},(${input.size} / ${ Hive.exec.Reducers.bytes.per.Reducer})] 也可根据Hive.exec.Reducers.bytes.per.Reducer(默认1G)来控制Reduce的数量。

C.Map与Reduce之间的优化(Spill, copy, Sort phase) Map phase和Reduce phase之间主要有3道工序。首先要把Map输出的结果进行排序后做成中间文件, 其次这个中间文件就能分发到各个Reduce,最后Reduce端在执行Reduce phase之前把收集到的排序子文件合并成一个排序文件。 这个部分可以调的参数挺多,但是一般都是不要调整的,不必重点关注。 (MAP -排序->中间文件-合并->Reduce)

D.Spill 与 Sort。调整io.Sort.mb和io.Sort.factor。 在Spill阶段,由于内存不够,数据可能没办法在内存中一次性排序完成,那么就只能把局部排序的文件先保存到磁盘上,这个动作叫Spill, 然后Spill出来的多个文件可以在最后进行merge。如果发生Spill,可以通过设置io.Sort.mb来增大Mapper输出buffer的大小,避免Spill的发生。 另外合并时可以通过设置io.Sort.factor来使得一次性能够合并更多的数据。调试参数的时候,一个要看Spill的时间成本,一个要看merge的时间成本, 还需要注意不要撑爆内存(io.Sort.mb是算在Map的内存里面的)。Reduce端的merge也是一样可以用io.Sort.factor。 一般情况下这两个参数很少需要调整,除非很明确知道这个地方是瓶颈。

E.Copy。调整Mapred.Reduce.slowstart.completed.Maps copy阶段是把文件从Map端copy到Reduce端。默认情况下在5%的Map完成的情况下Reduce就开始启动copy,这个有时候是很浪费资源的, 因为Reduce一旦启动就被占用,一直等到Map全部完成,收集到所有数据才可以进行后面的动作, 所以我们可以等比较多的Map完成之后再启动Reduce流程,这个比例可以通Mapred.Reduce.slowstart.completed.Maps去调整, 他的默认值就是5%。如果觉得这么做会减慢Reduce端copy的进度,可以把copy过程的线程增大。 tasktracker.http.threads可以决定作为server端的Map用于提供数据传输服务的线程, Mapred.Reduce.parallel.copies可以决定作为client端的Reduce同时从Map端拉取数据的并行度(一次同时从多少个Map拉数据), 修改参数的时候这两个注意协调一下,server端能处理client端的请求即可。

2.针对MR全局的优化(JOB优化)

A.JOB执行模式。 Hadoop的Map Reduce Job可以有3种模式执行, 即本地模式,伪分布式,还有真正的分布式。 本地模式和伪分布式都是在最初学习Hadoop的时候往往被说成是做单机开发的时候用到。 但是实际上对于处理数据量非常小的Job,直接启动分布式Job会消耗大量资源,而真正执行计算的时间反而非常少。 这个时候就应该使用本地模式执行mr Job,这样执行的时候不会启动分布式Job,执行速度就会快很多。 比如一般来说启动分布式Job,无论多小的数据量,执行时间一般不会少于20s,而使用本地mr模式,10秒左右就能出结果。 设置执行模式的主要参数有三个,一个是Hive.exec.mode.local.auto,把他设为true就能够自动开启local mr模式。 但是这还不足以启动local mr,输入的文件数量和数据量大小必须要控制,这两个参数分别为Hive.exec.mode.local.auto.tasks.max和Hive.exec.mode.local.auto.inputbytes.max, 默认值分别为4和128MB,即默认情况下,Map处理的文件数不超过4个并且总大小小于128MB就启用local mr模式。

B.JVM重用。 正常情况下,MapReduce启动的JVM在完成一个task之后就退出了,但是如果任务花费时间很短, 又要多次启动JVM的情况下(比如对很大数据量进行计数操作), JVM的启动时间就会变成一个比较大的overhead。在这种情况下,可以使用jvm重用的参数: set Mapred.Job.reuse.jvm.num.tasks = 5;

C.Join算法。一般可忽略该优化方法 处理分布式join,一般有两种方法: replication join:把其中一个表复制到所有节点,这样另一个表在每个节点上面的分片就可以跟这个完整的表join了; repartition join:把两份数据按照join key进行hash重分布,让每个节点处理hash值相同的join key数据,也就是做局部的join。 这两种方式在M/R Job中分别对应了Map side join和Reduce side join。在一些MPP DB中,数据可以按照某列字段预先进行hash分布, 这样在跟这个表以这个字段为join key进行join的时候,该表肯定不需要做数据重分布了,这种功能是以HDFS作为底层文件系统的Hive所没有的。 在默认情况下,Hive的join策略是进行Reduce side join。当两个表中有一个是小表的时候,就可以考虑用Map join了,因为小表复制的代价会好过大表Shuffle的代价。 使用Map join的配置方法有两种,一种直接在sql中写hint,语法是/*+MapJOIN (tbl)*/,其中tbl就是你想要做replication的表。 另一种方法是设置Hive.auto.convert.join = true,这样Hive会自动判断当前的join操作是否合适做Map join,主要是找join的两个表中有没有小表。 至于多大的表算小表,则是由Hive.smalltable.filesize决定,默认25MB。 但是有的时候,没有一个表足够小到能够放进内存,但是还是想用Map join怎么办? 这个时候就要用到bucket Map join。其方法是两个join表在join key上都做hash bucket,并且把你打算复制的那个(相对)小表的bucket数设置为大表的倍数。 这样数据就会按照join key做hash bucket。小表依然复制到所有节点,Map join的时候,小表的每一组bucket加载成hashtable, 与对应的一个大表bucket做局部join,这样每次只需要加载部分hashtable就可以了。 然后在两个表的join key都具有唯一性的时候(也就是可做主键),还可以进一步做Sort merge bucket Map join。 做法还是两边要做hash bucket,而且每个bucket内部要进行排序。这样一来当两边bucket要做局部join的时候, 只需要用类似merge Sort算法中的merge操作一样把两个bucket顺序遍历一遍即可完成,这样甚至都不用把一个bucket完整的加载成hashtable,这对性能的提升会有很大帮助。

D.数据倾斜。 所谓数据倾斜,说的是由于数据分布不均匀,个别值集中占据大部分数据量,加上Hadoop的计算模式,导致计算资源不均匀引起性能下降。 假设网站访问日志中会记录用户的user_id,并且对于注册用户使用其用户表的user_id,对于非注册用户使用一个user_id=0代表。 那么鉴于大多数用户是非注册用户(只看不写),所以user_id=0占据了绝大多数。而如果进行计算的时候如果以user_id作为group by的维度或者是join key, 那么个别Reduce会收到比其他Reduce多得多的数据——因为它要接收所有user_id=0的记录进行处理,使得其处理效果会非常差,其他Reduce都跑完很久了它还在运行。 倾斜分成group by造成的倾斜和join造成的倾斜,需要分开看。 group by造成的倾斜有两个参数可以解决,一个是Hive.Map.aggr,默认值已经为true,意思是会做Map端的combiner。所以如果你的group by查询只是做count(*)的话,其实是看不出倾斜效果的,但是如果你做的是count(distinct),那么还是会看出一点倾斜效果。另一个参数是Hive.groupby. skewindata。这个参数的意思是做Reduce操作的时候,拿到的key并不是所有相同值给同一个Reduce,而是随机分发,然后Reduce做聚合,做完之后再做一轮MR,拿前面聚合过的数据再算结果。所以这个参数其实跟Hive.Map.aggr做的是类似的事情,只是拿到Reduce端来做,而且要额外启动一轮Job,所以其实不怎么推荐用,效果不明显。 join造成的倾斜,就比如上面描述的网站访问日志和用户表两个表join:select a.* from logs a join users b on a。user_id = b.user_id; Hive给出的解决方案叫skew join,其原理把这种user_id = 0的特殊值先不在Reduce端计算掉,而是先写入hdfs,然后启动一轮Map join专门做这个特殊值的计算,期望能提高计算这部分值的处理速度。当然你要告诉Hive这个join是个skew join,即: set Hive.optimize.skewjoin = true;

3.针对整个查询(多MR Job)的优化

A.Job间并行。多用UNION ALL 首先,在Hive生成的多个Job中,在有些情况下Job之间是可以并行的,典型的就是子查询。当需要执行多个子查询union all或者join操作的时候,Job间并行就可以使用了。比如下面的代码就是一个可以并行的场景示意:select * from ( select count(*) from logs where log_date = 20130801 and item_id = 1 union all select count(*) from logs where log_date = 20130802 and item_id = 2 union all select count(*) from logs where log_date = 20130803 and item_id = 3 )t。设置Job间并行的参数是Hive.exec.parallel,将其设为true即可。默认的并行度为8,也就是最多允许sql中8个Job并行。如果想要更高的并行度,可以通过Hive.exec.parallel. thread.number参数进行设置,但要避免设置过大而占用过多资源。

B.减少JOB数。SQL优化 另外在实际开发过程中也发现,一些实现思路会导致生成多余的Job而显得不够高效。比如这个需求:查询某网站日志中访问过页面a和页面b的用户数量。低效的思路是面向明细的,先取出看过页面a的用户,再取出看过页面b的用户,然后取交集,代码如下: select count(*) from (select distinct user_id from logs where page_name = ‘a’) a join (select distinct user_id from logs where blog_owner = ‘b’) b on a.user_id = b.user_id; 这样一来,就要产生2个求子查询的Job,一个用于关联的Job,还有一个计数的Job,一共有4个Job。 但是我们直接用面向统计的方法去计算的话(也就是用group by替代join),则会更加符合M/R的模式,而且生成了一个完全不带子查询的sql,只需要用一个Job就能跑完: select count(*) from logs group by user_id having (count(case when page_name = ‘a’ then 1 end) > 0 and count(case when page_name = ‘b’ then 1 end) > 0) 第一种查询方法符合思考问题的直觉,是工程师和分析师在实际查数据中最先想到的写法,但是如果在目前Hive的query planner不是那么智能的情况下,想要更加快速的跑出结果,懂一点工具的内部机理也是必须的。

© 著作权归作者所有

共有 人打赏支持
胡德军
粉丝 2
博文 7
码字总数 9628
作品 0
闸北
程序员
分享一些MySQL的整理的一些资料

MySQL 资料整理目录 --------------------------- 一:MySQL 基本语句 (MySQL 基本语句.doc) 二:MySQL 存储过程(MySQL 存储过程.doc) 三:MySQL 监控(MySQL 监控.doc) 四:MySQL 技巧...

守望之心 ⋅ 2013/10/12 ⋅ 13

【2016-05-19】一次tomcat频繁挂掉的问题定位

问题: 最近手中一个web项目频繁挂掉,tomcat进程跑着跑着就没了,catalina.out里也没有任何相关报错。 项目功能: 该服务有3台物理机,接收client端的rpc调用,本机起hive进程做查询,将hiv...

rathan0 ⋅ 2016/05/19 ⋅ 1

Hadoop上时实类SQL查询系统对比

转载请注明作者与出处 作者:martin_li 网址:http://my.oschina.net/Senger/blog/180140 以前只用过Hive与impala两个类SQL查询系统,最近又将Hortonworks开源的Stinger与Apache的Drill做了些...

martin_li ⋅ 2013/11/29 ⋅ 10

大数据经典学习路线(及供参考)之 一

1.Linux基础和分布式集群技术 学完此阶段可掌握的核心能力: 熟练使用Linux,熟练安装Linux上的软件,了解熟悉负载均衡、高可靠等集群相关概念,搭建互联网高并发、高可靠的服务架构; 学完此...

柯西带你学编程 ⋅ 05/22 ⋅ 0

Hadoop、Pig、Hive、Storm、NoSQL 学习资源收集【Updating】

(一)hadoop 相关安装部署 1、hadoop在windows cygwin下的部署: http://lib.open-open.com/view/1333428291655 http://blog.csdn.net/ruby97/article/details/7423088 http://blog.csdn.n......

xrzs ⋅ 2013/06/25 ⋅ 3

Hive客户端工具

Hive客户端工具 {流水理鱼|wwek}2017-12-271 阅读 hivehadoopv 前沿 Hive有多种Hive客户端工具 Hive命令行工具只适合执行已经编写好的HSQL语句,或者执行较为简单 […] 点赞 hivehadoopv 作者...

{流水理鱼|wwek} ⋅ 2017/12/27 ⋅ 0

hive调优之 优化hive-site.xml配置

***hive多级目录作为输入-begin !hive.mapred.supports.subdirectories=false。是否将多级子目录作为输入,默认false是只能当前目录的文件。推荐使用如下配置: <property> <name>hive.mapr...

cjun1990 ⋅ 2016/04/26 ⋅ 0

Hive 在多维统计分析中的应用 & 技巧总结

本文原地址:https://my.oschina.net/leejun2005/blog/121945 多维统计一般分两种,我们看看 Hive 中如何解决: 1、同属性的多维组合统计 (1)问题: 有如下数据,字段内容分别为:url, ca...

SimplePoint ⋅ 2017/04/18 ⋅ 0

关于Hive优化的四种方法总结

一、整体架构优化 现在hive的整体框架如下,计算引擎不仅仅支持Map/Reduce,并且还支持Tez、Spark等。根据不同的计算引擎又可以使用不同的资源调度和存储系统。 整体架构优化点: 1、根据不同...

varchard ⋅ 2016/12/02 ⋅ 0

Apache Hive 走向内存计算,性能提升26倍

Apache Hive 2.1已于几个月前发布,它引入了内存计算,这使得Hive计算性能得到极大提升,这将会影响SQL On Hadoop目前的竞争局面。据测试,其性能提高约26倍。 Apache Hive 2.1新引入了6大性...

王练 ⋅ 2016/11/01 ⋅ 17

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部