Hive调优12法

目录

1. 尽量不要使用COUNT(DISTINCT col)

2. 小文件会造成资源的过度占用以及影响查询效率

3. 请慎重使用SELECT *

4.不要在表关联后面加WHERE条件

5. 处理掉字段中带有空值的数据

6. 设置并行执行任务数

7.设置合理的Reducer个数

8. JVM重用

9. 为什么任务执行的时候只有一个reduce?

10. 选择使用Tez引擎

11. 选择使用本地模式

12. 选择使用严格模式

往期精选▼

转载是一种动力 分享是一种美德, 欢迎关注 大数据与数据仓库公众号, 回复 spark 领取资料

 


1. 尽量不要使用COUNT(DISTINCT col)

原因:

distinct算会将col列所有的数据放到内存中形成一个类似hash的结构,去重的速度是十分的块,但是如果数据量过大的话,极有可能发生OOM。

解决方案:

可以考虑使用Group By 或者 ROW_NUMBER() OVER(PARTITION BY col)方式代替COUNT(DISTINCT col)

 

2. 小文件会造成资源的过度占用以及影响查询效率

原因:

  • 众所周知,小文件在HDFS中存储本身就会占用过多的内存空间,那么对于MR查询过程中过多的小文件又会造成启动过多的Mapper Task, 每个Mapper都是一个后台线程,会占用JVM的空间
  • 在Hive中,动态分区会造成在插入数据过程中,生成过多零碎的小文件(请回忆昨天讲的动态分区的逻辑)
  • 不合理的Reducer Task数量的设置也会造成小文件的生成,因为最终Reducer是将数据落地到HDFS中的
  • Hive中分桶表的设置

解决方案:

在数据源头HDFS中控制小文件产生的个数,比如

  • 采用Sequencefile作为表存储格式,不要用textfile,在一定程度上可以减少小文件(常见于在流计算的时候采用Sequencefile格式进行存储)
  • 减少reduce的数量(可以使用参数进行控制)
  • 慎重使用动态分区,最好在分区中指定分区字段的val值
  • 最好数据的校验工作,比如通过脚本方式检测hive表的文件数量,并进行文件合并
  • 合并多个文件数据到一个文件中,重新构建表

 

3. 请慎重使用SELECT *

原因:

在大数据量多字段的数据表中,如果使用 SELECT * 方式去查询数据,会造成很多无效数据的处理,会占用程序资源,造成资源的浪费

解决方案:

在查询数据表时,指定所需的待查字段名,而非使用 * 号

 

4.不要在表关联后面加WHERE条件

原因:

比如以下语句:

SELECT * FROM stu as t LEFT JOIN course as t1 ON t.id=t2.stu_id WHERE t.age=18;

上面语句是否具有优化的空间?如何优化?

解决方案:

采用谓词下推的技术,提早进行过滤有可能减少必须在数据库分区之间传递的数据量

谓词下推的解释:

所谓谓词下推就是通过嵌套的方式,将底层查询语句尽量推到数据底层去过滤,这样在上层应用中就可以使用更少的数据量来查询,这种SQL技巧被称为谓词下推(Predicate pushdown)

SELECT * FROM (SELECT * FROM stu WHERE age=18) as t LEFT JOIN course AS t1 on t.id=t1.stu_id

 

5. 处理掉字段中带有空值的数据

原因:

一个表内有许多空值时会导致MapReduce过程中,空成为一个key值,对应的会有大量的value值, 而一个key的value会一起到达reduce造成内存不足

解决方式:

在查询的时候,过滤掉所有为NULL的数据,比如:

create table res_tbl as select n.* from (select * from res where id is not null ) n left join org_tbl o on n.id = o.id;

查询出空值并给其赋上随机数,避免了key值为空(数据倾斜中常用的一种技巧)

create table res_tbl as select n.* from res n full join org_tbl o on case when n.id is null then concat('hive', rand()) else n.id end = o.id;

 

6. 设置并行执行任务数

通过设置参数 hive.exec.parallel 值为 true,就可以开启并发执行。不过,在共享集群中,需要注意下,如果 job 中并行阶段增多,那么集群利用率就会增加。

//打开任务并行执行 set hive.exec.parallel=true;

//同一个 sql 允许最大并行度,默认为 8

set hive.exec.parallel.thread.number=16;

7.设置合理的Reducer个数

原因:

  • 过多的启动和初始化 reduce 也会消耗时间和资源
  • 有多少个Reduer就会有多少个文件产生,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题

