线上ElasticJob堵塞问题排查

[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/Bug-Log-Optimization/elasticJob-bug-fix.html


背景

刚进新公司3天正逢双十一,领导生产补数出问题了,补数速度不稳定时快时慢,百万条数据补了好几个小时,之前都是几分钟搞定的,导致通了个宵;
早上我早到公司,领导截了个数据库的图给我,说交给我来看,然后刚通宵完的他就去开会汇报去了。。。我还没来得及熟悉环境,就被扔到了火坑里了,压力山大。。。
具体的过程没记录,这里只能凭回忆记录下了

问题描述

给我的截图大概长这样:

数据库分库号需要补数的运单数量
分库012345
分库10
分库20
***
分库310
分库320
分库325w
分库334w
分库348w
***
分库1288w

知道的太少,跟同事了解业务,其实补数就是重推数据,把需要重推的单号记入表中,然后通过ElasticJob定时任务消费表中数据,实现重推数据

问题分析

没用过ElasticJob这类定时任务组件,先通过现象分析,发现分库32-128的数据都是好几w条,而且分库0-31的数据都是0,这就很奇怪了;
查看配置sharding-total-count=16,看现象猜测是只有一个分片在跑,且一轮跑16个分片,跑到第二轮;

问题分析

因为实在不熟悉定时任务组件逻辑,还是得去分析源码看原因才好解决问题;

看了下配置

1
2
streaming-process=true 
sharding-total-count=16

streaming-process=true 代表流式处理;
sharding-total-count=16 代表分片总数;
结合问题,猜测是只有一个分片在消费,且一轮跑16个分片,跑到第二轮;

查看流式计算源码发现流式计算逻辑其实是:

  1. 各个节点接收任务
  2. 切分16个分片,当前节点只消费一个分片
  3. 所有分片处理完后,分发触发下一(16个分片)次的任务
    img.png

而我们系统对每个分片的处理实际上也是流式的,大致代码如下:

1
2
3
while(fetchData()){
processData()
}

fetchData()每次获取200条数据,如果有数据就进行重推,直到结束;

结论

那么问题就很明显了,研发人员把重推任务设置为流式处理,但是每次重推只处理200条数据,导致每个分片处理完后,分发下一轮任务;
但是在第二轮任务因为这某个节点分片数据量很大,导致其他节点早就处理完了,而这个节点的数据迟迟处理不完,任务一直结束不了一直在等待这个分片的完成,消费效率滑坡;

处理方案

  1. 流式计算加入超时机制,每个分片最多只能处理一段时间,超过后就结束本次任务,分发下一轮任务
  2. 放弃流式计算,缩短定时任务间隔

这里推荐方案1,不过最终团队选择方案2,实现比较简单。。。


作者

神奇宝贝大师

发布于

2019-12-12

更新于

2019-12-14

许可协议

评论