kafka日志存储(四):OffsetIndex

为了提高查找消息的性能,kafka在0.8 后为每个日志文件添加了对应的索引文件,OffsetIndex对象对应管理磁盘上的一个索引文件,预FileMessageSet共同构成了一个LogSegment对象。
OffsetIndex字段有:

class OffsetIndex(@volatile private[this] 
    //指向磁盘上的索引文件。
    var _file: File, 
    // 日志文件中的第一个消息的offset
    val baseOffset: Long, 
    val maxIndexSize: Int = -1) extends Logging {
    //mmap用来操作索引文件
    private[this] var mmap: MappedByteBuffer = {
        //如果索引文件不存在,则创建新文件并返回true
        val newlyCreated = _file.createNewFile()
        val raf = new RandomAccessFile(_file, "rw")
        try {
          /* 对新创建的索引文件进行扩容 */
          if (newlyCreated) {
            if (maxIndexSize < 8)
              throw new IllegalArgumentException("Invalid max index size: " + maxIndexSize)
            //根据maxIndexSize的值对索引文件进行扩容,扩容结果是小于maxIndexSize的最大的8的倍数
            raf.setLength(roundToExactMultiple(maxIndexSize, 8))
          }

          /* 内存映射 */
          val len = raf.length()
          val idx = raf.getChannel.map(FileChannel.MapMode.READ_WRITE, 0, len)

          /* set the position in the index for the next entry */
          if (newlyCreated)
            idx.position(0)
          else
            // if this is a pre-existing index, assume it is all valid and set position to last entry
            idx.position(roundToExactMultiple(idx.limit, 8))
          idx
        } finally {
          CoreUtils.swallow(raf.close())
        }
    }
    
    /* 索引文件中索引项的个数 */
    @volatile
    private[this] var _entries = mmap.position / 8

    /* 最大索引个数 */
    @volatile
    private[this] var _maxEntries = mmap.limit / 8
    //最后一个索引的offset
    @volatile
    private[this] var _lastOffset = readLastEntry.offset
}

offsetIndex中最常用的是查找方法lockup

def lookup(targetOffset: Long): OffsetPosition = {
    maybeLock(lock) {
      val idx = mmap.duplicate
      //二分查找
      val slot = indexSlotFor(idx, targetOffset)
      if(slot == -1)
        OffsetPosition(baseOffset, 0)
      else
        OffsetPosition(baseOffset + relativeOffset(idx, slot), physical(idx, slot))
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值