spark historyserver启动后,会启动一个定时任务线程,用来解析spark.eventLog.dir配置目录下spark应用生成的eventLog日志文件。
解析日志的线程启动后,会扫描spark.eventLog.dir目录下的所有文件,检查此目录下是否有新生成的文件和大小有增加的文件,过滤筛
选出需要解析的eventLog日志文件列表,之后对每一个eventLog文件都会开启一个线程去解析,这些线程会放在一个线程池中统一调
度,线程池大小由spark.history.fs.numReplayThreads配置决定,默认时按服务器cpu核数动态调整(cpu核数/4)。
从historyserver解析eventLog的流程可知,当spark.eventLog.dir目录下有新生成或大小有增加的日志文件时,historyserver就会对
其进行解析。但是在本次问题中historyserver因oom宕机,由保活机制自动拉起运行6分钟后,就没有再刷新日志replay信息。出现这种
情况有以下两个可能的原因:
(1)spark.eventLog.dir配置目录下没有新文件或大小有增加的文件
(2)Eventlog文件数过多,单个eventLog过大,解析replay时间过长导致解析线程卡住
对于第一种情况,和现场确认过,当时是有spark应用提交的,且eventlog下也有文件生成,可以排除。现在只有第二种情况会导致
historyserver日志不刷新,但是目前只有日志,不足以排查解析线程卡在哪里。
结论
因为spark historyserver日志卡住不刷新了,无法从日志排查出日志不刷新的真正原因。所以建议再持续观察一段时间,
观察historyserver日志中eventlog的reply回放情况。若再次出现日志不刷新时,通过如下方法排查。
(1)使用jstack打印出该进程的堆栈信息。
mr用户查看historyserver的进程号
su - mr
jps
使用mr用户打印此进程的堆栈信息,通过堆栈查看log-replay线程是否一处于RUNNABLE状态。
jstack -l pid号 > jstack.log
jstack内容:xxx
(2)jmap导出内存镜像
使用mr用户执行如下命令导出内存镜像
jmap -dump:live,file=hs.hprof ${historyserver_pid}
在本地将镜像文件导入到jvisualvm中,在类界面找到 LinkedBlockingQueue,点进去,在字段中找到count字段,点开可以查看value对应
的值,此值为排队等待执行的线程数据。