关于kafka:kafka日志清理引发的core-dump问题

53次阅读

共计 1914 个字符,预计需要花费 5 分钟才能阅读完成。

原文链接:http://fxbing.github.io/2021/…

团队开发了 kafka on hdfs 的性能,用以将 kafka 数据存储在 hdfs 上,然而在应用的过程中发现,有机器呈现 core dump 景象。

本文基于 kafka 版本 0.10.2

排查过程

一、排查 core dump 文件

因为呈现了屡次 core dump 问题,所以首先须要从 core dump 文件中进行剖析。从 core dump 文件能够看出,以下几个问题:

  1. 挂掉的线程名称都是 hdfs 相干的,所以揣测与 hdfs 相干性能无关
  2. 挂掉的代码地位都与 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 文件,而后再提早肯定工夫进行删除。

总结

  1. 本次问题的呈现属于偶发景象,只有在 kafka consumer 生产 lag,读取行将被删除的日志时才有可能会产生。
  2. core dump 问题剖析的过程中须要通过多个 case 的类似点来剖析问题。

正文完
 0