Kafka保证消息有序时max.in.flight.requests.per.connection最大值为何是5
问题核心解答
1. 你假设的场景不成立的原因
你描述的「序列号1的消息重试时,后续序列号的消息可正常提交成功」的情况不符合Kafka幂等生产者的设计逻辑,不可能发生:
开启enable.idempotence = true后,Kafka broker会为每个<生产者ID(PID), 目标分区>的组合维护下一个期望接收的序列号,只有收到的消息批次的起始序列号刚好等于该期望值时,broker才会允许该批次写入,同时累加期望值。如果前面序列号为1的批次未成功提交,后续序列号更大的批次发送到broker后,会直接被broker抛出OutOfOrderSequenceException拒绝,根本不会出现后续批次先于重试批次提交的情况。
生产者收到后续批次的拒绝响应后,会自动重试这些批次,直到序列号1的批次成功提交后,后续的批次才会被broker正常接收写入。
2. 保证有序性时max.in.flight.requests.per.connection最大值为5的原因
这个阈值是和Kafka broker端的生产者状态缓存规则对齐的:
- broker会为每个<PID, 分区>组合,默认最多缓存最近5个已成功提交的批次的序列号元数据,用来校验重试批次的合法性、避免重复写入。
- 如果
max.in.flight.requests.per.connection设置大于5,就可能出现:前面某个批次重试时,broker已经因为缓存数量上限,清理掉了该批次对应的序列号状态,此时broker无法判断该重试批次是合法请求还是非法乱序请求,要么误拒正常请求,要么导致消息乱序、重复提交。
如果不需要兼顾吞吐量,把max.in.flight.requests.per.connection设置为1,无论是否开启幂等都能保证消息有序,但生产端吞吐量会大幅下降。≤5的阈值范围是官方给出的兼顾有序性、幂等性、吞吐量的最优配置区间。
内容的提问来源于stack exchange,提问作者egS
相关产品推荐
相关产品推荐

