原文链接:http://fxbing.github.io/2021/...
团队开发了kafka on hdfs的性能,用以将kafka数据存储在hdfs上,然而在应用的过程中发现,有机器呈现core dump景象。
本文基于kafka版本0.10.2
排查过程
一、排查core dump文件
因为呈现了屡次core dump问题,所以首先须要从core dump文件中进行剖析。从core dump文件能够看出,以下几个问题:
- 挂掉的线程名称都是hdfs相干的,所以揣测与hdfs相干性能无关
- 挂掉的代码地位都与index读取逻辑无关,所以揣测和index清理逻辑无关
二、剖析代码
剖析kafka本地日志删除的代码发现,本地日志删除通过asyncDeleteSegment
进行,asyncDeleteSegment
进行删除时首先会rename本地日志文件和索引文件,而后提早肯定工夫进行删除。
/** a file that is scheduled to be deleted */ val DeletedFileSuffix = ".deleted"/** * Perform an asynchronous delete on the given file if it exists (otherwise do nothing) * * @throws KafkaStorageException if the file can't be renamed and still exists */ private def asyncDeleteSegment(segment: LogSegment) { segment.changeFileSuffixes("", Log.DeletedFileSuffix) def deleteSeg() { info("Deleting segment %d from log %s.".format(segment.baseOffset, name)) segment.delete() } scheduler.schedule("delete-file", deleteSeg, delay = config.fileDeleteDelayMs) }/** * Change the suffix for the index and log file for this log segment */ def changeFileSuffixes(oldSuffix: String, newSuffix: String) { def kafkaStorageException(fileType: String, e: IOException) = new KafkaStorageException(s"Failed to change the $fileType file suffix from $oldSuffix to $newSuffix for log segment $baseOffset", e) try log.renameTo(new File(CoreUtils.replaceSuffix(log.file.getPath, oldSuffix, newSuffix))) catch { case e: IOException => throw kafkaStorageException("log", e) } try index.renameTo(new File(CoreUtils.replaceSuffix(index.file.getPath, oldSuffix, newSuffix))) catch { case e: IOException => throw kafkaStorageException("index", e) } try timeIndex.renameTo(new File(CoreUtils.replaceSuffix(timeIndex.file.getPath, oldSuffix, newSuffix))) catch { case e: IOException => throw kafkaStorageException("timeindex", e) } }
然而在hdfs相干的清理性能中,间接进行的日志清理而没有rename和delay操作,所以揣测清理日志和索引时,如果文件仍被读取,强行删除会导致core dump。
三、测试论断
编写单测,本地索引lookup过程中强行删除索引文件,的确呈现了core dump景象。
解决方案
仿照本地日志的清理策略,在hdfs相干的逻辑中,不间接删除文件,而是先rename文件,而后再提早肯定工夫进行删除。
总结
- 本次问题的呈现属于偶发景象,只有在kafka consumer生产lag,读取行将被删除的日志时才有可能会产生。
- core dump问题剖析的过程中须要通过多个case的类似点来剖析问题。