前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hive的常用优化

Hive的常用优化

作者头像
kk大数据
发布2020-04-24 13:48:23
1.3K0
发布2020-04-24 13:48:23
举报
文章被收录于专栏:kk大数据kk大数据

一、慎用常用内置的api

数据量大尽量避免使用 count(distinct) ,这会导致所有数据在一个 reduce 内去重,导致运行缓慢,使用 group by 来代替

二、合理调整 map 数 和 reduce 数

下面我们列举几个常见的场景来分别进行调优

场景1

一个文件128M(一个 block 块的大小),但只有两列,数据量为几千万行,但只会产生一个 MapReduce

解决方案:

代码语言:javascript
复制
--设置10个reduceset mapred.reduce.tasks=10;-- 随机拆分成10个文件create table a_1 asselect * from adistribute by rand(123);

使用随机分配 key 的方案,用10个 reduce 来处理,此时数据就会随机分配到10个文件中,形成一个新的临时表。

场景2

一个表有成百上千的小文件,但仅仅是对表进行简单的 count。由于一个文件就会产生一个 map 任务,启动 map 任务的时间远远大于处理数据的时间。

解决方案:

代码语言:javascript
复制
set mapred.max.split.size=134217728;set mapred.min.split.size.per.node=104857600;set mapred.min.split.size.per.rack=104857600;set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

意思是:大于128M,按128M来切分;大于100M,小于128M的,按100M来切分;小于100M的,合并

这样就会先合并小文件,然后再启动 MapReduce 了

场景3

任务 reduce 普遍运行缓慢,迟迟没有运行完,那么需要合理调整 reduce 数量

如果不调整,hive 会自动帮你确定 reduce 任务,规则如下

代码语言:javascript
复制
--参数1,每个reduce任务处理的数据量,默认为1000^3=1Ghive.exec.reducers.bytes.per.reducer--参数2,每个任务最大的reduce数,默认为999hive.exec.reducers.max

reduce 数量 = min(参数2,总输入数据量/参数1)

也就是每个 reduce 处理1个g数据

设置方式1:

调整每个reduce处理的数据量

代码语言:javascript
复制
hive.exec.reducers.bytes.per.reducer

设置方式2:

直接设置 reduce 数量

代码语言:javascript
复制
set mapred.reduce.tasks=15;

当然 reduce 也不是越多越好,reduce 太多可能会产生非常多的小文件,增加 namenode 压力,执行 MapReduce 任务也会产生很多的map任务

三、小文件合并优化

代码语言:javascript
复制
--设置map端输出进行合并,默认为true  set hive.merge.mapfiles = true--设置reduce端输出进行合并,默认为false  set hive.merge.mapredfiles = true--设置合并文件的大小  set hive.merge.size.per.task = 256*1000*1000--当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。set hive.merge.smallfiles.avgsize=16000000

四、注意sql编写

(1)列裁剪,需要的列才输出,尽量不写*

(2)分区裁剪,设置好分区,不需要的分区不要读

(3)能用一个 sql 写完,绝不用临时表

(4)hive 可以自动把 union all 优化成一个 jon,但尽量不要再 union all 中写 group by 和 join,可以做一个临时表。

五、数据倾斜

(1)检查 join 条件的数值类型是不是一样

(2)join 操作之空 key 过滤,导致空值全在一个reduce中,可以使用下面的sql来解决这类问题

代码语言:javascript
复制
SELECT *   FROM log a   LEFT OUTER JOIN bmw_users b ON  CASE WHEN a.user_id IS NULL THEN CONCAT('dp_hive', RAND())   ELSE a.user_id END = b.user_id;

在 空的key上加随机数来解决

(3)join 操作之小表join大表,可以使用 mapjoin

代码语言:javascript
复制
set hive.auto.convert.join = true;默认为trueset hive.mapjoin.smalltable.filesize=25000000;

(4)使用 hive 自动的数据倾斜优化

代码语言:javascript
复制
set hive.groupby.skewindata = true

生成的查询计划会有两个MR Job。

第一个MR Job中,Map的输出结果结合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果。这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的。

第二个MR Job再根据预处理的数据结果按照Group By Key分布到reduce中,这个过程可以保证相同的key被分到同一个reduce中,最后完成最终的聚合操作。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 KK架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档