Spring Kafka 的偏移量到底什么时候提交?AckMode 选哪个?进程被杀之后会重复处理几条?MANUAL 里 ack 了为什么偏移量没动?concurrency 设成 10 就能 10 倍并发吗?这篇在 Spring Kafka 4.0.7 和真实的 Kafka 上逐项实测。
[BATCH(默认)] 开始处理后 1.0 秒:已处理完 3 条,已提交偏移量 None;全部处理完(10 条)之后已提交偏移量 10 [RECORD] 开始处理后 1.0 秒:已处理完 3 条,已提交偏移量 3;全部处理完(10 条)之后已提交偏移量 10 [MANUAL(处理完调用 ack.acknowledge())] 开始处理后 1.0 秒:已处理完 3 条,已提交偏移量 None;全部处理完(10 条)之后已提交偏移量 10 [MANUAL_IMMEDIATE(处理完调用 ack.acknowledge())] 开始处理后 1.0 秒:已处理完 3 条,已提交偏移量 3;全部处理完(10 条)之后已提交偏移量 10 [MANUAL 但代码里忘了确认] 开始处理后 1.0 秒:已处理完 3 条,已提交偏移量 None;全部处理完(10 条)之后已提交偏移量 None
BATCH、RECORD、MANUAL、MANUAL_IMMEDIATE 的提交时刻各不相同。
[BATCH(默认)] 被杀前开始处理 [0, 1, 2, 3]、处理完 [0, 1, 2],此时已提交偏移量 None;重启后开始处理 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];被重复处理的 [0, 1, 2, 3] [RECORD] 被杀前开始处理 [0, 1, 2, 3]、处理完 [0, 1, 2],此时已提交偏移量 3;重启后开始处理 [3, 4, 5, 6, 7, 8, 9];被重复处理的 [3] [MANUAL(处理完确认)] 被杀前开始处理 [0, 1, 2, 3]、处理完 [0, 1, 2],此时已提交偏移量 None;重启后开始处理 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];被重复处理的 [0, 1, 2, 3] [MANUAL_IMMEDIATE(处理完确认)] 被杀前开始处理 [0, 1, 2, 3]、处理完 [0, 1, 2],此时已提交偏移量 3;重启后开始处理 [3, 4, 5, 6, 7, 8, 9];被重复处理的 [3]
提交越勤重复越少,正在处理的一条一定重复。
concurrency=1:30 条消息在分区上的分布 {'p0': 8, 'p1': 12, 'p2': 10};参与的消费者线程 1 个,每个线程处理的分区与条数 [(['p0', 'p1', 'p2'], 30)]
concurrency=3:30 条消息在分区上的分布 {'p0': 8, 'p1': 12, 'p2': 10};参与的消费者线程 3 个,每个线程处理的分区与条数 [(['p0'], 8), (['p1'], 12), (['p2'], 10)]
concurrency=5:30 条消息在分区上的分布 {'p0': 8, 'p1': 12, 'p2': 10};参与的消费者线程 3 个,每个线程处理的分区与条数 [(['p0'], 8), (['p1'], 12), (['p2'], 10)]上限是分区数。