解决方案:

Reducer设置的原则:

每个Reduce处理的数据默认是256MB

hive.exec.reducers.bytes.per.reducer=256000000

每个任务最大的reduce数,默认为1009

hive.exec.reducers.max=1009

计算reduce数的公式

N=min(每个任务最大的reduce数,总输入数据量/reduce处理数据量大小)

设置Reducer的数量

set mapreduce.job.reduces=n

8. JVM重用

JVM重用是Hadoop中调优参数的内容,该方式对Hive的性能也有很大的帮助,特别对于很难避免小文件的场景或者Task特别多的场景,这类场景大数据书执行时间都很短

 

Hadood的默认配置通常是使用派生JVM来执行map和reduce任务的,会造成JVM的启动过程比较大的开销,尤其是在执行Job包含有成百上千个task任务的情况。

JVM重用可以使得JVM实例在同一个job中重新使用N次,N的值可以在hadoop的mapred-site.xml文件中进行设置

<property> <name>mapred.job.reuse.jvm.num.tasks</name> <value>10</value> </property>

 

9. 为什么任务执行的时候只有一个reduce?

原因:

  • 使用了Order by (Order By是会进行全局排序)
  • 直接COUNT(1),没有加GROUP BY,比如:

有笛卡尔积操作

SELECT COUNT(1) FROM tbl WHERE pt=’201909’

解决方案:

避免使用全局排序,可以使用sort by进行局部排序

使用GROUP BY进行统计,不会进行全局排序,比如:

SELECT pt,COUNT(1) FROM tbl WHERE pt=’201909’group by pt;

 

10. 选择使用Tez引擎

Tez: 是基于Hadoop Yarn之上的DAG(有向无环图,Directed Acyclic Graph)计算框架。它把Map/Reduce过程拆分成若干个子过程,同时可以把多个Map/Reduce任务组合成一个较大的DAG任务,减少了Map/Reduce之间的文件存储。同时合理组合其子过程,也可以减少任务的运行时间

设置

hive.execution.engine = tez;

通过上述设置,执行的每个HIVE查询都将利用Tez

当然,也可以选择使用spark作为计算引擎

 

11. 选择使用本地模式

有时候Hive处理的数据量非常小,那么在这种情况下,为查询出发执行任务的时间消耗可能会比实际job的执行时间要长,对于大多数这种情况,hive可以通过本地模式在单节点上处理所有任务,对于小数据量任务可以大大的缩短时间

可以通过

hive.exec.mode.local.auto=true

 

12. 选择使用严格模式

Hive提供了一种严格模式,可以防止用户执行那些可能产生意想不到的不好的影响查询

比如:

  • 对于分区表,除非WHERE语句中含有分区字段过滤条件来限制数据范围,否则不允许执行,也就是说不允许扫描所有分区
  • 使用ORDER BY 语句进行查询是,必须使用LIMIT语句,因为ORDER BY 为了执行排序过程会将所有结果数据分发到同一个reduce中进行处理,强制要求用户添加LIMIT可以防止reducer额外的执行很长时间

严格模式的配置:

hive.mapred.mode=strict

往期精选▼

Spark性能调优之在实际项目中广播大变量

Spark Shuffle调优之调节map端内存缓冲与reduce端内存占比

Spark Shuffle调优之合并map端输出文件

Flink调优法则

5个Hadoop优化技巧

4个角度轻松理解 Flink中的Watermark

Flink中Checkpoint和Savepoint 的 3 个不同点

Flink实现固定时长或消息条数的触发器

Flink方案设计中的4大误区

使用 Broadcast State 的 4 个注意事项

3种Flink State Backend | 你该用哪个?

一文搞定 Flink 异步 I/O

Flink State 使用的4点建议

Flink在开发中的7点建议

 

转载是一种动力 分享是一种美德, 欢迎关注 大数据与数据仓库公众号, 回复 spark 领取资料

 

 

