hive 调优手段

调优手段

(1)利用列裁剪

当待查询的表字段较多时,选取需要使用的字段进行查询,避免直接select *出大表的所有字段,以免当使用Beeline查询时控制台输出缓冲区被大数据量撑爆。

(2)JOIN避免笛卡尔积

JOIN场景应严格避免出现笛卡尔积的情况。参与笛卡尔积JOIN的两个表,交叉关联后的数据条数是两个原表记录数之积,对于JOIN后还有聚合的场景而言,会导致reduce端处理的数据量暴增,极大地影响运行效率。

    以下左图为笛卡尔积,右图为正常Join。

(3)启动谓词下推

谓词下推(Predicate Pushdown)是一个逻辑优化:尽早的对底层数据进行过滤以减少后续需要处理的数据量。通过以下参数启动谓词下推。

(4)开启Map端聚合功能

在map中会做部分聚集操作,能够使map传送给reduce的数据量大大减少,从而在一定程度上减轻group by带来的数据倾斜。通过以下参数开启map端聚合功能。

(5)使用Hive合并输入格式

设置Hive合并输入格式,使Hive在执行map前进行文件合并,使得本轮map处理数据量均衡。通过以下参数设置Hive合并输入格式。

(6)合并小文件

启动较多的map或reduce能够提高并发度,加快任务运行速度;但同时在HDFS上生成的文件数目也会越来越多,给HDFS的NameNode造成内存上压力,进而影响HDFS读写效率。

对于集群的小文件(主要由Hive启动的MR生成)过多已造成NameNode压力时,建议在Hive启动的MR中启动小文件合并。

小文件合并能够使本轮map输出及整个任务输出的文件完成合并,保证下轮MapReduce任务map处理数据量均衡。

(7)解决group by造成的数据倾斜

通过开启group by倾斜优化开关,解决group by数据倾斜问题。

开启优化开关后group by会启动两个MR。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。

(8)解决Join造成的数据倾斜

两个表关联键的数据分布倾斜,会形成Skew Join。

解决方案是将这类倾斜的特殊值(记录数超过hive.skewjoin.key参数值)不落入reduce计算,而是先写入HDFS,然后再启动一轮MapJoin专门做这类特殊值的计算,期望能提高计算这部分值的处理速度。设置以下参数。

(9)合理调整map和reduce的内存及虚拟核数

map和reduce的内存及虚拟核数设置,决定了集群资源所能同时启动的container个数,影响集群并行计算的能力。

对于当前任务是CPU密集型任务(如复杂数学计算)的场景:在map和reduce的虚拟核数默认值基础上,逐渐增大虚拟核数进行调试(mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores参数控制),但不要超过可分配给container的虚拟核数(yarn.nodemanager.resource.cpu-vcores参数控制)。

对于当前任务是内存密集型任务(如ORC文件读取/写入、全局排序)的场景:在map和reduce的内存默认值基础上,逐渐增大内存值进行调试(mapreduce.map.memory.mb和mapreduce.reduce.memory.mb参数控制),但不要超过当前NodeManager上可运行的所有容器的物理内存总大小(yarn.nodemanager.resource.memory-mb参数控制)。

(10)合理控制map的数量

map的数量会影响MapReduce扫描、过滤数据的效率。

对于扫描、过滤数据的逻辑比较复杂、输入数据量较大条数较多的场景:根据集群总体资源情况,以及分配给当前租户的资源情况,在不影响其他业务正常运行的条件下,map数量需要适当增大,增加并行处理的力度。

(11)合理控制reduce的数量

reduce数量会影响MapReduce过滤、聚合、对数据排序的效率。

对于关联、聚合、排序时reduce端待处理数据量较大的场景:首先根据每个reduce处理的合适数据量控制reduce的个数,如果每个reduce处理数据仍然很慢,再考虑设置参数增大reduce个数。另一方面,控制能启动的reduce最大个数为分配给当前租户的资源上限,以免影响其他业务的正常运行。

(12)将重复的子查询结果保存到中间表

对于指标计算类型的业务场景,多个指标的HQL语句中可能存在相同的子查询,为避免重复计算浪费计算资源,考虑将重复的子查询的计算结果保存到中间表,实现计算一次、结果共享的优化目标。

(13)启用相关性优化器

