第 5 章 用订单号理解 Key 和分区
建立三个分区的主题
bin/kafka-topics.sh --bootstrap-server localhost:9092 \
--create --topic orders \
--partitions 3 --replication-factor 1接着启动带 Key 的生产者:
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 \
--topic orders \
--property parse.key=true \
--property key.separator='|'输入以下三行,注意每行中间的 |:
A1001|{"event_id":"e-001","order_id":"A1001","type":"OrderCreated","amount_fen":9900,"schema_version":1}
A1002|{"event_id":"e-002","order_id":"A1002","type":"OrderCreated","amount_fen":2000,"schema_version":1}
A1001|{"event_id":"e-003","order_id":"A1001","type":"OrderPaid","amount_fen":9900,"schema_version":1}
左边是 Key,右边是 Value。金额用“分”的整数表示,避免用二进制浮点数直接表示钱。event_id 标识一次业务事件,order_id 标识一笔订单,两者用途不同。
显示记录位置
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic orders --from-beginning --group orders-inspect-v1 \
--property print.key=true \
--property print.partition=true \
--property print.offset=true你应看到分区、偏移量、Key 和 JSON。观察 A1001 的两个事件:在本书默认分区策略和未改分区数时,它们进入同一分区,偏移量按追加顺序增大。不同订单也可能落入同一分区,Key 与分区不是一对一关系。
不能依赖屏幕显示的三行恰好是发送时的全局顺序,因为消费者从多个分区取数据。也不要背下“A1001 一定进分区几”,分区映射不是业务规则。
业务顺序还有额外条件
把同一订单作为 Key 只是基础。若两个生产者同时写同一订单,“谁先发生”的业务顺序仍需要由上游协调,或者在事件里带业务版本号。消费者若并行处理同一分区,也要保证同一订单的处理顺序。
新增分区可以增加并行度,但可能改变 Key 映射。需要严格保持历史与后续顺序时,应先设计迁移和切换方案,而不是在高峰时随手扩分区。
练习:把 A1001 改成固定 Key all-orders 会怎样?所有这些消息会集中到同一个分区,失去按订单分摊流量的优势。