Hive优化(21种方案)

本文介绍了Hive性能优化的多项策略,包括Fetch抓取、本地模式、MapJoin、GroupBy优化、动态分区、并行执行等,旨在提升大数据处理效率。

1、Fetch抓取

  Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台。

  在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

2、本地模式

  大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际job的执行时间要多的多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

  (1)set hive.exec.mode.local.auto=true; //开启本地mr

  用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。

  (2)set hive.exec.mode.local.auto.inputbytes.max=50000000;

  设置local mr的最大输入数据量,当输入数据量小于这个值时采用local mr的方式,默认为134217728,即128M

  (3)set hive.exec.mode.local.auto.input.files.max=10;

  设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4

3、过滤导致数据倾斜的Key、空Key转换(数据倾斜)

  有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。

  有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的reducer上。

4、设置MapJoin(数据倾斜)

  如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。

  1)开启MapJoin参数设置:
  (1)设置自动选择Mapjoin
    set hive.auto.convert.join = true; 默认为true
  (2)大表小表的阀值设置(默认25M一下认为是小表):
    set hive.mapjoin.smalltable.filesize=25000000;

  2)MapJoin工作机制

在这里插入图片描述

  首先是Task A,它是一个Local Task(在客户端本地执行的Task),负责扫描小表b的数据,将其转换成一个HashTable的数据结构,并写入本地的文件中,之后将该文件加载到DistributeCache中。

  接下来是Task B,该任务是一个没有Reduce的MR,启动MapTasks扫描大表a,在Map阶段,根据a的每一条记录去和DistributeCache中b表对应的HashTable关联,并直接输出结果。

  由于MapJoin没有Reduce,所以由Map直接输出结果文件,有多少个Map Task,就有多少个结果文件。

5、Group By优化

  默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。

   (1)开启Map端聚合参数设置,默认为True

    hive.map.aggr = true

  (2)在Map端进行聚合操作的条目数目

     hive.groupby.mapaggr.checkinterval = 100000

  (3)有数据倾斜的时候进行负载均衡(默认是false)

     hive.groupby.skewindata = true

6、Count(Distinct) 去重优化方案(数据倾斜)

  数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替换,虽然会多用一个Job来完成,但在数据量大的情况下,这个绝对是值得的。

	select count(distinct id) from bigtable;(优化前)

	select count(id) from (select id from bigtable group by id) a;(优化后)

7、迪卡尔基

  尽量避免笛卡尔积,join的时候不加on条件,或者无效的on条件,Hive只能使用1个reducer来完成笛卡尔积。

8、行列过滤

  列处理:在SELECT中,只拿需要的列,如果有,尽量使用分区过滤,少用SELECT *。

  行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤。

9、开启动态分区

  关系型数据库中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive中也提供了类似的机制,即动态分区(Dynamic Partition),只不过,使用Hive的动态分区,需要进行相应的配置。

  (1)开启动态分区功能(默认true,开启)
    hive.exec.dynamic.partition=true

  (2)设置为非严格模式(动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。)
    hive.exec.dynamic.partition.mode=nonstrict

  (3)在所有执行MR的节点上,最大一共可以创建多少个动态分区。
    hive.exec.max.dynamic.partitions=1000

  (4)在每个执行MR的节点上,最大可以创建多少个动态分区。该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。
    hive.exec.max.dynamic.partitions.pernode=100

  (5)整个MR Job中,最大可以创建多少个HDFS文件。
    hive.exec.max.created.files=100000

  (6)当有空分区生成时,是否抛出异常。一般不需要设置。
    hive.error.on.empty.partition=false

10、开启并行执行

  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。

  当然,得是在系统资源比较空闲的时候才有优势,否则,没资源,并行也起不来。

11、开启严格模式

  Hive提供了一个严格模式,可以防止用户执行那些可能意向不到的不好的影响的查询。通过设置属性hive.mapred.mode值为默认是非严格模式nonstrict 。开启严格模式需要修改hive.mapred.mode值为strict,开启严格模式可以禁止3种类型的查询。

  1)对于分区表,除非where语句中含有分区字段过滤条件来限制范围,否则不允许执行。换句话说,就是用户不允许扫描所有分区。进行这个限制的原因是,通常分区表都拥有非常大的数据集,而且数据增加迅速。没有进行分区限制的查询可能会消耗令人不可接受的巨大资源来处理这个表。

  2)对于使用了order by语句的查询,要求必须使用limit语句。因为order by为了执行排序过程会将所有的结果数据分发到同一个Reducer中进行处理,强制要求用户增加这个LIMIT语句可以防止Reducer额外执行很长一段时间。

  3)限制笛卡尔积的查询。对关系型数据库非常了解的用户可能期望在执行JOIN查询的时候不使用ON语句而是使用where语句,这样关系数据库的执行优化器就可以高效地将WHERE语句转化成那个ON语句。不幸的是,Hive并不会执行这种优化,因此,如果表足够大,那么这个查询就会出现不可控的情况。

