当前位置: 首页 > article >正文

Kafka 源码分析(一) 日志段

首先我们的 kafka 的消息本身是存储在日志段中的, 对应的源码是下面这段代码:

class LogSegment private[log] (val log: FileRecords,
                               val lazyOffsetIndex: LazyIndex[OffsetIndex],
                               val lazyTimeIndex: LazyIndex[TimeIndex],
                               val txnIndex: TransactionIndex,
                               val baseOffset: Long,
                               val indexIntervalBytes: Int,
                               val rollJitterMs: Long,
  val time: Time) extends Logging {}

一个日志段包含消息日志文件、位移索引文件、时间戳索引文件、已中止事务索引文件等。这里的 FileRecords 就是实际保存 Kafka 消息的对象。

索引文件通常是以.index 为结尾的:

  • .offsetIndex 我们可以根据位移索引文件定位到记录在那个log 文件,
  • .timeindex:是时间索引文件,是用来帮助Kafka通过时间戳来查找对应记录的位移信息。

在这里插入图片描述

  • baseOffset 表示基础偏移量, 对应着文件名称, 注意这个开始位移在一开始就是固定的。
  • indexIntervalBytes 值其实就是 Broker 端参数 log.index.interval.bytes 值,它控制了日志段对象新增索引项的频率。默认情况下一般需要达到4kb 才会创建新的索引项
  • rollJitterMs 是日志段对象新增倒计时的“扰动值”。因为目前 Broker 端日志段新增倒计时是全局设置,这就是说,在未来的某个时刻可能同时创建多个日志段对象,这将极大地增加物理磁盘 I/O 压力。有了 rollJitterMs 值的干扰,每个新增日志段在创建时会彼此岔开一小段时间,这样可以缓解物理磁盘的 I/O 负载瓶颈。

这个扰动值含义是当前避免同时多个线程同时向磁盘中写入对应的数据

关于这个LogSegment 是存在与之相关的方法的, 主要有三个方法, 分别是对应的 append 方法, read 方法, 以及对应的 recover 方法。

首先我们看一下对应的append 函数

def append(largestOffset: Long,
             largestTimestamp: Long,
             shallowOffsetOfMaxTimestamp: Long,
             records: MemoryRecords): Unit;
  1. 这个函数首先会判断当前日志段时候为空, 如果为null, 我们就需要写入对应的最大时间戳
  2. 确保对应的最大位移值是正确的, 如果不正确的话是不给写入的
  3. 执行真正的写入操作
  4. 更新最大时间戳, 最大的位移值
  5. 更新写入的字节数量

和日志段相关的第二个相关的操作是 read 函数, 这个函数接受了四个参数, 分别是:

  1. 要读取的第一条消息的位移
  2. 能读取消息的最大位移数量
  3. 能读取的最大文件位置
  4. 是否允许消息体过大的时候至少返回对应的消息

和日志段相关的第三个操作是 recover 函数,在消息系统中, 日志被分成了多个日志段, 每个日志段包含一定数量的消息,这些日志消息被保存在磁盘上面,

recover 方法的作用是确保在 Broker 启动时,能够正确地从磁盘加载日志段数据,并将其恢复到一个一致的状态,以便后续的读写操作能够正常进行。


http://www.kler.cn/a/514870.html

相关文章:

  • HTTP 配置与应用(局域网)
  • 【JavaSE】(8) String 类
  • Visual Studio Community 2022(VS2022)安装方法
  • 深度学习-89-大语言模型LLM之AI应用开发的基本概念
  • 网络编程 | UDP组播通信
  • 队列的一些注意
  • java中的String类、StringBuffer类、StringBuilder类的详细讲解(包含相互之间的比较)
  • BUG解决:安装问题transformer_engine+pytorch
  • 基于springboot+vue的高校社团管理系统的设计与实现
  • docker ubuntu:20.04构建c++ grpc环境
  • es的date类型字段按照原生格式进行分组聚合
  • QILSTE H13-320B2W高亮白光LED灯珠 发光二极管LED
  • 如何使用CRM数据分析和洞察来支持业务决策和市场营销?
  • 开源鸿蒙开发者社区记录
  • 深入了解 Java split() 方法:分割字符串的利器
  • AI时代的网络安全:传统技术的落寞与新机遇
  • Kubernetes入门学习
  • Spring Boot 事件驱动:构建灵活可扩展的应用
  • PostgreSQL 初中级认证可以一起学吗?
  • Servlet快速入门
  • Spring Boot MyBatis Plus 版本兼容问题(记录)
  • HOW - 基于master的a分支和基于a的b分支合流问题
  • Echarts现成案例
  • 阻燃高温尼龙行业:市场潜力巨大,引领材料科学新变革
  • AI 辅助 Codebase 本地工程检索
  • Linux内核中 Netfilter 框架的用户态工具iptables(配置防火墙规则)