Kakfa同一主题下不同分区包含的消息不同
Kakfa同一主题下不同分区包含的消息不同
这是Kafka设计核心机制之一:
Kafka 主题(Topic)下不同分区(Partition)存储的是完全不同的消息。它们共同组成了整个主题的数据集,但每个分区都是该数据集的一个独立子集。
可以把Kafka主题想象成一个逻辑上的信息流(如:AA),这个巨大的消息流为了能够并行处理和水平扩展,被切分成了许多的分区。
1、分区是物理存储的基本单位
- 每个分区对应物理上一个文件夹(例如:topic-AA-0、topic-AA-1)存储在Kafka的日志目录下
- 每个分区都是一个独立、不可变的消息序列
- 消息在分区内会被分配一个唯一的、递增的偏移量(Offset),用于标记其位置
2、消息如何分配到不同分区
生产者发送消息时,决定消息进入哪个分区,规则如下:
- 指定分区(Partition):生产者可以直接指定目标分区
- 指定消息键(Key):生产者给消息设置一个key,Kafka对这个key进行哈希计算,根据hash值把同一个key的消息路由到同一个分区
好处:保证所有具有相同key的消息存储在同一个分区,并且保持严格的顺序 - 不指定Key(Round-Robin):生产者轮询的方式将消息依次发送到主题的各个分区,以实现负载均衡
3、消费者如何消费?
- 消费者以消费者组(Consumer Group)的形式工作
- Kafka会将一个主题的所有分区 分配给组内的各个消费者实例。一个分区同一时间只能被同一个消费者组内的一个消费者消费
- 这样组内的多个消费者就可以并行的从不同分区读取消息,极大提高吞吐量
- 因为分区内的消息是有序的,而单个消费者按顺序消费一个分区,所以它能保证该分区消息的顺序性
4、举例说明
假设我们有一个主题 order-events,它有 3 个分区(P0, P1, P2)
场景A:生产者发送没有 Key 的消息,不指定分区
- 发送消息 M1, M2, M3, M4, M5...
- 它们可能会被这样分配:
- 分区 P0: M1, M4, ...
- 分区 P1: M2, M5, ...
- 分区 P2: M3, ...
场景B:生产者发送带 Key 的消息(Key=订单ID)
-
发送消息
-
发送消息
-
发送消息 {Key: "order-123", Value: "paid"} // 注意,同一条订单的消息
-
哈希计算后,假设:
- "order-123" 的hash值总是映射到分区P1
- "order-456" 的hash值总是映射到分区P0
-
最终分配结果:
- 分区 P0:
- 分区 P1: {Key: "order-123", Value: "created"},
- 分区 P2: 空
这个例子中,关于order-123 的所有事件(创建、支付)都严格有序地存储在分区P1中。当消费者从P1开始消费,它会先读到"created",再读到"paid",顺序得到保证。
5、要点总结
- 数据不同:不同分区包含的消息是完全不同的,它们是整个主题数据的子集
- 顺序保证:分区内的消息是有序的,通过offset保证,offset不跨分区
- 并行性:分区是Kafka 并行处理的最小单位,多个消费者可以同时从不同分区读取,提高吞吐量
- 扩展性:增加分区水平扩展主题的吞吐量和容量
- 消息键(Key):使用消息键可以确保相关消息被写入同一分区,保证局部有序性
通过主题逻辑统一,分区分而治之,kafka实现了高吞吐、低延迟、高可扩展性。
浙公网安备 33010602011771号