Kafka数据存储结构

2016-10-07|来源:

要了解kafka的数据存储结构,首先得了解一下kafka中的Topic Partition


Topic在逻辑上可以被认为是一个queue,每条消费都必须指定它的Topic,可以简单理解为必须指明把这条消息放进哪个queue里。为了使得Kafka的吞吐率可以线性提高,物理上把Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件。若创建topic1topic2两个topic,且分别有13个和19个分区,则整个集群上会相应会生成共32个文件夹(本文所用集群共8个节点,此处topic1topic2 replication-factor均为1),如下图所示。



每个日志文件都是一个log entrie序列,每个log entrie包含一个4字节整型数值(值为N+5),1个字节的“magic value”,4个字节的CRC校验码,其后跟N个字节的消息体。

每条消息都有一个当前Partition下唯一的64字节的offset,它指明了这条消息的起始位置。


磁盘上存储的消息格式如下:

message length 4 bytes (value: 1+4+n)

magicvalue 1 byte

crc 4 bytes

payload n bytes


这个log entries并非由一个文件构成,而是分成多个segment,每个segment以该segment第一条消息的offset命名并以“.kafka”为后缀。另外会有一个索引文件,它标明了每个segment下包含的log entryoffset范围,如下图所示。



因为每条消息都被append到该Partition中,属于顺序写磁盘,因此效率非常高(经验证,顺序写磁盘效率比随机写内存还要高,这是Kafka高吞吐率的一个很重要的保证)。


对于传统的message queue而言,一般会删除已经被消费的消息,而Kafka集群会保留所有的消息,无论其被消费与否。当然,因为磁盘限制,不可能永久保留所有数据(实际上也没必要),因此Kafka提供两种策略删除旧数据。一是基于时间,二是基于Partition文件大小。例如可以通过配置$KAFKA_HOME/config/server.properties,让Kafka删除一周前的数据,也可在Partition文件超过1GB时删除旧数据,配置如下所示。


# The minimum age of a log file to be eligible for deletion
log.retention.hours=168
# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741824
# The interval at which log segments are checked to see if they can be deleted according to the retention policies
log.retention.check.interval.ms=300000
# If log.cleaner.enable=true is set the cleaner will be enabled and individual logs can then be marked for log compaction.
log.cleaner.enable=false


这里要注意,因为Kafka读取特定消息的时间复杂度为O(1),即与文件大小无关,所以这里删除过期文件与提高Kafka性能无关。选择怎样的删除策略只与磁盘以及具体的需求有关。另外,Kafka会为每一个Consumer Group保留一些metadata信息——当前消费的消息的position,也即offset。这个offsetConsumer控制。正常情况下Consumer会在消费完一条消息后递增该offset。当然,Consumer也可将offset设成一个较小的值,重新消费一些消息。因为offetConsumer控制,所以Kafka broker是无状态的,它不需要标记哪些消息被哪些消费过,也不需要通过broker去保证同一个Consumer Group只有一个Consumer能消费某一条消息,因此也就不需要锁机制,这也为Kafka的高吞吐率提供了有力保障。



本文转自:http://www.jasongj.com/2015/03/10/KafkaColumn1/


相关问答

更多

mysql传入到Kafka中的数据结构如何查看

private function loaderHandler(event:*):void { switch(event.type) { case Event.COMPLETE: trace(_loader.data.result); break; case Event.OPEN: trace("open: " + event); break; case ProgressEvent.PROGRESS: trace("progress: " + event); break;

项目中的关系型转换成redis存储怎么数据结构怎么转换的

通常用,redis 的 hash 数据结构来存储关系数据库,如果是 my SQL,有批处理可以直接命令导入

项目中的关系型转换成redis存储怎么数据结构怎么转换的

通常用,redis 的 hash 数据结构来存储关系数据库,如果是 my SQL,有批处理可以直接命令导入

mongodb存储数据和文档存储数据的区别?

MongoDB是文档型的行存储,行存储的读写过程是一致的,都是从第一列开始,到最后一列结束。行存储的写入是一次性完成,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产生冗余数据,如果只有少量数据,此影响可以忽略;数量大可能会影响到数据的处理效率。使用“文档”这个词似乎让人觉得奇怪,但是其实 “文档型数据模型”真的和传统意义的“文档”没有什么关系。这里说的“文档”其实是一个数据记录,这个记录能够对包含的数据类型和内容进行“自我描述”。 另外如果你用文档的话,查询,检索效率不高 ...

mongodb存储数据和文档存储数据的区别?

MongoDB是文档型的行存储,行存储的读写过程是一致的,都是从第一列开始,到最后一列结束。行存储的写入是一次性完成,消耗的时间比列存储少,并且能够保证数据的完整性,缺点是数据读取过程中会产生冗余数据,如果只有少量数据,此影响可以忽略;数量大可能会影响到数据的处理效率。使用“文档”这个词似乎让人觉得奇怪,但是其实 “文档型数据模型”真的和传统意义的“文档”没有什么关系。这里说的“文档”其实是一个数据记录,这个记录能够对包含的数据类型和内容进行“自我描述”。 另外如果你用文档的话,查询,检索效率不高 ...

专题教程

JAVA概述
第一部分:java入门基础
第二部分:java常用类
第三部分:jdbc系列教程
第四部分:java高级特征
Gson教程
快速了解 jdk8 新特征

相关文章

更多

最近更新

更多