华为如何生成日志_深入理解Kafka服务端之滚动生成新日志段的流程及条件

本文详细分析了Kafka服务端LogSegment的生成流程,从检查日志段文件状态开始,通过计算新日志段的起始偏移量,创建新的.log文件,到更新LEO和调度异步刷写等步骤。同时,探讨了滚动生成新日志段的条件,包括时间等待、日志段容量和索引文件大小等阈值,以及避免磁盘IO压力的策略。
摘要由CSDN通过智能技术生成
一、场景分析     之前提到,Kafka中一个分区对应一个Log对象,每个Log对象下面又划分了多个日志段LogSegment。那么这些日志段的划分策略是什么?即满足什么条件时会生成新的日志段,以及生成新日志段的流程是什么样的。这篇来进行详细的分析。 二、图示说明 滚动生成新的日志段流程:

b99dae6afe00db38319968bad3cd3c31.png

三、源码分析

    1. 新的日志段是如何生成的。

    由于LogSegment是由Log管理的,所以按理说,控制生成新的LogSegment的方法就应该在Log类中。这个方法就是roll()方法,它的注释如下:

* Roll the log over to a new active segment starting with the current logEndOffset.* This will trim the index to the exact size of the number of entries it currently contains.
大概翻译就是:     滚动生成新的active日志段,以当前的LogEndOffset作为日志段的起始偏移量。     这个方法将裁剪索引文件至实际大小。(具体为何裁剪索引文件可以看《深入理解Kafka服务端之索引文件及mmap内存映射 》)
这里要重点关注一个概念:  LogEndOffset,简称LEO。是Kafka服务端十分重要的一个概念,后面还会多次提及。  表示的是下一条待写入消息的偏移量。

生成新日志段的流程分析:

def roll(expectedNextOffset: Option[Long] = None): LogSegment = {
      maybeHandleIOException(s"Error while rolling log segment for $topicPartition in dir ${dir.getParent}") {
        //记录开始时间    val start = time.hiResClockMs()    lock synchronized {
          //检查索引文件的内存映射是否关闭      checkIfMemoryMappedBufferClosed()      //计算新日志段文件的起始偏移量baseOffset      val newOffset = math.max(expectedNextOffset.getOrElse(0L), logEndOffset)      //生成新的日志文件      val logFile = Log.logFile(dir, newOffset)      //如果newOffset对应的日志段文件已存在      if (segments.containsKey(newOffset)) {
            //如果active日志段的起始偏移量和上面计算的起始偏移量相同,且active日志段的日志文件大小为0,则删除active日志段        if (activeSegment.baseOffset == newOffset && activeSegment.size == 0) {
              warn(s"Trying to roll a new log segment with start offset $newOffset " +               s"=max(provided offset = $expectedNextOffset, LEO = $logEndOffset) while it already " +               s"exists and is active with size 0. Size of time index: ${activeSegment.timeIndex.entries}," +               s" size of offset index: ${activeSegment.offsetIndex.entries}.")          //异步删除active日志段(先标记为.delete)          deleteSegment(activeSegment)        } else {
              //如果日志段文件已存在且不是active,则抛异常          throw new KafkaException(s"Trying to roll a new log segment for topic partition $topicPartition with start offset $newOffset" +                                   s" =max(provided offset = $expectedNextOffset, LEO = $logEndOffset) while it already exists. Existing " +             
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值