Kafka是一种分布式的流处理平台,它通过文件存储机制来保证数据的可靠性,高效性和可扩展性。
Kafka的数据存储是基于日志的,它将所有的消息都保存在一个或多个主题(topic)的日志文件中。每个主题都由一个或多个分区(partition)组成,每个分区都是一个有序的、不可修改的消息日志。消息按照它们的写入顺序追加到分区中,并分配一个唯一的偏移量(offset)来标识它们在分区中的位置。
Kafka使用了两个文件来存储消息:消息文件和索引文件。
这种分离的存储方式使得Kafka可以高效地执行消息的写入和读取操作。
Kafka的文件存储机制还包括了消息的压缩和清理策略。
Kafka支持Gzip、Snappy和LZ4三种压缩算法,可以将消息在写入到日志文件中之前进行压缩,从而减少磁盘空间的占用。同时,Kafka也支持基于时间或日志大小的消息清理策略,可以根据设定的阈值自动删除过期或过大的消息,以释放存储空间。
此外,Kafka的文件存储机制还支持多副本机制,通过副本机制可以实现高可用性和数据冗余。
每个分区都可以配置多个副本(replica),副本分布在不同的Broker上,可以提高数据的可靠性和可用性。当某个Broker宕机时,其他Broker上的副本可以自动接管它的工作,保证数据不会丢失。
Kafka的文件存储机制还支持批量写入和读取,可以将多个消息一次性写入日志文件中,或一次性读取多个消息,从而提高数据的处理效率。
在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1。
这样做的好处就是能快速删除无用文件,有效提高磁盘利用率。
创建一个topicXXX包含1 partition,设置每个segment大小为500MB,并启动producer向Kafka broker写入大量数据,如下图2所示segment文件列表形象说明了上述2个规则:
以上述图中一对segment file文件为例,说明segment中index<—->data file对应关系物理结构如下:
上述图中索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。 其中以索引文件中元数据3497为例,依次在数据文件中表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。
从上述图了解到segment data file由许多message组成,下面详细说明message物理结构如下:
关键字 | 解释说明 |
---|---|
8 byte offset | 在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message |
4 byte message size | message大小 |
4 byte CRC32 | 用crc32校验message |
1 byte “magic” | 表示本次发布Kafka服务程序协议版本号 |
1 byte “attributes” | 表示为独立版本、或标识压缩类型、或编码类型。 |
4 byte key length | 表示key的长度,当key为-1时,K byte key字段不填 |
K byte key | 可选 |
value bytes payload | 表示实际消息数据。 |
从上述图可知这样做的优点,segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,它比稠密索引节省了更多的存储空间,但查找起来需要消耗更多的时间。
写message
读message
Kafka高效文件存储设计特点
下面以一个Kafka集群中4个Broker举例,创建1个topic包含4个Partition,2 Replication;数据Producer流动如图所示:
当集群中新增2节点,Partition增加到6个时分布情况如下:
副本分配逻辑规则如下:
副本分配算法如下: