对于Kafka 数据的存储,我们最经常听到的两个概念就是Topic和Partition了,下面就简单介绍下他们在Kafka系统中的意思和作用。
Topic
Topic是Kafka中消息的逻辑分类,每个Topic可有多个Partition
Partition
Partition是Kafka中实际的数据存储单元,每个Partition可以看做一个可以被订阅和消费的消息队列。每个Topic的partition数量在其被创建的时候就会被配置。partition中的消息也会被分成段(segments),以便于查找和定位offset。默认的分段(segment)的大小是1GB,也可以通过配置改变segment的大小。每个segment包含以下文件:
- Log,消息数据存储在这个文件中
- Index:存储消息的offset和起始位置
- Timeindex:时间戳 ? 关系不大
举个例子,在一个partition中有6个消息,而segment的大小正好设置成能够容纳3个消息的大小,这时这个partition包含了三个segments分段,如下所示:
- Segment – 00 contains 00.log, 00.index and 00.timeindex files
- Segment – 03 contains 03.log, 03.index and 03.timeindex files
- Segment – 06 contains 06.log, 06.index and 06.timeindex files
文件名代表分段中第一个消息的offset值。
Starting offset: 0 offset: 0 position: 0 CreateTime: 1533443377944 isvalid: true keysize: -1 valuesize: 11 producerId: -1 headerKeys: [] payload: Hello World offset: 1 position: 79 CreateTime: 1533462689974 isvalid: true keysize: -1 valuesize: 6 producerId: -1 headerKeys: [] payload: Hello World2
上面是log文件的示例。
对于查找消息时间的算法复制度
Step | Complexity |
Find partition | O(1) |
Find segment in partition | O(log (SN, 2)) SN代表segement的数量 |
Find message in segment | O(log (MN, 2)) MN代表log文件里消息的数量 |
因此总的复杂度是: O(1) + O(log (SN, 2)) + O(log (MN, 2)).
复制
每个Topic在创建的时候都可以配置一个复制参数(replication factor)。以确定在集群中的备份数量。
在多个partition的情况下,每个partition会保存为主从结构leader/replicas, Kafka保证任何消费者只能从leader中读取消息,replica会和leader实时同步,是leader的一个备份,replica和leader必须不在同一个broker下存在。这个原因其实非常明显,一旦partition的leader挂掉后,就会有一个replica立刻成为leader,继续给消费者提供消息。
Partition的平行机制。
Kafka只允许一个消费者去读取一个partition,以确保消息读取顺序的正确性。由于一个Topic有多个partition,因此Kafka其实不能保证在Topic层级上的消息读取顺序一致性。如果需要增加对某个topic的消费者数量,那同时也要增加partition的数量。