相关性优化,旨在利用下面两种查询的相关性:

(a)输入相关性:在原始operator树中,同一个输入表被多个MapReduce任务同时使用的场景;

(b)作业流程的相关性:两个有依赖关系的MapReduce的任务的shuffle方式相同。

    通过以下参数启用相关性优化:

相关参考:

https://cwiki.apache.org/confluence/display/Hive/Correlation+Optimizer

(14)启用基于代价的优化

基于代价的优化器,可以基于代价(包括FS读写、CPU、IO等)对查询计划进行进一步的优化选择,提升Hive查询的响应速度。

通过以下参数启用基于代价的优化:

相关参考:

https://cwiki.apache.org/confluence/display/Hive/Cost-based+optimization+in+Hive

(15)启用向量化查询引擎

传统方式中,对数据的处理是以行为单位,依次处理的。Hive也采用了这种方案。这种方案带来的问题是,针对每一行数据,都要进行数据解析,条件判断,方法调用等操作,从而导致了低效的CPU利用。

向量化特性,通过每次处理1024行数据,列方式处理,从而减少了方法调用,降低了CPU消耗,提高了CPU利用率。结合JDK1.8对SIMD的支持,获得了极高的性能提升。

通过以下参数启用向量化查询引擎:

相关参考:

https://cwiki.apache.org/confluence/display/Hive/Vectorized+Query+Execution

(16)启用Join相关优化

(a)使用MapJoin。MapJoin是针对以下场景进行的优化:两个待连接表中,有一个表非常大,而另一个表非常小,以至于小表可以直接存放到内存中。这样小表复制多份,在每个map task内存中存在一份(比如存放到hash table中),然后只扫描大表。对于大表中的每一条记录key/value,在hash table中查找是否有相同的key的记录,如果有,则连接后输出即可。

(b)使用SMB  Join。

相关参考:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+JoinOptimization

(17)使用Multiple Insert特性

    以下左图为普通insert,右图为Multiple Insert,减少了MR个数,提升了效率。

(18)使用TABLESAMPLE取样查询

在Hive中提供了数据取样(SAMPLING)的功能,用来从Hive表中根据一定的规则进行数据取样,Hive中的数据取样支持数据块取样和分桶表取样。

    以下左图为数据块取样,右图为分桶表取样:

(19)启用Limit优化

启用limit优化后,使用limit不再是全表查出,而是抽样查询。涉及参数如下:

(20)利用局部排序

Hive中使用order by完成全局排序,正常情况下,order by所启动的MR仅有一个reducer,这使得大数据量的表在全局排序时非常低效和耗时。

当全局排序为非必须的场景时,可以使用sort by在每个reducer范围进行内部排序。同时可以使用distribute by控制每行记录分配到哪个reducer。

(21)慎用低性能的UDF和SerDe

慎用低性能的UDF和SerDe,主要指谨慎使用正则表达式类型的UDF和SerDe。如:regexp、regexp_extract、regexp_replace、rlike、RegexSerDe。

