topic 从 6 个分区扩到 12 个,同一订单号的两条消息处理顺序反了,状态被旧消息盖回去。日志里能对上时间点,这种反而好排。

分区数一变 key 取模的映射整体改变,同一个 key 落到新分区,历史消息还留在旧分区,两边消费进度不同就会出现乱序。这一点先确认清楚,后面就不用反复试。

kafka-topics.sh --alter --topic order-event \
  --partitions 12 --bootstrap-server 127.0.0.1:9092
kafka-reassign-partitions.sh \
  --reassignment-json-file plan.json \
  --execute --bootstrap-server 127.0.0.1:9092

「Kafka 分区顺序」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

处理上按这个顺序:先确认业务是不是真的依赖同一个 key 严格有序;必须保序就新建 topic 按新分区数整体迁移 不要原地扩;消费端按主键比较版本号 用旧消息兜底不乱写。

结果对不对很好判断,同一订单的状态变更按时间先后落地,抽查十条都没有倒序。

作者 9823189