记一次Spark任务卡住的问题排查

上个版本因为一个需求需要在原有任务上加两个字段,很简单的一件事,想都没多想,直接在 select 后面加上了两个字段,类似于:

insert overwrite table tbl_test partition (undr)
select a.*,
       b.app,   -- 新增字段
       c.date   -- 新增字段
from a
where 
join b on a.id = b.aid
left join c on a.id = c.aid
left join d on a.id = d.aid
left join e on a.id = e.aid
left join f on a.id = f.aid

加完之后就上到测试环境去跑了,想着先把基表数据跑出来再做后面的需求。这时候问题出现了,原本基本两个小时跑完的任务,这次跑了五六个小时都没跑完,于是开始找问题。

最初没深究问题,直接 yarn application -kill application... kill 掉了,因为 kill 掉,所以调度平台收到了任务报错的消息,就自动下发了,我没注意到调度平台会自动下发,于是 kill 掉之后立即手动下发。等我回来排查问题的时候,发现下发的任务都在排队,因为有一个任务在跑,把资源都占用完了。

重复下发了几次,都是超过四五个小时没结束,甚至头一天下班下发的任务,第二天上班还没跑完,感觉不太对劲,开始仔细排查问题。

查看日志每次都卡在 stage8,看 DAG 图,应该是最后一个 stage 了,流程比较复杂。怀疑是加的两个字段有问题,于是将两个字段写死成 ‘’ ,结果还是跑不出结果。

因为不是专业搞大数据的,又临近版本日,只好提单向大数据组的同事求助。结果令人失望,一个接单的女同事,都没看我的 SQL 直接发给我几个优化参数,说加上再跑试试。。原本以为他们能具体问题具体分析的。加上了几个常见的优化参数还是不行。

确实没办法,只能先上到生产环境,生产环境资源多,历史记录显示基本50分钟左右就能跑完。周末发版之后让运营帮忙下发了任务,持续观察,结果过了快一天也没有跑完,资源占满还导致一些重要的任务被卡住了好几个小时,开始报警。无奈只能强行 kill 掉。

让大数据组的同事拉了集群节点的进程、内存、CPU资源占用情况,发现内存占用很低,CPU 占用几乎达到100%。

感觉很诡异了,也找不到问题所在,有点束手无策。前两天下班后和组里的一位对大数据比较熟悉的同事讨论,我正打算把这个表新加的字段删除,直接把任务恢复到改动之前去试试的,这才看到 insert 语句后面跟了动态分区!partition(undr)!!我想我知道问题在哪里了,这个语句有动态分区,原本的 SQL 里最后一个字段是年月,做了分区字段,而我加上了这两个字段之后,现在 SQL 在用客户号分区,而这个 SQL 查出来的客户号有上亿的数据,真相就在这里了!于是开始验证我的想法,先查看表机构,确定原本的最后一个字段就是分区字段;dfs -ls 语句查看表里的目录,确实正是用客户号分的区,分区目录不计其数。确定就是分区导致的问题后,将新增加的两个字段调整到分区字段之前,重新部署、下发任务。不出预料,很顺利的 50 分钟就成功结束,困扰两个星期的问题最终还是靠自己解决。