大数据Hive——数据倾斜

什么是数据倾斜呢?

简单的讲,数据倾斜就是在我们计算的时候,由于数据的分布不均,导致大量的数据集中在一台或者几台服务器上,造成数据的热点问题,这些数据的计算速度往往低于平均计算速度,从而导致整个计算过程变慢

  • 用Hive算数据的时候reduce阶段卡在99.99%

  • 用SparkStreaming做实时算法时候,一直会有executor出现OOM的错误,但是其余的executor内存使用率却很低。

hive优化方法

1- join优化

在表的关联时,因为关联字段的原因造成某个reduce处理的数据量过大,产生数据的倾斜,导致计算时间过长

方案一: Mapjoin

Map join 在每一个maptask读取数据的时候,每读取一条,就会和内存中的数据进行匹配,如果匹配的上,将数据合并在一起输出

优点:将原有的reduce join 问题全部解决

缺点:1 比较消耗内存

2 要求整个join中,必须都有一个小表,否则无法放入内存

仅适用于:小表join大表 /大表join小表

设置放法:

set hive.auto.convert.join=true; -- 开启 map join的支持 默认值为True

set hive.auto.convert.join.noconditionaltask.size=20971520; -- 设置 小表数据量的最大阈值: 默认值为 20971520(20M)

方案二 Bucket Map Join

1-开启Bucket Map Join支持:

2-Join两个表必须是分桶表

3-一个表的分桶数量是另一个表的分桶数量的整倍数

4-分桶列必须是join的ON条件的列 join tb1.id = tb2.id

5-必须建立在Map Join场景中

设置方法:

set hive.optimize.bucketmapjoin =true;

方案三 :SBM Join

1-两个表必须都是分桶表

2-开启SMB Join支持: set hive.auto.convert.sortmerge.join=true; set hive.optimize.bucketmapjoin.sortedmerge =true;

set hive.auto.convert.sortmerge.join.noconditionaltask=true;

3-两个表的分桶的数量是一致的

4-分桶列必须是join的on条件的列,同时必须保证按照分桶列进行排序操作 当向表中写入数据是,按照分桶字段进行排序写入

--开启强制排序 ​ set hive.enforce.sorting=true;

--在建分桶表使用:必须使用sorted by() 5- 应用在Bucket Map Join场景中

--开启bucket map join

set hive.optimize.bucketmapjoin =true; 6-必须开启HIVE自动尝试使用SMB方案:

set hive.optimize.bucketmapjoin.sortedmerge =true;

当相关服务都开启后,有hive决定使用那种方式进行关联

1-判断表是不是 分桶表,在判断表的大小 如果不是分桶,但是属于小表 触发mapjoin

2-判断表是分桶,但是分桶数量不一致 触发Bucket Map Join

3-断表是分桶,但是分桶数量一致,关联字段是顺序的 触发SMB Join

如果条件不符和上面要求,就执行一般join流程,可能出现数据倾斜

在运行期间

运行期处理方案:

思路: 在执行MR的时候, 会动态统计每一个 k2的值出现重复的次数, 当这个重复的次数达到一定的阈值后, 认为

当前这个k2的数据存在数据倾斜, 自动将其剔除, 交由给一个单独的MR来处理即可,两个MR处理完成后, 将结果基于

union all 合并在一起即可

实操:

set hive.optimize.skewjoin=true; -- 阈值, 此参数在实际生产环境中, 需要调整在一个合理的值(否则极易导致大量的key都是倾斜的) set hive.skewjoin.key=100000;

group by 造成的数据倾斜

将相同的分组数据放在一个reduce中处理,造成数据倾斜

方案一

基于MR的 combiner(规约, 提前聚合) 减少数据达到reduce数量, 从而减轻倾斜问题

-- 只需要在HIVE中开启combiner提前聚合配置参数即可:
set hive.map.aggr=true;

方案二

负载均衡的解决方案(需要运行两个MR来处理) (大combiner方案)

-- 只需要开启负载均衡的HIVE参数配置即可:
set hive.groupby.skewindata=true;

如果说分组的字段对应的数据较多,建议只用负载均衡解决方案

3 索引优化

用来提升查询速度

Row Group Index索引

行组索引

条件:

1) 要求表的存储类型为ORC存储格式

2) 在创建表的时候, 必须开启 row group index 索引支持'orc.create.index'='true'

3) 在插入数据的时候, 必须保证按照where过滤的字段进行数据的顺序插入

适用于: 数值类型的, 并且对数值类型进行 不等的过滤操作

Bloom Fliter Index索引

布隆索引

条件:

1) 要求表的存储类型为 ORC存储方案

2) 在建表的时候, 必须设置为那些列构建布隆索引

3) 仅能适合于等值过滤查询操作

  • 26
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值