为了账号安全,请及时绑定邮箱和手机立即绑定

kafka原理详解之各种offset和checkpoint

每一个分区都是一个顺序的、不可变的消息队列,并且可以持续的添加。分区中的消息都被分配了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。
一个分区在文件系统里存储为一个文件夹。文件夹里包含日志文件和索引文件。其文件名是其包含的offset的最小的条目的offset。
这里写图片描述
这里写图片描述
每个文件是一个segment。
在broker的log存储文件下,除了存储这各个topic的文件夹,还存在这几个checkpoint文件。分别是

  • recovery-point-offset-checkpoint 负责记录topic已经被写入磁盘的offset

  • replication-offset-checkpoint  负责记录已经被复制到别的topic上的文件

__consumer_offsets存储各个topic的offset。但是,他的只有一份。

  • logStartOffset 日志段集合中第一个日志段(segment)的基础位移,也就是这个日志对象的基础位移

  • LogEndOffset 下一条将要被加入到日志的消息的位移

FAQ

Resetting first dirty offset of __consumer_offsets
例如,重复报错信息如下,这显然是清理线程在一直遇到麻烦。

[2018-06-01 13:46:27,156] WARN Resetting first dirty offset of __consumer_offsets-18 to log start offset 44 since the checkpointed offset 42 is invalid. (kafka.log.LogCleanerManager$)1

报错代码段为

    val lastCleanOffset: Option[Long] = lastClean.get(topicPartition)    // If the log segments are abnormally truncated and hence the checkpointed offset is no longer valid;
    // reset to the log starting offset and log the error
    val logStartOffset = log.logSegments.head.baseOffset
    val firstDirtyOffset = {
      val offset = lastCleanOffset.getOrElse(logStartOffset)      if (offset < logStartOffset) {        // don't bother with the warning if compact and delete are enabled.
        if (!isCompactAndDelete(log))
          warn(s"Resetting first dirty offset of ${log.name} to log start offset $logStartOffset since the checkpointed offset $offset is invalid.")
        logStartOffset
      } else {        offset
      }
    }   123456789101112131415

我们可以看见,清理线程试图获取一个partition的最后清理的位移(lastCleanOffset),并同时获取了该partition中现存的所有segment中最小的头部offset(logStartOffset)。但是,却发现lastCleanOffset比logStartOffset还要小。清理线程自然会反应,那些我没有清理的数据跑哪里去了呢?抱怨完后,其将firstDirtyOffset置为logStartOffset,准备下一次从这里开始清理。报错中令人迷惑的checkpointed offset是指lastCleanOffset。

val dirtyNonActiveSegments = log.logSegments(firstDirtyOffset, log.activeSegment.baseOffset)1

kafka本来应该是在完成清理后将lastCleanOffset提高,但是问题在于,如果此时没有可清理的segment,lastCleanOffset也就将保持不变。则线程下一次循环时仍然会遇到这个问题。
解决方案中最快捷的是清空kafka的data目录。或者忽略这个问题,等待大量数据灌入。一旦产生可以清理的segment,这个问题就会解决。

原文出处

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消