Kakfa同一主题下不同分区包含的消息不同

Kakfa同一主题下不同分区包含的消息不同

这是Kafka设计核心机制之一:
Kafka 主题(Topic)下不同分区(Partition)存储的是完全不同的消息。它们共同组成了整个主题的数据集,但每个分区都是该数据集的一个独立子集。

可以把Kafka主题想象成一个逻辑上的信息流(如:AA),这个巨大的消息流为了能够并行处理和水平扩展,被切分成了许多的分区。

1、分区是物理存储的基本单位

  1. 每个分区对应物理上一个文件夹(例如:topic-AA-0、topic-AA-1)存储在Kafka的日志目录下
  2. 每个分区都是一个独立、不可变的消息序列
  3. 消息在分区内会被分配一个唯一的、递增的偏移量(Offset),用于标记其位置

2、消息如何分配到不同分区

生产者发送消息时,决定消息进入哪个分区,规则如下:

  1. 指定分区(Partition):生产者可以直接指定目标分区
  2. 指定消息键(Key):生产者给消息设置一个key,Kafka对这个key进行哈希计算,根据hash值把同一个key的消息路由到同一个分区
    好处:保证所有具有相同key的消息存储在同一个分区,并且保持严格的顺序
  3. 不指定Key(Round-Robin):生产者轮询的方式将消息依次发送到主题的各个分区,以实现负载均衡

3、消费者如何消费?

  1. 消费者以消费者组(Consumer Group)的形式工作
  2. Kafka会将一个主题的所有分区 分配给组内的各个消费者实例。一个分区同一时间只能被同一个消费者组内的一个消费者消费
  3. 这样组内的多个消费者就可以并行的从不同分区读取消息,极大提高吞吐量
  4. 因为分区内的消息是有序的,而单个消费者按顺序消费一个分区,所以它能保证该分区消息的顺序性

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、要点总结

  1. 数据不同:不同分区包含的消息是完全不同的,它们是整个主题数据的子集
  2. 顺序保证:分区内的消息是有序的,通过offset保证,offset不跨分区
  3. 并行性:分区是Kafka 并行处理的最小单位,多个消费者可以同时从不同分区读取,提高吞吐量
  4. 扩展性:增加分区水平扩展主题的吞吐量和容量
  5. 消息键(Key):使用消息键可以确保相关消息被写入同一分区,保证局部有序性

通过主题逻辑统一,分区分而治之,kafka实现了高吞吐、低延迟、高可扩展性。

posted @ 2025-09-11 15:54  hqq的进阶日记  阅读(8)  评论(0)    收藏  举报