返回文章列表

文章

Kafka生产者怎么指定分区发送消息

Kafka 生产者发送消息时,可以通过三种方式来指定消息发送到哪个分区,以满足如“同一订单编号消息落到同一分区”等顺序性或分区控制的需求。

目录
  1. Kafka 生产者发送消息时,可以通过三种方式来指定消息发送到哪个分区,以满足如“同一订单编号消息落到同一分区”等顺序性或分区控制的需求。
  2. ✅ 一、三种分区路由策略
  3. ✅ 二、Java 示例:三种方式对比
  4. 1️⃣ 不指定 key(Kafka 自动轮询分区)
  5. 2️⃣ 指定 key(按 key 的 hash 值自动分区)
  6. 3️⃣ 手动指定分区(强制指定 partition)
  7. ✅ 三、Kafka 分区逻辑源码简述
  8. ✅ 四、最佳实践建议
  9. ✅ 五、自定义一个分区器(Partitioner)
  10. 3. Kafka Producer 配置
  11. 4. 生产者服务调用
  12. 5. Web 控制器触发
  13. 6. 打包与运行
  14. POST http://localhost:8080/orders?orderId=123 ``` 你会在控制台看到消息发送到分区 0 或 1。

Kafka 生产者发送消息时,可以通过三种方式来指定消息发送到哪个分区,以满足如“同一订单编号消息落到同一分区”等顺序性或分区控制的需求。#

✅ 一、三种分区路由策略#

方式是否指定 Key分区控制能力使用场景
默认轮询❌ 不指定 KeyKafka 自动轮询分区无顺序要求、负载均衡
基于 Key 哈希✅ 指定 KeyKafka 使用 `key.hashCode()` 决定分区相同 key 保持顺序
手动指定分区✅ 可选 Key完全自定义分区逻辑精细控制分区,例如按用户 ID 分区

✅ 二、Java 示例:三种方式对比#

1️⃣ 不指定 key(Kafka 自动轮询分区)#

ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "hello world");
producer.send(record);

Kafka 会以轮询方式自动将消息分配到不同分区。


2️⃣ 指定 key(按 key 的 hash 值自动分区)#

ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "user123", "message for user123");
producer.send(record);

Kafka 会用 key("user123")的 hashCode 决定分区,相同 key 一定落入同一个分区,保证顺序。


3️⃣ 手动指定分区(强制指定 partition)#

int partition = 2;
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", partition, "user123", "manual partition");
producer.send(record);

消息会被强制发送到分区 2,不受 key 的影响,完全手动控制。


✅ 三、Kafka 分区逻辑源码简述#

Kafka 默认使用如下逻辑确定分区(在没有手动指定分区的情况下):

int partition = (key == null)
    ? randomPartition()
    : Math.abs(key.hashCode()) % numPartitions;


✅ 四、最佳实践建议#

需求建议方式
希望某个 key 的消息顺序性(如订单、用户)使用 key 自动分区(同 key 同分区)
希望均匀负载不指定 key,默认轮询
精细控制路由、数据分区统计手动指定 partition

✅ 五、自定义一个分区器(Partitioner#