<think>好的,我现在需要解决用户关于Hive数据倾斜的问题。首先,我得回忆一下Hive数据倾斜的常见原因解决方案。数据倾斜通常发生在分布式计算中,当某些节点处理的数据量远大于其他节点时,导致任务执行时间过长甚至失败。 用户提到了他们想了解解决方案最佳实践,所以我需要系统性地整理这些内容。首先,数据倾斜可能出现在哪些阶段呢?比如在group by、join操作或者窗口函数中。不同的操作可能需要不同的处理方式。 接下来,我得考虑常见的解决方。比如,使用Map端聚合,hive.map.aggr参数,或者在join时处理倾斜的键。比如,将倾斜的键单独处理,或者使用随机数打散。这些方是否适用取决于具体场景。 另外,用户提供的引用中提到了在数据清洗阶段替换缺失值为平均值,这可能是在处理数据分布不均的问题。所以,数据预处理也是一个重要的步骤。比如,识别倾斜的键,并提前进行分散处理。 还需要考虑Hive的参数,比如设置hive.groupby.skewindata为true,或者整并行任务数。这些参数如何影响执行计划,需要解释清楚。 然后,最佳实践部分需要结合具体案例,比如电商数据分析中的处理方式,可能用到随机前缀或扩容的方。同时,要确保每个解决方案都有实际应用场景的支持,比如引用中的例子。 最后,生成相关问题时要围绕用户的问题展开,可能涉及识别数据倾斜、不同操作的化策略、参数等。确保问题能够帮助用户深入理解各个方面的解决方案。 现在需要将这些思考整理成一个结构化的回答,分点说明原因解决方案,引用相关的内容,并附上相关问题。确保语言清晰,符合中文习惯,同时正确使用LaTeX格式标注公式代码块。</think>### Hive数据倾斜解决方案及最佳实践 #### 一、数据倾斜成因分析 1. **键值分布不均**:在$group\ by$、$join$操作中,某些键值出现频率过高(如null值或特定枚举值) 2. **数据特征突变**:业务数据量级突然增长导致原有处理逻辑失效 3. **计算方式缺陷**:窗口函数使用不当或笛卡尔积操作 #### 二、通用解决方案 1. **参数**: ```sql set hive.map.aggr=true; -- Map端聚合(默认开启) set hive.groupby.skewindata=true; -- 开启负载均衡 set hive.optimize.skewjoin=true; -- 开启倾斜连接化 ``` 通过分散计算压力化执行计划[^1] 2. **数据预处理**: ```sql -- 示例:将null值替换为随机数 SELECT COALESCE(user_id, CONCAT('null_', FLOOR(RAND()*100))) AS new_key, COUNT(*) FROM log_table GROUP BY new_key ``` 推荐在ETL阶段处理异常值,如引用[3]所述将缺失值替换为平均值保证数据正态分布[^3] 3. **计算层化**: - **MapJoin强制转换**(小<25M): ```sql set hive.auto.convert.join=true; ``` - **倾斜键分离处理**(大join化): ```sql -- 分离倾斜键单独处理 SELECT * FROM ( SELECT /*+ MAPJOIN(b) */ a.key,a.value FROM a JOIN b ON a.key = b.key WHERE a.key <> 'hot_key' ) UNION ALL SELECT /*+ MAPJOIN(b) */ a.key,a.value FROM a JOIN b WHERE a.key = 'hot_key' ``` #### 三、典型场景解决方案 | 场景类型 | 解决方案 | 数学原理 | |-----------------|-----------------------------------|----------------------------| | Group By倾斜 | 两阶段聚合 | $$ \sum_{i=1}^n x_i = \sum_{j=1}^m (\sum_{k=1}^{k_j} x_k) $$ | | Join操作倾斜 | 随机前缀+扩容 | $hash(key)\ mod\ N \rightarrow hash(concat(key, rand()))\ mod\ M$ | | 窗口函数倾斜 | 分区键组合化 | $over(partition\ by\ key1,key2)$ | #### 四、最佳实践建议 1. **监控预警**:通过Hive集群监控系统(如引用[1]所述监控体系)提前发现倾斜特征[^1] 2. **采样分析**:执行前使用`tablesample`进行数据分布探测 ```sql SELECT key, COUNT(*) cnt FROM fact_table TABLESAMPLE(BUCKET 1 OUT OF 100) GROUP BY key ORDER BY cnt DESC LIMIT 10 ``` 3. **资源配置**:对倾斜任务单独设置资源参数 ```sql set mapreduce.map.memory.mb=4096; set mapreduce.reduce.memory.mb=8192; ``` #### 五、验证方 1. 执行计划分析: ```sql EXPLAIN EXTENDED SELECT ... -- 原始查询语句 ``` 2. 计数器验证: ```shell # 查看Counter信息 grep "COUNTERS" job_log.txt | grep "RECORDS_" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值