Producer 发事件,不是扔给一个神秘黑盒,而是写到某个 topic 的某个 partition 上。
最常见的分配方式:
- 指定 key:同 key 的消息通常进入同一 partition
- 不指定 key:Kafka 按分区器分配,追求负载均衡
例如:
ProducerRecord<String, String> record =
new ProducerRecord<>("order-events", "order-1001", "{\"status\":\"CREATED\"}");这里 "order-1001" 是 key。它的价值不是“看起来规范”,而是:
让同一个订单的事件尽量落到同一个 partition,从而保住该订单维度的顺序。
#ack 是什么
acks 是 producer 侧的“写入确认等级”。
它问的不是“消费者处理完了吗”,而是:
broker 这边,写入到底确认到什么程度,我才算发送成功?
常见认知可以这样记:
acks |
类比 | 含义 |
|---|---|---|
0 |
喊一声就走 | 不等 broker 确认 |
1 |
主站点头即可 | leader 写入就回 |
all |
同步副本都点头 | 最强的 broker 侧确认 |
这里最容易犯的错是:
把 producer 的 ack,误认为 consumer 的处理确认。
不是一回事。
acks解决“写进去没有”offset commit解决“我读到哪里了”
生产里更常见的基线是:
props.put("acks", "all");
props.put("enable.idempotence", "true");这代表:
- 写入确认更强
- 生产者重试时更不容易写出重复记录
但你仍然不能把它理解成“业务绝对不会重复”。后面我们会讲为什么。