Hive作为大数据平台无足轻重的框架,以其稳定性和简略易用性也成为以后构建企业级数据仓库时应用最多的框架之一。
然而如果咱们只局限于会应用Hive,而不思考性能问题,就难搭建出一个完满的数仓,所以Hive性能调优是咱们大数据从业者必须把握的技能。本文将给大家解说Hive性能调优的一些办法及技巧。
本文首发于公众号:五分钟学大数据
Hive性能问题排查的形式
当咱们发现一条SQL语句执行工夫过长或者不合理时,咱们就要思考对SQL进行优化,优化首先得进行问题排查,那么咱们能够通过哪些形式进行排查呢。
常常应用关系型数据库的同学可能晓得关系型数据库的优化的窍门-看执行打算。 如Oracle数据库,它有多种类型的执行打算,通过多种执行打算的配合应用,能够看到依据统计信息推演的执行打算,即Oracle推断进去的未真正运行的执行打算;还能够看到理论执行工作的执行打算;可能察看到从数据读取到最终出现的次要过程和两头的量化数据。能够说,在Oracle开发畛域,把握适合的环节,选用不同的执行打算,SQL调优就不是一件难事。
Hive中也有执行打算,然而Hive的执行打算都是预测的,这点不像Oracle和SQL Server有实在的打算,能够看到每个阶段的解决数据、耗费的资源和解决的工夫等量化数据。Hive提供的执行打算没有这些数据,这意味着尽管Hive的使用者晓得整个SQL的执行逻辑,然而各阶段耗用的资源情况和整个SQL的执行瓶颈在哪里是不分明的。
想要晓得HiveSQL所有阶段的运行信息,能够查看YARN提供的日志。查看日志的链接,能够在每个作业执行后,在控制台打印的信息中找到。如下图所示:
Hive提供的执行打算目前能够查看的信息有以下几种:
- 查看执行打算的根本信息,即explain;
- 查看执行打算的扩大信息,即explain extended;
- 查看SQL数据输出依赖的信息,即explain dependency;
- 查看SQL操作相干权限的信息,即explain authorization;
- 查看SQL的向量化形容信息,即explain vectorization。
在查问语句的SQL后面加上关键字explain是查看执行打算的根本办法。 用explain关上的执行打算蕴含以下两局部:
- 作业的依赖关系图,即STAGE DEPENDENCIES;
- 每个作业的详细信息,即STAGE PLANS。
Hive中的explain执行打算详解可看我之前写的这篇文章:
Hive底层原理:explain执行打算详解
注:应用explain查看执行打算是Hive性能调优中十分重要的一种形式,请务必把握!
总结:Hive对SQL语句性能问题排查的形式:
- 应用explain查看执行打算;
- 查看YARN提供的日志。
Hive性能调优的形式
为什么都说性能优化这项工作是比拟难的,因为一项技术的优化,必然是一项综合性的工作,它是多门技术的联合。咱们如果只局限于一种技术,那么必定做不好优化的。
上面将从多个齐全不同的角度来介绍Hive优化的多样性,咱们先来一起感触下。
1. SQL语句优化
SQL语句优化波及到的内容太多,因篇幅无限,不能一一介绍到,所以就拿几个典型举例,让大家学到这种思维,当前遇到相似调优问题能够往这几个方面多思考下。
1. union all
insert into table stu partition(tp) select s_age,max(s_birth) stat,'max' tp from stu_origroup by s_ageunion allinsert into table stu partition(tp) select s_age,min(s_birth) stat,'min' tp from stu_origroup by s_age;
咱们简略剖析下面的SQl语句,就是将每个年龄的最大和最小的生日获取进去放到同一张表中,union all 前后的两个语句都是对同一张表依照s_age进行分组,而后别离取最大值和最小值。对同一张表雷同的字段进行两次分组,这造成了极大节约,咱们能不能革新下呢,当然是能够的,为大家介绍一个语法:from ... insert into ...
,这个语法将from前置,作用就是应用一张表,能够进行屡次插入操作:
--开启动静分区 set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; from stu_ori insert into table stu partition(tp) select s_age,max(s_birth) stat,'max' tp group by s_ageinsert into table stu partition(tp) select s_age,min(s_birth) stat,'min' tp group by s_age;
下面的SQL就能够对stu_ori表的s_age字段分组一次而进行两次不同的插入操作。
这个例子通知咱们肯定要多理解SQL语句,如果咱们不晓得这种语法,肯定不会想到这种形式的。
2. distinct
先看一个SQL,去重计数:
select count(1) from( select s_age from stu group by s_age ) b;
这是简略统计年龄的枚举值个数,为什么不必distinct?
select count(distinct s_age) from stu;
有人说因为在数据量特地大的状况下应用第一种形式可能无效防止Reduce端的数据歪斜,然而事实如此吗?
咱们先不论数据量特地大这个问题,就以后的业务和环境下应用distinct肯定会比下面那种子查问的形式效率高。起因有以下几点:
- 下面进行去重的字段是年龄字段,要晓得年龄的枚举值是十分无限的,就算计算1岁到100岁之间的年龄,s_age的最大枚举值才是100,如果转化成MapReduce来解释的话,在Map阶段,每个Map会对s_age去重。因为s_age枚举值无限,因此每个Map失去的s_age也无限,最终失去reduce的数据量也就是map数量*s_age枚举值的个数。
- distinct的命令会在内存中构建一个hashtable,查找去重的工夫复杂度是O(1);group by在不同版本间变动比拟大,有的版本会用构建hashtable的模式去重,有的版本会通过排序的形式, 排序最优工夫复杂度无奈到O(1)。另外,第一种形式(group by)去重会转化为两个工作,会耗费更多的磁盘网络I/O资源。
- 最新的Hive 3.0中新增了 count(distinct ) 优化,通过配置
hive.optimize.countdistinct
,即便真的呈现数据歪斜也能够主动优化,主动扭转SQL执行的逻辑。 - 第二种形式(distinct)比第一种形式(group by)代码简洁,表白的意思简单明了,如果没有非凡的问题,代码简洁就是优!
这个例子通知咱们,有时候咱们不要适度优化,调优考究适时调优,过早进行调优有可能做的是无用功甚至产生负效应,在调优上投入的工作老本和回报不成正比。调优须要遵循肯定的准则。
2. 数据格式优化
Hive提供了多种数据存储组织格局,不同格局对程序的运行效率也会有极大的影响。
Hive提供的格局有TEXT、SequenceFile、RCFile、ORC和Parquet等。
SequenceFile是一个二进制key/value对构造的立体文件,在晚期的Hadoop平台上被宽泛用于MapReduce输入/输入格局,以及作为数据存储格局。
Parquet是一种列式数据存储格局,能够兼容多种计算引擎,如MapRedcue和Spark等,对多层嵌套的数据结构提供了良好的性能反对,是目前Hive生产环境中数据存储的支流抉择之一。
ORC优化是对RCFile的一种优化,它提供了一种高效的形式来存储Hive数据,同时也可能进步Hive的读取、写入和解决数据的性能,可能兼容多种计算引擎。事实上,在理论的生产环境中,ORC曾经成为了Hive在数据存储上的支流抉择之一。
咱们应用同样数据及SQL语句,只是数据存储格局不同,失去如下执行时长:
数据格式 | CPU工夫 | 用户期待耗时 |
---|---|---|
TextFile | 33分 | 171秒 |
SequenceFile | 38分 | 162秒 |
Parquet | 2分22秒 | 50秒 |
ORC | 1分52秒 | 56秒 |
注:CPU工夫:示意运行程序所占用服务器CPU资源的工夫。
*用户期待耗时*:记录的是用户从提交作业到返回后果期间用户期待的所有工夫。
查问TextFile类型的数据表耗时33分钟, 查问ORC类型的表耗时1分52秒,工夫得以极大缩短,可见不同的数据存储格局也能给HiveSQL性能带来极大的影响。
3. 小文件过多优化
小文件如果过多,对 hive 来说,在进行查问时,每个小文件都会当成一个块,启动一个Map工作来实现,而一个Map工作启动和初始化的工夫远远大于逻辑解决的工夫,就会造成很大的资源节约。而且,同时可执行的Map数量是受限的。
所以咱们有必要对小文件过多进行优化,对于小文件过多的解决的方法,我之前专门写了一篇文章解说,具体可查看:
解决hive小文件过多问题
4. 并行执行优化
Hive会将一个查问转化成一个或者多个阶段。这样的阶段能够是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能须要的其余阶段。默认状况下,Hive一次只会执行一个阶段。不过,某个特定的job可能蕴含泛滥的阶段,而这些阶段可能并非齐全相互依赖的,也就是说有些阶段是能够并行执行的,这样可能使得整个job的执行工夫缩短。如果有更多的阶段能够并行执行,那么job可能就越快实现。
通过设置参数hive.exec.parallel值为true,就能够开启并发执行。在共享集群中,须要留神下,如果job中并行阶段增多,那么集群利用率就会减少。
set hive.exec.parallel=true; //关上工作并行执行set hive.exec.parallel.thread.number=16; //同一个sql容许最大并行度,默认为8。
当然得是在系统资源比拟闲暇的时候才有劣势,否则没资源,并行也起不来。
5. JVM优化
JVM重用是Hadoop调优参数的内容,其对Hive的性能具备十分大的影响,特地是对于很难防止小文件的场景或task特地多的场景,这类场景大多数执行工夫都很短。
Hadoop的默认配置通常是应用派生JVM来执行map和Reduce工作的。这时JVM的启动过程可能会造成相当大的开销,尤其是执行的job蕴含有成千盈百task工作的状况。JVM重用能够使得JVM实例在同一个job中从新应用N次。N的值能够在Hadoop的mapred-site.xml
文件中进行配置。通常在10-20之间,具体多少须要依据具体业务场景测试得出。
<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; //这个设置来设置咱们的jvm重用
这个性能的毛病是,开启JVM重用将始终占用应用到的task插槽,以便进行重用,直到工作实现后能力开释。如果某个“不均衡的”job中有某几个reduce task执行的工夫要比其余Reduce task耗费的工夫多的多的话,那么保留的插槽就会始终闲暇着却无奈被其余的job应用,直到所有的task都完结了才会开释。
6. 揣测执行优化
在分布式集群环境下,因为程序Bug(包含Hadoop自身的bug),负载不平衡或者资源散布不均等起因,会造成同一个作业的多个工作之间运行速度不统一,有些工作的运行速度可能显著慢于其余工作(比方一个作业的某个工作进度只有50%,而其余所有工作曾经运行结束),则这些工作会拖慢作业的整体执行进度。为了防止这种状况产生,Hadoop采纳了揣测执行(Speculative Execution)机制,它依据肯定的法令揣测出“拖后腿”的工作,并为这样的工作启动一个备份工作,让该工作与原始工作同时解决同一份数据,并最终选用最先胜利运行实现工作的计算结果作为最终后果。
设置开启揣测执行参数:Hadoop的mapred-site.xml
文件中进行配置:
<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的揣测执行:
set hive.mapred.reduce.tasks.speculative.execution=true
对于调优这些揣测执行变量,还很难给一个具体的倡议。如果用户对于运行时的偏差十分敏感的话,那么能够将这些性能敞开掉。如果用户因为输出数据量很大而须要执行长时间的map或者Reduce task的话,那么启动揣测执行造成的节约是十分微小大。
公众号【五分钟学大数据】,大数据畛域原创技术号
最初
代码优化准则:
- 理透需要准则,这是优化的基本;
- 把握数据全链路准则,这是优化的脉络;
- 保持代码的简洁准则,这让优化更加简略;
- 没有瓶颈时议论优化,这是自寻烦恼。