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

【深入理解Kafka系列】第五章 日志存储

        前几章已经讲解了kafka的基本知识,我们已经能较好的用kafka来完成基本的开发任务,接下来了解一下内部的一些细节,便于知道相关的原理。本章主要讲kafka日志存储相关的知识。

1、文件目录布局

      回顾之前所学的知识: Kafka 中的消息是以主题为基本单位进行归类的,各个主题在逻辑
上相互独立。每个主题又可以分为一个或多个分区,分区的数量可以在主题创建的时候指定,
也可以在之后修改 。 每条消息在发送的时候会根据分区规则被迫加到指定的分区中,分区中的
每条消息都会被分配一个唯一的序列号,也就是通常所说的偏移量 ( offset )。
        如果分区规则设置得合理,那么所有的消息可以均匀地分布到不同的分区中,这样就可以
实现水平扩展。不考虑多副本的情况, 一个分区对应一个日志( Log)。为了防止 Log 过大,
Kafka 又引入了日志分段( LogSegment )的概念, 将 Log 切分为多个 LogSegment,相当于一个巨型文件被平均分配为多个相对较小的文件,这样也便于消息的维护和清理。事实上, Log 和
LogSegnient 也不是纯粹物理意义上的概念, Log 在物理上只以文件夹的形式存储,而每个
LogSegment 对应于磁盘上的一个日志文件和两个索引文件,以及可能的其他文件
(比如以
“ .txnindex ”为后缀的事务索引文件〉 。 

     向 Log 中追加消息时是顺序写入的,只有最后一个 LogSegment 才能执行写入操作,在此
之前所有的 LogSegment 都不能写入数据。
        为了便于消息的检索,每个 LogSegment 中的日志文件(以“ .log”为文件后缀)都有对应的两个索引文件 :偏移量索引文件(以“ .index”为文件后缀)和时间戳索引文件(以“ .timeindex ”为文件后缀)。每个 LogSegment 都有一个基准偏移量 baseOffset,用来表示当前 LogSegment
中第一条消息的 offset 。 偏移量是一个 64 位的长整型数,日志文件和两个索引文件都是根据基
准偏移量( baseOffset)命名的,名称固定为 20 位数字,没有达到的位数则用 0 填充 。 比如第
一个 LogSegment 的基准偏移量为 0,对应的日志文件为 00000000000000000000 .logo

2、日志索引

          偏移量索引文件用来建立消息偏移量( offset )到物理地址之间的映射关系,方便快速定位消息所在的物理文件位置;时间戳索引文件则根据指定的时间戳( timestamp )来查找对应的偏移量信息。
        Kafka 中的索引文件以稀疏索引( sparse index )的方式构造消息的索引,它并不保证每个
消息在索引文件中都有对应的索引项 。当写入一定量(由 broker 端参数 log.index.interval.bytes 指定,默认值为4096 ,即 4KB )的消息时,偏移量索引文件和时间戳索引文件分别增加一个偏移量索引项和时间戳索引项,增大或减小log.index.interval.bytes的值,对应地可以增加或缩小索引项的密度。稀疏索引通过 MappedByteBuffer 将索引文件映射到内存中,以加快索引的查询速度。

        开头也提及日志分段文件达到一定的条件时需要进行切分,那么其对应的索引文件也
需要进行切分。

       日志分段文件切分规则 :
       (1) 当前日志分段文件的大小超过了 broker 端参数 log.segment.bytes 配置的值。
log.segment.bytes 参数的默认值为 1073741824 ,即 1GB
        (2)当前日志分段中消息的最大时间戳与当前系统的时间戳的差值大于 log.roll .ms或 log.roll.hours 参数配置的值。如果同时配置了 log.roll.ms 和 log.roll.hours 参数,那么 log.roll.ms 的优先级高 。 默认情况下,只配置了 log.ro ll.hours 参数,其值为 168,即 7 天
        (3)偏移量索引文件或时间戳索引文件的大小达到 broker 端参数 log.index.size .max.
bytes 配置的值。log.index.size.max.bytes 的默认值为 10485760 ,即 10MB
        (4)追加的消息的偏移量与当前日志分段的偏移量之间的差值大于 Integer.MAX_VALUE,
即要追加的消息的偏移量不能转变为相对偏移量( offset - baseOffset > Integer.MAX_VALUE )。

        对非当前活跃的日志分段而言,其对应的索引文件内容己经固定而不需要再写入索引项,所以会被设定为只读 。 而对当前活跃的日志分段 (activeSegment)而言,索引文件还会追加更多的索引项,所以被设定为可读写。

  2.1、偏移量索引

        偏移量索引项的格式如图 5 -8 所示。每个索引项占用 8 个字节,分为两个部分。
        (1)relativeOffset:相对偏移量,表示消息相对于 baseOffset 的偏移量,占用 4 个字节 ,
当前索引文件的文件名即为 baseOffset 的值 。
        (2)position:物理地址,也就是消息在日志分段文件中对应的物理位置,占用 4 个字节。

                                    

       偏移量索引文件中的偏移量是单调递增的,查询指定偏移量时,使用二分查找法来快速定位偏移量的位置,如果指定的偏移量不在索引文件中,则会返回小于指定偏移量的最大偏移量 。

 2.2、时间戳索引

        每个索 引 项占用 12 个字节,分为两个部分:
        (1) timestamp : 当前日志分段最大的时间戳。
        (2) relativeOffset:时间戳所对应的消息的相对偏移量。
                                  

        时间戳索引文件中的时间戳也保持严格的单调递增,查询指定时间戳时,也根据二分查找法来查找不大于该时间戳的最大偏移量,至于要找到对应的物理文件位置还需要根据偏移量索引文件来进行再次定位。 

 3、日志清理

        Kafka 将消息存储在磁盘中,为了控制磁盘占用空间的不断增加就需要对消息做一定的清
理操作。 Kafka 中每一个分区副本都对应一个 Log,而 Log 又可以分为多个日志分段,这样也
便于日志的清理操作。 Kafka 提供了两种日志清理策略 。
      (1)日志删除( Log Retention ) : 按照一定的保留策略直接删除不符合条件的日志分段。
      (2)日志压缩( Log Compaction ):针对每个消息的 key 进行整合,对于有相同 key 的不
同 value 值,只保留最后一个版本。

        我们可以通过broker端参数log.cleanup.policy来设置日志清理策略, 此参数的默认值为“delete ”,即采用日志删除的清理策略 。如果要采用日志压缩的清理策略,就需要将
log.cleanup.policy设置为“compact”,并且还要将 log.cleaner.enable(默认值为 true)设定为 true。

3.1、日志删除

        在Kafka的日志管理器中会有一个专门的日志删除任务来周期性地检测和删除不符合保留条
件的日志分段文件,这个周期可以通过 broker 端参数 log.retention.check.interval.ms来配置,默认值为 300000,即 5 分钟。

      当前日志分段的清除策略有3种:

  • 基于时间:日志删除任务会检查当前日志文件中是否有保留时间超过设定的阑值 来寻找可删除的日志分段文件集合,可以通过broker端参数 log.retention.hours、log.retention.minutes 和 log.retention.ms来配置,其中log.retention.ms 的优先级最高,log.retention.minutes 次之,log.retention.ms最低。默认情况下只配置了 log.retention.hours参数 ,其值为168,故默认情况下日志分段文件的保留时间为 7 天
  • 基于日志大小:日志删除任务会检查当前日志的大小是否超过设定的阔值来寻找可删除的日志分段的文件集合,可以通过 broker 端参数 log .retention.bytes 来配置,默认值为-1,表示无穷大。注意 log. retention.bytes配置的是 Log 中所有日志文件的总大小,而不是单个日志分段(确切地说应该为 .log 日志文件)的大小 。单个日志分段的大小由 broker 端参数log.segment.bytes 来限制,默认值为1073741824, 即 1GB
  • 基于日志起始偏移量:基于日志起始偏移量的保留策略的判断依据是某日志分段的下一个日志分段的起始偏移量baseOffset 是否小于等于 logStartOffset ,若是,则可以删除此日志分段。

  3.2、日志压缩

        Kafka 中的Log Compaction是指在默认的日志删除( Log Retention )规则之外提供的一种
清理过时数据的方式。 Log Compaction 对于有相同 key 的不同 value 值,只保留最后一个版本。如果应用只关心 key 对应的最新 value 值,则可以开启 Kafka 的日志清理功能,Kafka 会定期将相同 key 的消息进行合井,只保留最新的 value 值。

相关文章:

  • 想做好数据可视化?手把手教你正确选择图表类型
  • C#【高级篇】 IntPtr是什么?怎么用?
  • 软考知识点---01计算机的基本组成---02存储系统
  • Day09JavaWeb第九次笔记---Request和Response学习
  • 第三章 Flink基础理论之内存优化及常见内存报错解决方案
  • 分数阶粒子群算法-附代码
  • springboot(三)
  • Kubernetes 常见面试题(六)
  • Linux安装禅道最新版
  • 【Bluetooth|蓝牙开发】十一、一文秒懂 | 超详细的Bluez交叉编译
  • TC8:SOMEIPSRV_FORMAT_01-10
  • 软考:信息安全工程师3
  • 接口(续)和Object类
  • 构造接口,免费查询快递物流
  • 被裁后一个offer都没有,测试人的问题在哪里?
  •  D - 粉碎叛乱F - 其他起义
  • Docker 笔记(2):Dockerfile
  • E-HPC支持多队列管理和自动伸缩
  • java第三方包学习之lombok
  • java正则表式的使用
  • js作用域和this的理解
  • node.js
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • spark本地环境的搭建到运行第一个spark程序
  • 构建二叉树进行数值数组的去重及优化
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 实现简单的正则表达式引擎
  • 通过几道题目学习二叉搜索树
  • 微信支付JSAPI,实测!终极方案
  • ​力扣解法汇总946-验证栈序列
  • ​学习一下,什么是预包装食品?​
  • #100天计划# 2013年9月29日
  • #define
  • (补)B+树一些思想
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (学习日记)2024.01.19
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • **PHP二维数组遍历时同时赋值
  • .gitignore文件_Git:.gitignore
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET 表达式计算:Expression Evaluator
  • .NET 事件模型教程(二)
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET大文件上传知识整理
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @JoinTable会自动删除关联表的数据
  • @property python知乎_Python3基础之:property
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • @在php中起什么作用?
  • [ C++ ] STL---string类的模拟实现
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [Android]How to use FFmpeg to decode Android f...
  • [bzoj4010][HNOI2015]菜肴制作_贪心_拓扑排序