Kafka是大型架构的必备中间件,下面我就重点来详解Kafka存储原理@mikechen
Kafka存储
消息队列,在现代分布式系统中扮演着至关重要的角色,而消息的持久化是确保这些系统稳定性和数据可靠性的基石。
Kafka 的核心特性:就是其可靠的消息持久化能力。
理解 Kafka 的存储原理,有助于我们更好地理解其高吞吐、高可靠和低延迟的特性是如何实现的。
通过将消息写入磁盘,即使 Kafka Broker 发生故障(例如服务器宕机、重启等),消息也不会丢失。
当 Broker 恢复后,仍然可以从磁盘中恢复数据,确保消息的可靠传递。
并且,持久化使得生产者无需等待消费者处理消息即可继续发送,实现了生产者和消费者的解耦。
即使在消费者离线或处理缓慢的情况下,消息也能被安全地存储在 Kafka 中,等待后续处理。
Kafka存储原理
Kafka 的存储模型,是基于日志文件(log file)按分区组织的,每个 Topic 的每个 Partition 对应磁盘上的一个日志目录。
Kafka 将每个 Topic 划分为多个 Partition,每个 Partition 在磁盘上对应一个目录,该目录下存储着该 Partition 的所有消息数据。
Kafka 的消息并不是存储在一个巨大的文件中,而是被分割成多个称为日志段(Log Segment)的小文件。
/kafka-logs/ └── my-topic-0/ ├── 00000000000000000000.log ├── 00000000000000000000.index ├── 00000000000000000000.timeindex ├── ...
说明:
-
.log
:消息数据文件,按顺序追加写入; -
.index
:Offset 到物理地址的稀疏索引; -
.timeindex
:消息时间戳到 Offset 的索引。
顺序追加写入
Kafka 为了实现高吞吐量的写入性能,采用了顺序追加写入的方式,将消息写入磁盘。
顺序写入是磁盘 I/O 操作中最快的方式之一,因为它避免了大量的磁盘寻道时间。
与随机写入相比,顺序写入可以充分利用磁盘的写入带宽,从而实现非常高的写入吞吐量。
写入流程,如下:
-
Broker 接收 Producer 请求;
-
校验合法性后,将数据写入内存缓冲区;
-
按批追加写入
.log
文件末尾(当前活跃 Segment); -
更新索引文件(按间隔写入);
-
异步刷盘(依据
flush.messages
或flush.ms
);
日志段管理
Kafka 不会将所有数据写入一个大文件,而是采用 分段机制(Segment) 将日志分割成多个小文件,提高管理与清理效率。
如下所示:
00000000000000000000.log 00000000000000000000.index 00000000000000000000.timeindex
为了防止磁盘空间被无限增长的日志数据占用,Kafka 提供了灵活的日志段过期删除策略。
比如:
基于时间的保留策略 , Kafka 会删除在指定时间之前创建的非活跃日志段。
例如:配置保留 7 天的日志,那么超过 7 天的旧日志段将被删除。
基于大小的保留策略, Kafka 会删除最早的非活跃日志段,直到所有日志段的总大小不超过配置的最大值。
通过以上机制,顺序写入保证了写入性能,日志分段方便了管理和清理,而灵活的过期删除策略则避免了磁盘空间的无限增长。