hadoop-hive-面试-数据倾斜问题

1 数据倾斜如何处理?

1.1 什么是数据倾斜?

数据分配严重不均就会产生数据倾斜。
数据倾斜,指的是并行处理的过程中,某些分区或节点处理的数据,显著高于其他分区或节点,导致这部分的数据处理任务比其他任务要大很多,从而成为这个阶段执行最慢的部分,进而成为整个作业执行的瓶颈,甚至直接导致作业失败。

1.2 数据倾斜的危害

(1)任务长时间挂起,资源利用率低下
(2)引发内存溢出,导致任务失败
(3)作业执行时间超出预期,导致后续依赖作业结果的作业出错

1.3 数据倾斜的原因

(1)读入数据的时候就是倾斜的
读入数据是计算任务的开始,但是往往这个阶段就可能已经开始出现问题了。
对于一些本身就可能倾斜的数据源,在读入阶段就可能出现个别partition执行时长过长或直接失败,如读取id分布跨度较大的mysql数据、partition分配不均的kafka数据不可分割的压缩文件
这些场景下,数据在读取阶段或者读取后的第一个计算阶段,就会容易执行过慢或报错。
(2)shuffle产生倾斜
在shuffle阶段造成倾斜,在实际的工作中更加常见,比如特定key值数量过多,导致join发生时,大量数据涌向一个节点,导致数据严重倾斜,个别节点的读写压力是其他节点的好几倍,容易引发OOM错误。
(3)过滤导致倾斜
有些场景下,数据原本是均衡的,但是由于进行了一系列的数据剔除操作可能在过滤掉大量数据后,造成数据的倾斜。
例如,大部分节点都被过滤掉了很多数据,只剩下少量数据,但是个别节点的数据被过滤掉的很少,保留着大部分的数据。这种情况下,一般不会OOM,但是倾斜的数据可能会随着计算逐渐累积,最终引发问题。

1.4 如何预防或解决数据倾斜问题?

(1)尽量保证数据源是均衡
程序读入的数据源通常是上个阶段其他作业产生的,那么我们在上个阶段作业生成数据时,就要注意这个问题,尽量不要给下游作业埋坑。
小建议:在程序输出写文件时,尽量不要用coalesce,而是用repartition,这样写出的数据,各文件大小往往是均衡的。
(2)对大数据集做过滤,结束后做repartition
对比较大的数据集做完过滤后如果过滤掉了绝大部分数据,在进行下一步操作前,最好可以做一次repartition,让数据重回均匀分布的状态,否则失衡的数据集,在进行后续计算时,可能会逐渐累积倾斜的状态,容易产生错误。
(3)对小表进行广播
如果两个数据量差异较大的表做join时,发生数据倾斜的常见解决方法,是将小表广播到每个节点去,这样就可以实现map端join,从而省掉shuffle,避免了大量数据在个别节点上的汇聚,执行效率也大大提升。
(4)编码时要注意,不要人为造成倾斜
(5)join前优化
个别场景下,两个表join,某些特殊key值可能很多,很容易产生数据倾斜,这时可以根据实际计算进行join前优化。
如计算是先join后根据key聚合,那可以改为先根据key聚合然后再join。又如,需求是join后做distinct操作,在不影响结果的前提下,可以改为先distinct,然后再join。这些措施都是可以有效避免重复key过多导致join时倾斜。
(6)具体问题具体分析
例如,读入mysql数据时倾斜,这通常是由于mysql的id分布严重不均,中间存在跨度很大的区间造成的。解决方法有两种,一是加大读取时的分区数,将倾斜的区间划分开;另一种是,先把id取出来进行等宽切割,确保每个区段的id数量一致,之后再对各区间进行数据读取。
参考:添加链接描述

2.数据倾斜

2.1 倾斜原因:

map输出数据按key Hash的分配到reduce中,由于key分布不均匀、业务数据本身的特性、建表时考虑不周、等原因造成的reduce 上的数据量差异过大。
(1)key分布不均匀;
(2)业务数据本身的特性;
(3)建表时考虑不周;
(4)某些SQL语句本身就有数据倾斜;
如何避免:对于key为空产生的数据倾斜,可以对其赋予一个随机值。

2.2 解决方案

(1)参数调节:
hive.map.aggr = true
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中),最后完成最终的聚合操作
(2)SQL 语句调节:
① 选用join key分布最均匀的表作为驱动表。做好列裁剪和filter操作,以达到两表做join 的时候,数据量相对变小的效果。
大小表Join:
使用map join让小的维度表(1000 条以下的记录条数)先进内存(小表在左,大表在右)。在map端完成reduce.
③ 大表Join大表:
空值的key变成一个字符串加上随机数或者删除空值,把倾斜的数据分到不同的reduce上,由于null 值关联不上,处理后并不影响最终结果。
④ count distinct大量相同特殊值:
count distinct 时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

3.用mapreduce怎么处理数据倾斜问题?

数据倾斜:map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完,此称之为数据倾斜。

(1)局部聚合加全局聚合。
第一次在 map 阶段对那些导致了数据倾斜的 key 加上 1 到 n 的随机前缀,这样本来相同的 key 也会被分到多个 Reducer 中进行局部聚合,数量就会大大降低。
第二次 mapreduce去掉 key 的随机前缀,进行全局聚合
思想:二次 mr,
第一次将 key 随机散列到不同 reducer 进行处理
达到负载均衡
目的。
第二次再根据去掉 key 的随机前缀按原 key 进行 reduce 处理
这个方法进行两次 mapreduce,性能稍差。
(2)增加 Reducer,提升并行度
JobConf.setNumReduceTasks(int)
(3)实现自定义分区
根据数据分布情况,自定义散列函数,将 key 均匀分配到不同 Reducer

4. hive的倾斜的原因?如何解决?

注意数据倾斜
在hive里比较常用的处理办法

  1. 通过hive.groupby.skewindata=true控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到reduce做次预汇总,减少某些key值条数过多某些key条数过小造成的数据倾斜问题
    第二通过hive.map.aggr = true(默认为true)在Map端做combiner,假如map各条数据基本上不一样, 聚合没什么意义,做combiner反而画蛇添足,hive里也考虑的比较周到通过参数hive.groupby.mapaggr.checkinterval = 100000 (默认)hive.map.aggr.hash.min.reduction=0.5(默认),预先取100000条数据聚合,如果聚合后的条数/100000>0.5,则不再聚合
    第三对实际key数据分布预先统计根据实际情况进行调优。
    -举例:
null值较多,分布在一个reduce调优
Select*
from log a
left outer join bmw_users b
on case when a.user_id is null thenconcat(‘dp_hive’,rand() ) else a.user_id end = b.user_id;

再比如做reduce join时关联某些值特别多,我们可以先count采样下,知道有哪几个值特别斜用union all
这些值的单独用mapjoin,再 union 起来

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值