Storm 重启排查(续)
此文主要接 storm worker异常重启原因排查汇总 这篇文章继续描述。上文中的第三点大概描述了一下造成重启的原因,这次又有一次详细的排查过程和思路供参考。
一、背景
今天,另一个同事反应,我们的一个任务在早上4点到10点之间会有严重的数据丢失,而这个时间点与一个数据导入任务的时间点是吻合的,经查看此任务的的数据量有将近5亿。因此,在这段时间内造成的影响还是挺大的,毕竟都是线上数据。
因此,又重新启动此任务,可以观察到,数据丢失率确实增高,因此,就查看各个woker的状态如何,发现了有一台机器woker重启,开始了这个问题的排查过程。
(注:此结果还无法反馈数据丢失的具体原因,仅仅是针对woker重启的现象排查过程进行记录)
二、排查过程
1、是否有明显异常
这个问题的排查请参考storm worker异常重启原因排查汇总 中的1和2两点。经查看,可以知道不是这两种原因导致的。
2、开启打怪模式
(1) 首先查看supervisor的日志文件,发现重启的原因是由于心跳timeout。
但是supervisor检测worker的心跳,是在本机的一个心跳文件检测的,不涉及到网络的问题,因此,就开始怀疑是本物理机有问题。
(2) 查看机器的各个指标
首先查看机器的整体监控,可以看到该机器的CPU整理利用率 80%, 内存整体利用率88%,CPU的负载持续很高,并且不稳定,见下图:
然后通过top命令,查看各个进程的内存和CPU情况,如下:
(3)根据2中观察到的结果,具体查看占用CPU高的线程在做什么事情,看到是GC线程把CPU打满了。
注:
1) supervisor检测worker心跳,是通过检测本地的心跳文件来完成的,心跳文件的路径为:{storm.local.dir}/supervisor/localstate
2) 查看各个线程在做什么的相关命令为:
jstack :查看各个线程的堆栈
ps -mp pid -o THREAD,tid,time :查看各线程的CPU使用
printf "%x\n" pid :把十进制线程id转成16进制,去jstack结果中,查看线程堆栈
刚开始怀疑GC是诱因,但是其实最后判定,GC是结果,因为改机整体利用率太高,导致频繁的进行GC,最终导致了恶性循环。
因此,到这里基本上可以判定,本机负载太高导致worker无法及时更新心跳文件,导致supervisor判定其timeout,开始重启worker。
(4)为什么此机器负载较高?
经过查看,因为本机内存为128G,storm配置中设置了 supervisor.slots.ports的数量为40个,并且真正的运行的worker也为40个。而且,虽然worker启动限制最大内存为2G,但是实际worker占用内存却很多超过了2G。 这是一个疑点,我还没有搞清楚。
另外一点,发现有些机器也设置了最大40个worker,但是其实只启动了20个,因此,这就涉及到了storm分配资源的问题了。对于单个topology来说,storm会尽可能的把其worker分配到单台机器上面,但是并没有考虑到机器的负载。
总结:对于不容易看出错误的worker重启,基本上是由于机器问题导致的,可以查看机器负载如何。