【大数据】Kafka 数据存储

1.文件目录

Kafka 中的消息是存储在磁盘上的,一个分区副本对应一个 日志(Log)。为了防止 Log 过大,Kafka 又引入了 日志分段(LogSegment)的概念,将 Log 切分为多个 LogSegment ,相当于一个巨型文件被平均分配为多个相对较小的文件,这样也便于消息的维护和清理。事实上,Log 和 LogSegment 也不是纯粹物理意义上的概念,Log 在物理上只以文件夹的形式存储,而每个 LogSegment 对应于磁盘上的一个日志文件和两个索引文件,以及可能的其他文件(比如以 .txnindex 为后缀的事务索引文件),下图为 Topic、Partition、副本、Log 和 LogSegment 之间的关系。

在这里插入图片描述

2.日志分段

虽然一个 Log 被拆为多个分段,但只有最后一个 LogSegment(当前活跃的日志分段)才能执行写入操作,在此之前所有的 LogSegment 都不能写入数据。当满足以下其中任一条件会创建新的 LogSegment。

  • 当前日志分段文件的大小超过了 Broker 端参数 log.segment.bytes 配置的值,默认值为 1073741824 1073741824 1073741824,即 1 G B 1GB 1GB
  • 当前日志中第一条消息的时间戳与当前系统的时间戳的差值大于 log.roll.mslog.roll.hours 参数配置的值。如果同时配置了 log.roll.mslog.roll.hours,那么以 log.roll.ms 为准。默认只配置了 log.roll.hours 参数,其值为 168 168 168,即 7 7 7 天。
  • 偏移量索引文件或时间戳索引文件的大小达到 Broker 端参数 log.index.size.max.bytes 配置的值,默认值为 10485760 10485760 10485760,即 10 M 10M 10M
  • 追加的消息的偏移量与当前日志分段的偏移量之间的差值大于 Integer.MAX_VALUE,即(offset - baseOffset)> Integer.MAX_VALUE

在索引文件切分的时候,Kafka 会关闭当前正在写入的索引文件并置为只读模式,同时以可读写的模式创建新的索引文件,默认大小为 1 G B 1GB 1GB。当下次索引切分时才会设置为实际大小。也就是说,之前的 Segment 都是实际大小,活跃的 Segment 大小为 1 G 1G 1G

3.日志索引

索引的主要目的是提高查找的效率。

Kafka 采用 稀疏索引sparse index)的方式构造消息的索引,它并不保证每个消息在索引文件中都有对应的索引项。而是每当写入一定量(由 Broker 端参数 log.index.interval.bytes 指定,默认 4 K B 4KB 4KB)的消息时,索引文件会增加一个索引项。

3.1 偏移量索引

一条偏移量索引包含两部分数据,如图:

在这里插入图片描述

在这里插入图片描述

  • relativeOffset:相对偏移量,表示消息相对于 baseOffset 的偏移量,当前索引文件的文件名即为 baseOffset
  • position:物理地址,也就是消息在日志分段文件中对应的物理位置。
  • baseOffset:Segment 第一个 Message 的 Offset。

消息查找过程
在这里插入图片描述

如果我们要查找偏移 23 23 23 的消息,那么应该怎么做呢? 首先通过二分法在偏移量索引文件中找到不大于 23 23 23 最大索引项,即 [22,656],然后从日志分段文件中的物理位置 656 656 656 开始顺序查找偏移 23 23 23 的消息。

以上是比较简单的情况,如下图所示,如果要查找要查找偏移 268 268 268 的消息,那么应该怎么办呢?

在这里插入图片描述

首先肯定是定位到 baseOffset = 251 的日志分段,然后计算相对偏移量 relativeOffset 268 − 251 = 17 268 - 251=17 268251=17,之后再在对应的索引文件中找到不大于 17 17 17 的索引项,最后根据索引项中的 position 定位到具体的日志分段文件位置开始查找目标消息。

那么如何查找 baseOffset 25 的日志分段的呢?Kafka 使用了跳跃表的结构。Kafka 的每个日志对象中使用了 ConcurrentSkipListMap 来保存各个日志分段,每个日志分段的 baseOffset 作为 Key ,这样可以根据指定偏移量来快速定位到消息所在的日志分段。

3.2 时间戳索引

时间戳索引也是包含两部分数据,如图:

在这里插入图片描述

在这里插入图片描述

  • timestamp:当前日志分段最大的时间戳。
  • relativeOffset:时间戳所对应的消息的相对偏移量,也就是偏移量索引中偏移量。

时间戳索引文件中包含若干时间戳索引项,每个追加的时间戳索引项中的 timestamp 必须大于之前追加的索引项的 timestamp,否则不予追加。

消息查找过程

在这里插入图片描述

