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

你可能感兴趣的文章
php对象引用和析构函数的关系
查看>>
RabbitMQ HTTP 认证后端项目常见问题解决方案
查看>>
PHP将图片转换成base64格式(优缺点)
查看>>
php将多个值的数组去除重复元素
查看>>
php局域网上传文件_PHP如何通过CURL上传文件
查看>>
PHP工具插件大全
查看>>
php布尔值的++
查看>>
PHP常量、变量作用域详解(一)
查看>>
PHP应用目录结构设计
查看>>
PHP应用程序连接MSQL数据库Demo(附crud程序)
查看>>
PHP开发api接口安全验证
查看>>
PHP开发规范PSR
查看>>
PHP开发遇到错误0001
查看>>
PHP引入了泛型和集合两大重要特性,大大改善 PHP 代码的可维护性和可读性
查看>>
PHP引擎php.ini参数优化
查看>>
PHP引用(&)使用详解
查看>>
php引用及垃圾回收
查看>>
php当前时间的集中写法
查看>>
php循环比较数组中的值,如何从PHP数组中计算值并在foreach循环中仅显示一次值?...
查看>>
php微信 开发笔记,微信WebApp开发总结笔记
查看>>