Kafka日志模块(五):Log 基本操作之关键位移值管理

        Log 对象维护了一些关键位移值数据,比如 Log Start Offset、LEO 等。Log 对象中的 LEO 永远指向下一条待插入消息,也就是说,LEO 值上面是没有消息的。

@volatile private var nextOffsetMetadata: LogOffsetMetadata = _

在之前说过的log初始化的时候,源码会加载所有日志段对象,并由此计算出当前 Log 的下一条消息位移值。

locally {
  val startMs = time.milliseconds
  // 创建日志路径,保存Log对象磁盘文件
  Files.createDirectories(dir.toPath)
  // 初始化Leader Epoch缓存
  initializeLeaderEpochCache()
  // 加载所有日志段对象,并返回该Log对象下一条消息的位移值
  val nextOffset = loadSegments()
  // 初始化LEO元数据对象,LEO值为上一步获取的位移值,起始位移值是Active Segment的起始位移值,日志段大小是Active Segment的大小
  nextOffsetMetadata = LogOffsetMetadata(nextOffset, activeSegment.baseOffset, activeSegment.size)

  // 更新Leader Epoch缓存,去除LEO值之上的所有无效缓存项 
  leaderEpochCache.foreach(
    _.truncateFromEnd(nextOffsetMetadata.messageOffset))
  ......
}

单独定义了更新 LEO 的 updateLogEndOffset 方法

  private def updateLogEndOffset(offset: Long): Unit = {
    nextOffsetMetadata = LogOffsetMetadata(offset, activeSegment.baseOffset, activeSegment.size)

    // Update the high watermark in case it has gotten ahead of the log end offset following a truncation
    // or if a new segment has been rolled and the offset metadata needs to be updated.
    // 一个新的segments被创建处理,要更新HW
    if (highWatermark >= offset) {
      updateHighWatermarkMetadata(nextOffsetMetadata)
    }

    if (this.recoveryPoint > offset) {
      this.recoveryPoint = offset
    }
  }

        LEO 对象被更新的时机有 4 个。

1. Log 对象初始化时:当 Log 对象初始化时,我们必须要创建一个 LEO 对象,并对其进行初始化。

2. 写入新消息时:这个最容易理解。以上面的图为例,当不断向 Log 对象插入新消息时,LEO 值就像一个指针一样,需要不停地向右移动,也就是不断地增加。

3. Log 对象发生日志切分(Log Roll)时:创建一个全新的日志段对象,并且关闭当前写入的日志段对象。这通常发生在当前日志段对象已满的时候。一旦发生日志切分,说明 Log 对象切换了 Active Segment,那么,LEO 中的起始位移值和段大小数据都要被更新,因此,在进行这一步操作时,我们必须要更新 LEO 对象。

4. 日志截断(Log Truncation)时:这个也是显而易见的。日志中的部分消息被删除了,自然可能导致 LEO 值发生变化,从而要更新 LEO 对象。

        Log Start Offset被更新的时机有 5 个。
 
1. Log 对象初始化时:和 LEO 类似,Log 对象初始化时要给 Log Start Offset 赋值,一般是将第一个日志段的起始位移值赋值给它。
 
2. 日志截断时:同理,一旦日志中的部分消息被删除,可能会导致 Log Start Offset 发生变化,因此有必要更新该值。
 
3. Follower 副本同步时:一旦 Leader 副本的 Log 对象的 Log Start Offset 值发生变化。为了维持和 Leader 副本的一致性,Follower 副本也需要尝试去更新该值。
 
4. 删除日志段时:这个和日志截断是类似的。凡是涉及消息删除的操作都有可能导致 Log Start Offset 值的变化。
 
5. 删除消息时:严格来说,这个更新时机有点本末倒置了。在 Kafka 中,删除消息就是通过抬高 Log Start Offset 值来实现的,因此,删除消息时必须要更新该值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值