数据倾斜,在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。

IMG_20210427_091644.png

数据倾斜是什么 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)/也可以解决倾斜的问题

  1. Select /*+mapjoin(a)*/ t1.city,t2.type,count(t1.imei) as uv
  2. From
  3. select imei,city,count(1) as pv from a where imei != ‘’ group by imei,cityt1
  4. Join
  5. select imei,type,count(1) as pv from a where imei != ‘’ group by imei,type t2
  6. On t1.imei=t2.imei
  7. Group by t1.city,t2.type

mapjoin 会把小表全部加载到内存中,这里是mapjoin(a)会把表a加载到内存中。

上面通过实例解释了 Hive 进行数据统计中,为什么会遇到数据倾斜,以及如何解决数据倾斜。最后我们来分享下 Hive 如何合理控制 map 和 reduce 数量来优化数据处理效率。

数据量大不可怕,数据倾斜才可怕。

数据倾斜的现象

大部分task都非常快速处理完成,只有极少数的task处理特别慢

在Spark中,可以在UI的job/stage/task进行查看

Spark/Hive作业平常没问题 突然发生OOM

数据突然上量了,需要具备自适应能力