当待处理表的条数很多时,如上亿条,采用诸如([^ ]*)([^ ]*)([^]*)(.?)(\".*?\")(-|[0-9]*)(-|[0-9]*)(\".*?\")(\".*?\")这种复杂类型的正则表达式组成过滤条件去匹配记录,会严重地影响map阶段的过滤速度。

建议在充分理解业务需求后,自行编写更高效准确的UDF实现相应的功能。

(22)优化count(distinct)

    优化方式如下,左图为原始HQL,右图为优化后HQL。

(23)改用MR实现

    在某些场景下,直接编写MR比使用HQL更加高效。

原文地址:https://www.cnblogs.com/alamps/p/8446877.html

时间: 2024-11-02 21:18:44

hive 调优手段的相关文章

Hive调优实战

Hive优化总结 ---by 食人花 优化时,把hive sql当做map reduce程序来读,会有意想不到的惊喜. 理解hadoop的核心能力,是hive优化的根本.这是这一年来,项目组所有成员宝贵的经验总结.   长期观察hadoop处理数据的过程,有几个显著的特征: 1.不怕数据多,就怕数据倾斜. 2.对jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几个jobs,没半小时是跑不完的.map reduce作业初始化的时间是比较长的. 3.对su

Python的内存管理机制及调优手段

内存管理机制:引用计数.垃圾回收.内存池 引用计数: 引用计数是一种非常高效的内存管理手段,当一个Python对象引用时其引用计数加一,当其不再被一个变量引用时则减一.当引用计数等于0时对象被删除. 1.引用计数: 引用计数也是一种垃圾收集机制,而且也是一种最直观,最简单的垃圾收集技术.当 Python 的某个对象的引用计数降为 0 时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了.比如某个新建对象,它被分配给某个引用,对象的引用计数变为 1.如果引用被删除,对象的引用计数为 0,那

Hive调优-萌贝树母婴无骗子

1 Fetch 抓取 Hive调优-萌贝树母婴无骗子,Fectch 抓取是指对某些情况下的查询不必使用 MapReduce 计算将 hive.fetch.task.conversion 设置成 more,在全局查找.字段查找.limit查找等都不走 MapReduce2 本地模式 Hive调优-萌贝树母婴无骗子,多数的 Hadoop Job 是需要 Hadoop 提供的完整的可扩展性来处理大数据集的,不过,有时 Hive 的输入数据量是非常小的,在这种情况下,为查询触发执行任务消耗的时间可能会比

JVM:垃圾回收机制和调优手段

转载请注明出处: jiq?钦's technical Blog - 季义钦 引言: 我们都知道JVM内存由几个部分组成:堆.方法区.栈.程序计数器.本地方法栈 JVM垃圾回收仅仅针对公共内存区域即:堆和方法区进行. 本文主要讨论两点,一是垃圾回收策略,二是调优的方法. 一.垃圾回收机制 1.1 分代管理 将堆和方法区按照对象不同年龄进行分代: u  堆中会频繁创建对象,基于一种分代的思想,按照对象存活时间将堆划分为新生代和旧生代两部分,我们不能一次垃圾回收新生代存活的对象就放入旧生代,而是要经过

二、hive调优

下面是hive使用过程中一些调优策略 一.fetch抓取 ? Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算.例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台.? 在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查

Hive调优(语法与参数层面优化)

一.简介 作为企业Hadoop应用的核心产品,Hive承载着FaceBook.淘宝等大佬 95%以上的离线统计,很多企业里的离线统计甚至全由Hive完成,如我所在的电商.Hive在企业云计算平台发挥的作用和影响愈来愈大,如何优化提速已经显得至关重要. 好的架构胜过任何优化,好的Hql同样会效率大增,修改Hive参数,有时也能起到很好的效果. 有了瓶颈才需要优化 1.Hadoop的主要性能瓶颈是IO负载,降IO负载是优化的重头戏. 2.对中间结果的压缩 3.合理设置分区,静态分区和动态分区 二.H

hive调优

怎样才能让程序花费的时间最短?Hadoop 是分布式处理系统,可以从两方面进行入手:控制任务的处理数量,使之均衡分布在每个reduce上,不会使哪个任务因为数据量多大而使用过长的时间:增加reduce到一定的数量. 另外的制约因素是tasktracker的负载,一个tasktracker能同时运行多少个map任务,是由 mapred.taskertracker.map.tasks.maximun 属性控制,默认是2个任务.能同时运行多少个reduce任务数是由mapred.tasktracker

(转)hive调优(1) coding调优

本人认为hive是很好的工具,目前支持mr,tez,spark执行引擎,有些大公司原来封装的sparksql,开发py脚本,但是目前hive支持spark引擎(不是很稳定,建议Tez先),所以离线还是用hive比较好. 先将工作中总结,以及学习其他人的hive优化总结如下: 一. 表连接优化 这是比较常见的问题 1.  将大表放后头 Hive假定查询中最后的一个表是大表.它会将其它表缓存起来,然后扫描最后那个表. 因此通常需要将小表放前面,或者标记哪张表是大表:/*streamtable(tab

Hive调优技巧

1.Fetch抓取 set hive.fetch.task.conversion=more(默认) 1 Fetch 抓取是指,Hive 中对某些情况的查询可以不必使用 MapReduce 计算.该属性设置为 more 以后,在全局查找.字段查找.limit 查找等都不走 MapReduce. 设置为none后所有类型的查找语句都要走MapReduce: 2.本地模式 set hive.exec.mode.local.auto=true(开启本地模式) 1 Hive 可以通过本地模式在单台机器上