如果要查找指定时间戳 targetTimeStamp = 1526384718288 开始的消息,首先是找到不小于指定时间戳的日志分段。这里就无法使用跳跃表来快速定位到相应的日志分段 了, 需要分以下几个步骤来完成。

  • targetTimeStamp 和每个日志分段中的最大时间戳对比,直到找到不小于 targetTimeStam 所对应的日志分段。(注:日志分段中的最大时间戳的计算是先查询该日志分段所对应的时间戳索引文件,找到最后一条索引项,若最后一条索引项的时间戳字段值大于 0 0 0,则取其值,否则取该日志分段的最近修改时间。)
  • 找到相应的日志分段之后,在时间戳索引文件中使用二分查找算法查找到不大于 targetTimeStamp 最大索引项,即 [1526384718283, 28],如此便找到了相对偏移量 28 28 28
  • 在偏移量索引文件中使用二分算法查找到不大于 28 28 28 的最大索引工页,即 [26,838]
  • 从第一步中找到的日志分段文件中的 838 838 838 的物理位置开始查找不小于 targetTimeStamp 的消息。

4.日志清理

Kafka 将消息存储在磁盘中,为了控制磁盘占用空间的不断增加就需要对消息做一定的清理操作。Kafka 提供了两种日志清理策略。

  • 日志删除:按照一定的保留策略直接删除不符合条件的日志分段,默认该策略。
  • 日志压缩:针对每个消息的 Key 进行整合,对于有相同 Key 的不同 Value 值,只保留最后一个版本。

4.1 日志删除

kafka 有专门的任务来周期性删除不符合条件的日志分段文件,删除策略主要以下有 3 3 3 种。

4.1.1 基于时间

Broker 端可通过参数设置日志的最大保留时间,默认 7 7 7 天。定时任务会查看每个分段的最大时间戳(计算逻辑同上),若最大时间戳距当前时间超过 7 7 7 天,则需要删除。

删除日志分段时, 首先会先从跳跃表中移除待删除的日志分段,保证没有线程对这些日志分段进行读取操作。然后将日志分段所对应的所有文件添加上 .delete 的后缀。最后由专门的定时任务来删除以 .delete 为后缀的文件。

4.1.2 基于日志大小

日志删除任务会检查当前日志的大小是否超过设定的阈值(retentionSize)来寻找可删除的日志分段的文件集合(deletableSegments)。

注意这里的日志的大小是指所有的 Segment 的总和,不是单个 Segment。

在这里插入图片描述

首先计算日志文件的总大小和设定阈值的差值,即计算需要删除的日志总大小,然后从日志文件中的第一个日志分段开始进行查找可删除的日志分段,放入集合 deletableSegments 中 。之后进行删除,删除过程同 4.1.1 小节所述。

4.1.3 基于日志起始偏移量

一般情况下,日志文件的起始偏移 logStartOffset 等于第 1 1 1 个日志分段的 baseOffset,但 logStartOffset 是可以被修改的。

该策略会判断某日志分段的下一个日志分段的起始偏移量 baseOffset 是否小于等于 logStartOffset,若是,则将其放入 deletableSegments 中。如下图所示。

在这里插入图片描述
之后进行删除,删除过程同 4.1.1 小节所述。

4.2 日志压缩

对于有相同 Key 的不同 Value 值,只保留最后一个版本。如果应用只关心 Key 对应的最新 Value 值,则可以开启 Kafka 的日志压缩功能,Kafka 会定期将相同 Key 的消息进行合井,只保留最新的 Value 值。

在这里插入图片描述

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当面试官问到大数据Kafka的面试题,可能会涉及以下几个方面的内容: 1. Kafka的基本概念和特点: - Kafka是一个分布式流处理平台,用于高吞吐量的实时数据传输。 - Kafka采用发布-订阅模式,消息以topic为单位进行发布和订阅。 - Kafka具有高可靠性、可扩展性和持久性等特点。 2. Kafka的架构和组件: - Kafka集群由多个broker组成,每个broker负责存储和处理消息。 - 每个topic可以分为多个分区,每个分区可以在不同的broker上进行复制。 - 生产者将消息发布到指定的topic,消费者从指定的topic订阅消息。 3. Kafka的消息传输和存储: - Kafka使用消息日志的方式存储消息,每个分区都有一个对应的日志文件。 - 生产者将消息追加到分区的日志文件末尾,消费者按照偏移量顺序读取消息。 - Kafka支持消息的持久化存储,并且可以根据配置进行数据的保留和清理。 4. Kafka的高可用和容机制: - Kafka通过副本机制实现高可用性,每个分区可以有多个副本。 - 副本之间通过ISR(In-Sync Replicas)机制保持同步,确保数据的一致性。 - 当某个broker宕机时,Kafka会自动将其上的分区副本迁移到其他可用的broker上。 5. Kafka的性能调优和监控: - 可以通过调整Kafka的参数来提高性能,如调整分区数、批量发送消息等。 - 监控Kafka集群的健康状态,包括吞吐量、延迟、存储空间等指标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G皮T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值