**现象:**Hive 提交 SQL 之后,任务长时间不动,Map 或者 Reduce 停在某个百分比不动,不报错、不失败,就是卡住。
底层跑 Hive on MR / Tez / Spark‑on‑YARN,绝大多数问题体现在 YARN 任务层面。
一、第一步:定位卡在哪一层
- Hive 客户端看:是否已经提交到 YARN。
- 如果还没提交:卡在编译、解析、获取元数据(元数据库 MySQL 卡顿、NameNode 卡顿)
- 如果已经提交 YARN:去 Yarn UI 看对应 Job。看是 Map 阶段卡,还是 Reduce 阶段卡。
- YARN UI 观察 Job 状态
- Map 进度不动
- Reduce 卡在 0%、33%、99%、100%(99% 最典型,大概率数据倾斜)
- Task 大量 Pending,不启动
场景 1:任务已经提交 YARN,Reduce 卡在 99%
最高频:数据倾斜
现象:大部分 reduce 迅速跑完,少数几个 reduce 长时间 RUNNING,Shuffle Read/Reduce input records 巨大。
排查:
- Job→Counters 看
Reduce input records,确认个别 reduce 数据量异常大。 - 找到慢 Reduce Task,进入 Container 看日志:大量 Full GC、OOM 风险。
处理:
- 紧急:可以 kill 掉这个 hive 任务
yarn application -kill application_xxx - 定位热点 key:task 日志 + 源表统计 key 分布;区分脏数据倾斜 / 业务热点倾斜。
- 优化手段:过滤脏 key、加盐打散、开启
hive.groupby.skewindata=true、mapjoin。
不要单纯加大 reduce 内存,治标不治本。
场景 2:Map 阶段卡住,Map 进度不动
- HDFS 读取慢 / HDFS 故障, NameNode 压力大、DataNode 繁忙、部分块损坏、副本不可读。 看 map task 日志:HDFS 读取超时、block 异常。 检查 HDFS 健康
hdfs fsck /。 - 输入文件存在大量小文件,生成大量 Map Task,map 数量巨多,YARN 资源不够,task 排队 Pending。 处理:输入合并小文件
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; - 数据源文件损坏、权限不足,部分文件无读权限,map task 一直报错重试。看 map task container 日志。
补充:查看小文件方式
1)统计目录下文件总数量(最基础)
# 统计该目录下所有文件(递归)
hdfs dfs -count /user/hive/warehouse/xxx.db/xxx_table
输出格式:目录数 文件数 总字节数 路径
重点看第二个数字,文件数量巨大,大概率存在小文件。
2)筛选小于指定大小的文件(找出小文件)
# 查找 /xxx 下 小于128M 的文件,打印路径+大小
hdfs dfs -ls -R /user/hive/warehouse/xxx.db/xxx_table | awk '$5 < 134217728 {print $5,$8}'
# 查找小于1M的极小文件(高频排查)
hdfs dfs -ls -R /user/hive/warehouse/xxx.db/xxx_table | awk '$5 < 1048576 {print $5,$8}'
缺点:目录超大时
ls -R很慢,不建议在生产根目录直接跑。
3)更高效:hdfs dfsadmin 读取 fsimage(推荐生产大集群)
NameNode 的 fsimage 保存全量元数据,离线统计,不占用 NN 压力
# 下载fsimage
hdfs dfsadmin -fetchImage /tmp/fsimage
# 解析统计小文件数量
hdfs oiv -i /tmp/fsimage -o /tmp/fsimage.txt -p Delimited
awk '$8 < 1048576 {print}' /tmp/fsimage.txt | wc -l
✅ 优点:不压 NameNode,适合全集群统计小文件总量。
4)Hive 表单独统计(数仓场景)
看numFiles字段,分区表可以循环查每个分区的文件数。
-- Hive SQL查看表文件数量
describe formatted 库名.表名;
场景 3:大量 Task Pending,不启动,Map/Reduce 都是 0%
资源不足,YARN 没有可用 Container :YARN 集群资源被别的任务占满,队列资源耗尽,队列最大并发限制。
看 YARN UI,Applications 页面,大量任务处于 PENDING 状态。
排查点:
- 当前队列剩余内存、vcore;
- 是否队列设置了最大并发数;
- 是否有大任务抢占全部资源。
处理:
- kill 掉优先级低的占用资源大的 yarn 应用;
- 调整 hive 任务 map/reduce 数,减少资源申请;
- 提交到资源充足队列。
场景 4:还没有提交 YARN Job,Hive 客户端本身卡住
SQL 在编译阶段,根本没有生成 Job。 常见原因:
- Hive Metastore 元数据库 MySQL 卡顿(元数据查询慢,表多、分区多) 比如查询一张有上万个分区的表,获取分区元数据卡死。
- NameNode 卡顿,获取 HDFS 文件列表慢。
- 执行
select *不 limit,海量数据往客户端输出,客户端网络卡死。
处理:
- 避免不带 limit 的 select *;
- 优化元数据库;分区表尽量裁剪分区;
- 查看 hive metastore 服务状态;
场景 5:卡住,reduce 不断 Full GC,偶尔 OOM
两种可能
- 数据倾斜导致单个 reduce 数据量过大;
- 单条记录 value 巨大(超大 JSON),reduce 堆内存不足。 排查 Counters:
-
如果只有个别 reduce 记录数大:倾斜。
-
如果所有 reduce 记录数差不多:调大 reduce 内存。
set mapreduce.reduce.memory.mb=4096;
set mapreduce.reduce.java.opts=-Xmx3276m;
二、标准排查流程
Hive SQL 卡住,第一步先看任务是否已经提交 YARN。
- 如果还没提交 YARN:说明卡在编译 / 元数据获取。检查 Hive Metastore、NameNode,是否表分区过多;禁止不带 limit 查询全量数据。
- 如果已经提交到 YARN:打开 RM UI 看 job。
- Task 大量 Pending:YARN 队列资源不足,容器申请不到,kill 低优先级任务或者换队列。
- Reduce 卡在 99%,大部分 task 跑完少数很慢:优先怀疑数据倾斜。查看 Counter 的 Reduce‑input‑records 定位异常 reduce,下载 container 日志找热点 key,区分脏数据或者业务热点,做过滤或者打散优化。
- Map 阶段卡住:排查 HDFS 状态,是否大量小文件,开启输入合并;检查文件权限、块损坏。
- 定位问题后可以先用
yarn application‑kill杀掉卡住任务,再做 SQL 参数改写优化。
三、常用应急参数(hive 会话内设置)
--合并小文件输入,减少map数
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
--groupby倾斜处理
set hive.groupby.skewindata=true;
--mapjoin开启
set hive.auto.convert.join=true;
--调整reduce内存
set mapreduce.reduce.memory.mb=4096;
set mapreduce.reduce.java.opts=-Xmx3276m;
四、高频Q&A
- Hive reduce 卡在 99% 一定是数据倾斜吗? 大部分情况是,但不完全。也有可能 shuffle 拉取数据网络慢、节点硬件故障;优先看 Counter 每个 reduce 输入记录数做确认。
- 任务卡住,我直接调大内存行不行? 资源不足 OOM 可以调内存;数据倾斜场景调内存只是临时缓解,热点 key 数据继续增大依然会卡住。
- yarn application -kill 之后,任务会回滚吗? Hive 批处理,任务中途 kill,不会产生脏输出,输出目录不会生成;不会残留部分结果。