数据倾斜,在mapreduce和spark中,都会出现。
MR的任务分为map和reduce,
map的任务和inputsplit相关,inputsplit和block相关,因此map和block个数相关,map个数在小文件时需要优化;
默认情况下,reduce个数是1个,可以把reduce数量增加,这样getPartition
获取的分区数就增加了;也可以通过打散数据。
20220124 今天和一个面试者沟通,他说遇到的倾斜主要有这几种:读倾斜,写倾斜,计算倾斜,数据文件倾斜
什么动作会产生数据倾斜
count、join 、group by
join
通过mapjoin
group by
倾斜原因
本质是key分布不均匀导致
空值
空值问题可能会导致大量数据在同一个分区中;
数据类型不一致
数据类型不一致可以通过cast等解决
业务数据本身
业务数据本身的问题,可以通过增加一个随机数进行group by,引入不相关的随机数将数据打散进行计算,引入新的job,但是不可以影响原本计算。
但是会存在一个新问题,就是随机数会把原数据修改了,因此在此基础之上还有再进行一次map reduce。
数据倾斜是什么 key分布不均匀
同样举一个卡车运西瓜的例子说明。假设现在有 1 万个西瓜,有 100 辆卡车,前 99 辆车每辆车一次只运送 1 个西瓜,剩余 9901 个西瓜都让最后一辆卡车拉。这就是“西瓜倾斜”。
同样,在大数据处理过程中,一个数据处理任务的数据量可能有几百 GB 或者几十 TB,对应会有几百甚至几千台机器一起处理。如果某一台机器被分配的数据量比其他机器多几十倍甚至几百倍,那就是我们说的数据倾斜了。
大量数据集中在某个点上,造成数据热点问题。
这样的情况造成的结果是,数据处理任务结束时间因为其中一台机器而延后,处理效率被严重降低。
避免数据倾斜非常重要,社区考虑 Hive 使用过程中会出现这种情况,进而提供了比较好的解决方案。
比方说group by的时候,大量userid是null
hive 配置
现在,仅仅需要你配置如下参数分两部分进行。
第一部分:有些聚合可以先在 Map 端进行,然后进入 Reduce 端,这时数据量会小很多。我们再得出最终结果即可。
set hive.map.aggr=true; — 开启Map端聚合参数设置
set hive.grouby.mapaggr.checkinterval=100000; — 在Map端进行聚合操作的条目数目
第二部分:如下参数将会添加一个 MapReduce 任务,目的就是让数据平均分配到各个 reduce 上,这样基本能解决数据倾斜问题。
set hive.groupby.skewindata = true; — 有数据倾斜的时候进行负载均衡(默认是false)
mapjoin
或者,好像使用/+mapjoin(a)/也可以解决倾斜的问题
Select /*+mapjoin(a)*/ t1.city,t2.type,count(t1.imei) as uv
From
(select imei,city,count(1) as pv from a where imei != ‘’ group by imei,city)t1
Join
(select imei,type,count(1) as pv from a where imei != ‘’ group by imei,type) t2
On t1.imei=t2.imei
Group by t1.city,t2.type
mapjoin 会把小表全部加载到内存中,这里是mapjoin(a)会把表a加载到内存中。
上面通过实例解释了 Hive 进行数据统计中,为什么会遇到数据倾斜,以及如何解决数据倾斜。最后我们来分享下 Hive 如何合理控制 map 和 reduce 数量来优化数据处理效率。
数据量大不可怕,数据倾斜才可怕。
数据倾斜的现象
大部分task都非常快速处理完成,只有极少数的task处理特别慢
在Spark中,可以在UI的job/stage/task进行查看
Spark/Hive作业平常没问题 突然发生OOM
数据突然上量了,需要具备自适应能力