记一次线上任务堆积问题排查

2018/07/20   

0. 背景

KingSight是一款自助报表配置服务系统。用户可以连接各方数据源,用sql语句获取所需数据并配置出想要的数据报表,还可以将最终的报表分享嵌入至第三方系统;实现原理是将sql查询语句存储为任务单元,通过使用定时任务生成中间数据缓存表或者在线实时查询。

后面均已KS代指KingSight。

通过上面的简单介绍,相比你已经大概了解到KS是用来做什么的了。那接下来我们简要说明下KS执行流程:

  • 1) KS每天1点半开始陆续提交各种类型的报表任务SQL,会根据报表配置信息,生成对应的任务信息,把任务信息发送到Redis,把任务ID放到Kafka中进行排队

  • 2) Kafka消费端接收到任务后,通过任务ID从Redis中获取到任务信息,提交给任务管理器进行调度

  • 3)任务管理器会根据任务的类型(MySQL/Hive/Druid等)调度到相应的任务解析器消费的内存优先级队列(此时会根据任务优先级自动排序)中

  • 4)任务解析器每次从对应优先级队列中拿到任务后,会做几件事情:
    • 4.1)申请数据库连接token
    • 4.2)拿到token,则调用查询服务,将SQL任务转交给查询模块去执行
    • 4.3)如果没有拿到token,则会延时3秒到优先级队列里面继续排队
  • 5)查询模块接收到任务后,开始提交任务给对应的数据库集群端,并监听任务执行情况

  • 6)查询结束后,会将查询结果集均分为每份10000条记录转交给数据处理线程,生成入库SQL

  • 7)数据存储站接收到入库SQL后会在保证数据唯一性的情况下进行入库操作

  • 8)任务完成

而当前遇到的问题是什么呢?没有异常,没有报错的情况,也没有任务卡住,但是就是任务执行缓慢,平时下午6点任务已经全部执行完毕了,但是最近到晚上10点也没有完成的意思,不知道KS是不是身体欠安,有罢工的打算?

1. 定位问题

1.1 检查是否有CPU或内存过高现象

  • 1)通过ps命令或者jps命令拿到应用的PID

  • 2)通过top -p PID命令将这个进程的CPU以及内存等使用率显示出来进行观察

    • 2.1)如果存在CPU使用率高的情况,通过top -Hp PID将该进程的线程显示出来,输入大写P可以将线程按照CPU使用比例排序
      • 2.1.1)一旦发现某些线程CPU使用率很高,则通过jstack PID > PID.log将线程栈dump到日志文件中,然后拿16进制的线程ID去日志文件中查看线程快照。如果查看不便,可以把日志文件上传到 http://fastthread.io/ 网站进行可视化分析
    • 2.2)如果存在内存使用率高的情况,通过jmap -histo:live PID将该应用中对象占用字节数情况显示出来,这样我们就可以知道是哪个对象占用率最高,然后再去排查对应的代码,查看是否有内存泄漏情况

发现一切正常,我们继续往后……

1.2 检查各组件是否有不正常现象

  • 1)首先通过查看KS任务端日志是否有异常情况,是否正常消费Kakfa数据,是否正常和Redis进行连接通信

  • 2)检查Kafka是否有异常情况

  • 3)检查Redis是否有异常情况

  • 4)KS后台RDS缓存库是否存在问题等

按照上述步骤排查,发现是因为RDS内存太小才只有4GB,导致数据存储站写入过慢,使得入库数据堆积,进而影响了上一环节,以此类推,层层恶化,最终导致任务严重堆积。

所以,得出结论后,紧急让运维同学帮忙扩容,然后回去补上工单,果然效果显著,任务执行速度快速提升。

其实troubleshooting的过程并没有我表述出来的这么简单,期间也因为焦急而忽略掉了运维同学给出的KS RDS慢查询告警信息,而去做了查询索引方面的优化,虽然也有一定缓解,但是治标不治本。从接收到RDS告警信息开始,我其实就应该把RDS的内存、CPU以及QPS等重视起来的。看来还是经验不足所致!

Summary

  • 1)要在不断的解决线上问题中,积累经验,形成排查问题的过程系统化,这样有助于快速去定位问题

  • 2)定位问题期间,不要忽略任何一个有效信息,存在即合理

  • 3)监控很重要,可以给你提供第一手现场状态信息


一个正在技术专家成长道路上不断努力前进的程序员

(转载本站文章请注明作者和出处 buildupchao

Post Directory