Hive数据倾斜解决方案

1. 单表造成的倾斜

1.1 倾斜场景

如果是单表倾斜,一般是Group By 造成的,Shuffle时会把某个key的数据发送到一个Reduce里,如果某个key的数据量很大,那么就会造成倾斜。

1.2 解决方案

开启Map端预聚合 ,参数为:
set hive.map.aggr = true; // map端预聚合
set hive.groupby.skewindata = true; // 倾斜时负载均衡
提前在Map端做一个预聚合,这样就会很大的减轻Reduce端的压力

2. 两张表Join造成的倾斜

2.1 倾斜场景

两张大表Join发生倾斜

2.2 解决方案

使用分桶表,并且开启SMB Join (Sort Merge Bucket Join)
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;

3. 大表Join小表造成的倾斜

3.1 倾斜场景

大表和小表Join时发生倾斜

3.2 解决方案

开启MapJoin,将小表广播到内存中,避免Shuffle的产生。

4. 空值过多造成的倾斜

4.1 倾斜场景

两张表进行Join时,某张表空值过多,发生倾斜的现象

4.2 解决方案

这里有两张解决方案,第一种就是给空值加上随机数,做法很简单,就是在关联条件那里使用case when 函数加上随机数就行 例如:
select t1.*,t2.x from t1 left join t2 on case when t2.x is null then concat(“hive”,rand()) else t2.guid=t1.guid;

第二种就是在join之前过滤掉为null的数据,关联之后再加上null值数据;例如:
select t1.*,t2.x from t1 left join t2 on t2.x is not null and t2.guid=t1.guid;

5. Hive任务整体优化

5.1. Fetch 抓取

Fetch 抓取可以控制Hive某些简单的查询不用走MR,只要修改在 hive-default.xml.template 文件中 hive.fetch.task.conversion = more,那么之后在全局查找、字段查找、limit查找都不用走MR程序。

5.2. 本地模式

本地模式可以控制MR不用被提交到Yarn上,本地模式对小文件处理比较有效果

SET hive.exec.mode.local.auto=true; – 默认 false
SET hive.exec.mode.local.auto.inputbytes.max=50000000;
SET hive.exec.mode.local.auto.input.files.max=5; – 默认 4

默认情况下,一个作业只要满足以下条件,会启用本地模式

输入文件的大小 < 128MB
map任务的数量 < 4 个
reduce个数是1或者0

5.3. 严格模式

严格模式可以限制三种类型的查询,默认情况下是非严格模式。
开启严格模式

set hive.mapred.mode=strict;

开启严格模式后,限制3查询

笛卡尔积的查询
查询分区表时,必须指定分区范围,否则不允许查询
对于使用了order by的查询,必须使用limit进行限制

5.4. JVM 重用机制

默认情况下,Hadoop会为一个map或者reduce启动一个JVM,这样可以并行执行map和reduce任务。但是当map或者reduce是那种仅运行几秒钟的轻量级作业时,JVM启动进程所耗费的时间会比作业执行的时间还要长。所以我们可以开启JVM重用,以串行方式运行map和reduce任务,这样可以避免频繁的启停JVM。

如果要开启JVM重用,需要配置多少个task,默认值为共用一个JVM1,如果设置为-1,则表示不限制

#代表同一个MR job中顺序执行的10个task重复使用一个JVM,减少启动和关闭的开销
set mapreduce.job.jvm.numtasks=10;

5.5. 并行执行

Hive 会将一个SQL查询 转化成一个或者多个阶段,可能转化成 MapReduce阶段、抽样阶段、合并阶段、 limit 阶段。也就是说一个job可能包含一个或多个阶段,而hive在默认情况下,一次只能执行一个阶段, 而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,所以, 如果有更多的阶段可以并行执行,那么 job 可能就越快完成。

set hive.exec.parallel=true; //打开任务并行执行
set hive.exec.parallel.thread.number=16; //同一个 sql 允许最大并行度,默认为 8。

5.6. 推测执行

在分布式集群环境下,因为程序Bug、负载不均衡、资源分布不均等原因,会造成同一个job的多个任务之间运行速度不一致,有些任务的运行速度可能明显慢于其他任务(比如一个作业的某个任务进度只有50%,而其他所有任务已经运行完毕),则这些任务会拖慢作业的整体执行进度。

为了避免这种情况发生,Hadoop采用了推测执行机制,它根据一定的规则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。

hadoop 中默认两个阶段都开启了推测执行机制。
hive 本身也提供了配置项来控制 reduce-side 的推测执行:

set mapreduce.map.speculative=true
set mapreduce.reduce.speculative=true
set hive.mapred.reduce.tasks.speculative.execution=true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值