博客
关于我
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/

你可能感兴趣的文章
oncopy和onpaste
查看>>
onCreate中的savedInstanceState作用
查看>>
onCreate()方法中的参数Bundle savedInstanceState 的意义用法
查看>>
One good websit for c#
查看>>
One-Shot学习/一次学习(One-shot learning)
查看>>
OneASP 安全公开课,深圳站, Come Here, Feel Safe!
查看>>
OneBlog Shiro 反序列化漏洞复现
查看>>
oneM2M
查看>>
Oneplus5重装攻略
查看>>
one_day_one--mkdir
查看>>
ONI文件生成与读取
查看>>
Vue 项目中实现高效的消息提示与确认对话框功能(模版)
查看>>
Online PDF to PNG、JPEG、WEBP、 TXT - toolfk
查看>>
onlstm时间复杂度_CRF和LSTM 模型在序列标注上的优劣?
查看>>
onlyoffice新版5.1.2版解决中文汉字输入重复等问题
查看>>
onnx导出动态输入
查看>>
onnx导出动态输入
查看>>
onScrollStateChanged无效
查看>>
onTouchEvent构造器
查看>>
on_member_join 和删除不起作用.如何让它发挥作用?
查看>>