12、开启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>

  这个功能的缺点是,开启JVM重用将一直占用使用到的task插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡的”job中有某几个reduce task执行的时间要比其他Reduce task消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。

13、开启推测执行机制

  在分布式集群环境下,因为程序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的推测执行:

<property>
	<name>hive.mapred.reduce.tasks.speculative.execution</name>
	<value>true</value>
    <description>Whether speculative execution for reducers should be turned on. </description>
</property>

  关于调优这些推测执行变量,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大大。

14、执行计划分析

  1)基本语法
    EXPLAIN [EXTENDED | DEPENDENCY | AUTHORIZATION] query
  2)案例实操
    (1)查看下面这条语句的执行计划
      hive (default)> explain select * from emp;
      hive (default)> explain select deptno, avg(sal) avg_sal from emp group by deptno;
    (2)查看详细执行计划
      hive (default)> explain extended select * from emp;
      hive (default)> explain extended select deptno, avg(sal) avg_sal from emp group by deptno;

15、改变压缩格式

Snappy

16、开启负载均衡机制(数据倾斜)

	hive.map.aggr=true
	//Map 端部分聚合,相当于Combiner
	hive.groupby.skewindata=true

  有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。

17、使用TEZ引擎

  开启TEZ引擎会将多个并行任务合并为一个任务执行,减少任务启停时间,提高运算效率。

18、使用Combine(数据倾斜)

  使用Combine可以大量地减小数据频率倾斜和数据大小倾斜。在可能的情况下,combine的目的就是聚合并精简数据。

19、抽样和范围分区(数据倾斜)

  可以通过对原始数据进行抽样得到的结果集来预设分区边界值。

20、自定义分区(数据倾斜)

  基于输出键的背景知识进行自定义分区。例如,如果map输出键的单词来源于一本书。其中大部分必然是省略词(stopword)。那么就可以将自定义分区将这部分省略词发送给固定的一部分reduce实例。而将其他的都发送给剩余的reduce实例。

21、为倾斜Key打上随机数(数据倾斜)

  把导致倾斜的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null 值关联不上,处理后并不影响最终结果。

