博客
关于我
kafka日志存储(五):LogSegment
阅读量:250 次
发布时间:2019-03-01

本文共 3132 字,大约阅读时间需要 10 分钟。

为了防止Log文件过大,Log文件会被切分成多个日志文件,每个日志文件对应一个LogSegment。在LogSegment中,封装了FileMessageSet和OffsetIndex对象。LogSegment类的实现如下:

LogSegment类结构

class LogSegment(val log: FileMessageSet,                 val index: OffsetIndex,                 val baseOffset: Long,                 val indexIntervalBytes: Int,                 val rollJitterMs: Long,                 time: Time) extends Logging {    private var bytesSinceLastIndexEntry = 0  var created: Long = time.milliseconds}

append方法

def append(offset: Long, messages: ByteBufferMessageSet): Unit = {  if (messages.sizeInBytes > 0) {    trace("Inserting %d bytes at offset %d at position %d".format(      messages.sizeInBytes, offset, log.sizeInBytes()))        if (bytesSinceLastIndexEntry > indexIntervalBytes) {      index.append(offset, log.sizeInBytes())      this.bytesSinceLastIndexEntry = 0    }        log.append(messages)    this.bytesSinceLastIndexEntry += messages.sizeInBytes  }}

read方法

def read(  startOffset: Long,  maxOffset: Option[Long],  maxSize: Int,  maxPosition: Long = size): FetchDataInfo = {  if (maxSize < 0) {    throw new IllegalArgumentException("Invalid max size for log read (%d)".format(maxSize))  }    val logSize = log.sizeInBytes  val startPosition = translateOffset(startOffset)    if (startPosition == null) {    return null  }    val offsetMetadata = new LogOffsetMetadata(    startOffset,     this.baseOffset,     startPosition.position  )    if (maxSize == 0) {    return FetchDataInfo(offsetMetadata, MessageSet.Empty)  }    val length = maxOffset match {    case None =>      min((maxPosition - startPosition.position).toInt, maxSize)    case Some(offset) =>      if (offset < startOffset) {        return FetchDataInfo(offsetMetadata, MessageSet.Empty)      }            val mapping = translateOffset(offset, startPosition.position)      val endPosition = if (mapping == null) {        logSize      } else {        mapping.position      }            min(min(maxPosition, endPosition) - startPosition.position, maxSize).toInt  }    FetchDataInfo(offsetMetadata, log.read(startPosition.position, length))}

recover方法

def recover(maxMessageSize: Int): Int = {  index.truncate()  index.resize(index.maxIndexSize)    var validBytes = 0  var lastIndexEntry = 0    val iter = log.iterator(maxMessageSize)    try {    while (iter.hasNext) {      val entry = iter.next      entry.message.ensureValid()            if (validBytes - lastIndexEntry > indexIntervalBytes) {        val startOffset = entry.message.compressionCodec match {          case NoCompressionCodec =>            entry.offset          case _ =>            ByteBufferMessageSet.deepIterator(entry).next().offset        }                index.append(startOffset, validBytes)        lastIndexEntry = validBytes      }            validBytes += MessageSet.entrySize(entry.message)    }  } catch {    case e: CorruptRecordException =>      logger.warn("Found invalid messages in log segment %s at byte offset %d: %s.".format(        log.file.getAbsolutePath, validBytes, e.getMessage))  }    val truncated = log.sizeInBytes - validBytes  log.truncateTo(validBytes)  index.trimToValidSize()  truncated}

转载地址:http://gjxx.baihongyu.com/

你可能感兴趣的文章
osi 负载均衡
查看>>
OSI七层模型与TCP/IP五层模型(转)
查看>>
OSI七层模型与TCP/IP四层与五层模型详解
查看>>
OSI七层模型的TCP/IP模型都有哪几层和他们的对应关系?
查看>>
OSI操作系统(NETBASE第八课)
查看>>
OSM数据如何下载使用(地图数据篇.11)
查看>>
OSPF 四种设备角色:IR、ABR、BR、ASBR
查看>>
OSPF 四种路由类型:Intra Area、Inter Area、第一、二类外部路由
查看>>
OSPF 学习
查看>>
OSPF 支持的网络类型:广播、NBMA、P2MP和P2P类型
查看>>
OSPF 概念型问题
查看>>
OSPF 的主要目的是什么?
查看>>
OSPF5种报文:Hello报文、DD报文、LSR报文、LSU报文和LSAck报文
查看>>
SQL Server 存储过程分页。
查看>>
OSPFv3:第三版OSPF除了支持IPv6,还有这些强大的特性!
查看>>
OSPF不能发现其他区域路由时,该怎么办?
查看>>
OSPF两个版本:OSPFv3与OSPFv2到底有啥区别?
查看>>
SQL Server 存储过程
查看>>
OSPF在什么情况下会进行Router ID的重新选取?
查看>>
OSPF在大型网络中的应用:高效路由与可扩展性
查看>>