Hadoop MapReduce/Hive 数据倾斜完整排查

数据倾斜本质:Shuffle 阶段,某一个 / 某几个 Reduce 接收的数据量远大于其他 Reduce,任务长时间卡在这几个 Reduce,出现长尾任务,严重时 OOM

一、现象识别(怎么判断发生倾斜)

现象 1:YARN 页面观察

  1. 大部分 Reduce 任务快速跑完,少数几个 Reduce 进度卡在 99%、100% 很久不动,耗时远高于其余 task。
  2. 看 Counters → Reduce input records 计数器:
    • 绝大多数 reduce 输入记录数几万,个别 reduce 几百万、上千万条,数量差距几十上百倍。

✔ Counter 只能确认倾斜发生,看不到具体热点 key

现象 2:日志异常

  • 慢 Reduce 的 Container 日志:频繁 Full GC、OOM、内存溢出报错。
  • Task 日志大量重复相同 key。

现象 3:Hive SQL 表现

  • Map 阶段很快结束,MR Job 卡在 Reduce 阶段,任务跑很久不结束。

二、完整排查步骤

  1. 确认是否发生数据倾斜 :YARN UI 打开对应 Job → Counters 标签,查看 Reduce input records。如果个别 reduce 输入记录数远超其他,确认倾斜。

  2. 定位出有问题的 Reduce Task:进入 Job 的 Attempts/Container 列表,找到执行时间极长、进度停滞的 Reduce 任务,复制该 Container ID。

  3. 下载该 Reduce Task 日志,定位热点 Key :打开该 container 日志,搜索 key 相关打印,找到数量爆炸的热点 key 具体值

    注意:MR 原生计数器不保存 key,日志才能拿到真实 key。

  4. 分析倾斜产生的根因 :拿到热点 key 后分析业务:

    • 大量 null、空字符串 key;
    • 某个业务 key 数据量异常大;
    • join 的一侧存在大量重复 key;
    • 分区函数不合理。
  5. 区分倾斜类型

    • ✅ Group By / 聚合倾斜:group by 的某个 key 值数据量巨大
    • ✅ Join 倾斜:join 的其中一张表有大量重复 join key
    • ✅ Count Distinct 倾斜:去重,相同 key 过多

三、常见倾斜分类 + Hive 解决方案

类型 1:group by 数据倾斜(聚合倾斜)

场景:group by 某个字段,某个 key 行数特别多。现象:reduce 输入记录数严重不均。

优化方案

  1. 开启 map 端预聚合

    set hive.map.aggr=true; --map端局部聚合
    set hive.groupby.mapaggr.checkinterval=100000;

  2. 开启倾斜自动处理

    set hive.groupby.skewindata=true;

原理:拆两轮 MR。第一轮随机打散做局部聚合;第二轮再汇总。代价:多一轮 MR,消耗资源。

类型 2:Join 数据倾斜

场景:大表 join 大表,join key 存在热点;或者大表 join 小表但 key 热点。

方案 A:小表侧 mapjoin(小表全部加载到 map 内存,无 shuffle,不走 reduce join)

复制代码
set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=25000000;

适用:一张表很小,另一张大表。

方案 B:热点 key 打散(大表 join 大表,存在热点 key)

思路:

  • 对大表热点 key,拼接随机前缀打散,分到不同 reduce;
  • 另外一张表,把热点 key 复制 N 份,带上对应随机前缀;再做 join。

适合:join 的热点 key 只是少数,其他 key 正常。

方案 C:分离热点 key 单独处理

把热点 key 过滤出来单独做 join;非热点 key 正常 join;最后把两部分结果 union all 合并。

类型 3:null / 空值 key 导致倾斜

场景:大量记录 join/group by 的 key 为 null、空字符串,全部 hash 到同一个 reduce。优化:

  1. 过滤掉 null(业务允许情况下);

  2. null 值给随机前缀打散,不让全部落到同一个 reduce。

    -- 示例,null打上随机数
    case when key is null then concat('rand_',rand()) else key end as join_key

类型 4:count distinct 去重倾斜

count (distinct id),同一个 id 数量巨大,shuffle 全部落到同一个 reduce。优化:先 group by 去重,再 count。

复制代码
--倾斜写法
select count(distinct id) from table;

--优化改写
select count(*) from (select id from table group by id) t;

四、参数

复制代码
--开启mapjoin
set hive.auto.convert.join=true;
--groupby倾斜优化
set hive.groupby.skewindata=true;
--map端聚合
set hive.map.aggr=true;
--倾斜join自动优化(hive新版本)
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000;

五、精简版

排查数据倾斜,首先看 YARN 任务 Counter 中 Reduce-input-records,观察每个 reduce 输入数据量,如果少数 reduce 数据量远大于其他,确认发生数据倾斜。然后找到耗时很长的那个 reduce 对应的 Container,下载 task 日志,从中定位热点 key。

倾斜主要分 groupby 聚合倾斜、join 倾斜、null 值倾斜、count distinct 倾斜。优化手段有 map 端预聚合、skewindata 开启两轮 MR、mapjoin、热点 key 打散、分离热点单独处理、改写 count distinct。

六、容易踩考点

  1. Counter 只能发现倾斜,不能直接看到热点 key,热点 key 要去 container 日志找
  2. 数据倾斜发生在Shuffle 阶段
  3. hive.groupby.skewindata=true 会把 group by 拆两轮 MR,会增加任务耗时,不要无脑开启。
  4. mapjoin 没有 shuffle 阶段,完全规避 join 倾斜,但受内存限制,只适合小表。
相关推荐
Gl�ria2 小时前
Hadoop Hive 和 YARN 的关系
数据仓库·hive·hadoop
pjj198541 天前
Hadoop-python中使用大数据
大数据·hadoop·python
计算机源码社2 天前
分享一个基于大数据的跨平台内容生态画像与互动等级分析系统,基于Hadoop+Spark的社交媒体互动数据可视化大屏分析
大数据·hadoop·python·机器学习·数据挖掘·spark·毕业设计
BYSJMG2 天前
计算机毕设选题做什么好?基于大数据的用户健身行为数据分析与可视化系统,Hadoop+Spark处理
大数据·人工智能·hadoop·数据分析·spark·课程设计
ha_lydms3 天前
HDFS 简介
大数据·hadoop·hdfs·yarn·调度·aliyun·计算
2601_962298093 天前
零基础学大数据分析全栈
hadoop·python·spark·实战·大数据分析
ha_lydms3 天前
HDFS的读写流程
大数据·hadoop·hdfs·mapreduce·yarn·maxcompute·odps
BYSJMG4 天前
大数据毕业设计选题推荐:基于大数据的全球气温历史演变分析与可视化,用Hadoop+Spark处理
大数据·hadoop·分布式·信息可视化·spark·kmeans·课程设计
fastjson_4 天前
Hive 自定义函数
数据仓库·hive·hadoop