<think> 首先,用户的问题是基于之前的引用内容:"我想查找hive优化方案的案例"。用户提到了引用[1]到[5],这些是关于Hive优化的内容。 我的系统级指令包括: - 所有行内数学表达式必须使用$...$格式(但这里没有数学内容)。 - 独立公式必须使用$$...$$格式(同样,没有数学)。 - LaTeX语法正确(确保任何公式正确格式)。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 用户的问题是:"我想查找hive优化方案的案例",意思是"我想查找Hive优化方案的案例"。用户提供了引用,所以我需要基于这些引用来回答问题。 回顾引用: - [^1]: 讨论了使用Tez或Spark作为执行引擎的优化案例,比如切换到Tez后时间从4小时缩短到1.5小时。 - [^2]: 关于Fetch抓取优化,避免mapreduce计算。 - [^3]: 类似[^2],强调了本地模式和Fetch抓取。 - [^4]: 关于倾斜优化(skewjoin)。 - [^5]: 关于倾斜优化的具体设置。 用户之前可能有对话历史,但在这个消息中,没有提供之前的对话。系统提示说:"上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。" 但在这个上下文,用户第一次出现这个问题,所以我应该基于当前问题和引用。 用户说:"参考站内引用",并提供了引用内容,所以我需要整合这些内容来回答。 结构清晰的回答: - 逐步解决问题:先从整体介绍Hive优化,然后提供具体案例。 - 生成相关问题。 回答大纲: 1. 介绍Hive优化方案。 2. 基于引用提供具体优化案例: - 案例1: 使用Tez执行引擎优化(来自[^1])。 - 案例2: Fetch抓取优化(来自[^2]和[^3])。 - 案例3: 倾斜优化(来自[^4]和[^5])。 3. 每个案例简要描述优化方法、效果和设置。 4. 结尾自然地添加引用标识。 5. 生成相关问题。 使用中文回答。 确保引用标识:在每个引用段落末尾添加[^n]。 现在,构建回答: - 开头:解释Hive优化的重要性。 - 主体:列举几个优化方案案例。 - 执行引擎优化:Tez或Spark。 - Fetch抓取优化。 - 倾斜优化。 - 每个案例基于引用。 生成相关问题: - 例如:如何配置Tez执行引擎?Fetch抓取的更多细节?倾斜优化的最佳实践? 最终回答结构: - 回答部分。 - §§相关问题§§部分。 </think> ### Hive优化方案案例介绍 Hive是一个基于Hadoop的数据仓库工具,优化方案能显著提升查询性能和效率。基于您提供的引用内容,我将介绍几个典型的优化方案案例,包括优化方法、设置参数、预期效果和实际应用场景。优化方案通常涉及执行引擎切换、查询简化、倾斜数据处理等。下面我将逐步解析每个案例,帮助您理解如何应用这些优化。 #### 案例1: 切换到Tez执行引擎优化复杂ETL作业 当Hive查询涉及多步复杂ETL(Extract-Transform-Load)任务时,默认的MapReduce引擎可能效率低下。切换到Tez执行引擎可以通过DAG(有向无环图)优化、Container重用和动态物理优化等手段加速处理。 - **优化方法**:修改Hive的执行引擎参数为Tez。 - **设置参数**: ```sql SET hive.execution.engine=tez; ``` - **实际效果**:参考引用[^1],一个包含多步复杂ETL的Hive SQL脚本从MapReduce切换到Tez后,运行时间从4小时缩短到1.5小时,效率提升约2.7倍。适用于大数据量、多关联查询的场景。 - **应用场景**:ETL pipelines、数据清洗作业,尤其在需要减少整体运行时间的环境中。 #### 案例2: Fetch抓取优化简化查询 对于不需要MapReduce计算的简单查询(如全表扫描或LIMIT操作),开启Fetch抓取可以直接读取存储文件,避免启动MapReduce任务的开销。 - **优化方法**:配置`hive.fetch.task.conversion`参数为"more",系统会自动优化查询路径。 - **设置参数**:在`hive-site.xml`文件中修改: ```xml <property> <name>hive.fetch.task.conversion</name> <value>more</value> <description>Expects one of [none, minimal, more]. Enables optimization for SELECT, FILTER, LIMIT queries without MapReduce.</description> </property> ``` - **实际效果**:引用[^2]和[^3]指出,开启后全局查找(如`SELECT * FROM table`)、字段查找或LIMIT查询不再触发MapReduce,减少延迟,提升响应速度。例如,一个简单的SELECT查询从秒级延迟降低到毫秒级。 - **应用场景**:数据探索、快速数据抽样或开发测试阶段,特别适合小规模数据集或无需聚合的查询[^2][^3]。 #### 案例3: 倾斜优化处理数据分布不均 在JOIN或GROUP BY操作中,数据倾斜(某些key值分布不均匀)会导致部分节点负载过高。Hive内置的倾斜优化可以自动识别并拆分倾斜数据到独立任务中处理。 - **优化方法**:开启倾斜优化参数并指定倾斜key值。 - **设置参数**: ```sql -- 开启倾斜优化 SET hive.optimize.skewjoin=true; -- 设置倾斜阈值(如默认100,000) SET hive.skewjoin.key=100000; -- 可选:指定表名和倾斜key值(例如seller_id的'0'和'1') SET hive.optimize.skewinfo=table_B:(seller_id)[('0')('1')]; ``` - **实际效果**:引用[^4]和[^5]说明,优化Hive会自动为倾斜key创建新MapReduce任务处理,避免任务拖尾。例如,在电商数据分析中,seller_id的特定值导致倾斜,优化后查询时间减少50%以上,资源利用率更均衡。 - **应用场景**:高并发ETL、大型JOIN操作或数据仓库中处理用户行为数据等倾斜问题[^4][^5]。 ### 优化方案总结 这些案例展示了Hive优化的常见方向: - **执行引擎优化**:切换Tez或Spark提升并行处理能力(Tez适合通用ETL,Spark适合迭代计算)。 - **查询简化**:利用Fetch抓取减少不必要计算。 - **数据均衡**:倾斜优化保证任务负载分配。 实际应用中,建议结合监控工具(如YARN资源管理器)评估优化效果,并通过测试环境迭代参数。更多案例可参考Hive官方文档或社区分享。 ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值