首先单Toptic单分区的情况下,并不是天然有序的吧?应该根据版本来配置
1)kafka在1.x版本之前保证数据单分区有序,条件如下:
max.in.flight.requests.per.connection=1(不需要考虑是否开启幂等性)。 2)kafka在1.x及以后版本保证数据单分区有序,条件如下:
(1)开启幂等性
max.in.flight.requests.per.connection需要设置小于等于5。
(2)未开启幂等性
max.in.flight.requests.per.connection需要设置为1。
原因说明:因为在kafka1.x以后,启用幂等后,kafka服务端会缓存producer发来的最近5个request的元数据,
故无论如何,都可以保证最近5个request的数据都是有序的。
以上说明然后再结合官网的配置说明,我就懵逼了,以下是官网的配置说明
retries:若设置大于0的值,则客户端会将发送失败的记录重新发送,尽管这些记录有可能是暂时性的错误。请注意,这种 retry 与客户端收到错误信息之后重新发送记录并无区别。允许 retries 并且没有设置max.in.flight.requests.per.connection 为1时,记录的顺序可能会被改变。比如:当两个批次都被发送到同一个 partition ,第一个批次发生错误并发生 retries 而第二个批次已经成功,则第二个批次的记录就会先于第一个批次出现。
enable.idempotence:当设置为true时, Producer 将确保每个消息在 Stream 中只写入一个副本。如果为false,由于 Broker 故障导致 Producer 进行重试之类的情况可能会导致消息重复写入到 Stream 中。请注意,启用幂等性需要确保 max.in.flight.requests.per.connection小于或等于5,retries 大于等于0,并且ack必须设置为all 。如果这些值不是由用户明确设置的,那么将自动选择合适的值。如果设置了不兼容的值,则将抛出一个ConfigException的异常。
max.in.flight.requests.per.connection :在发生阻塞之前,客户端的一个连接上允许出现未确认请求的最大数量。注意,如果这个设置大于1,并且有失败的发送,则消息可能会由于重试而导致重新排序(如果重试是启用的话)。
我的疑问是:
根据上面那张图,开启幂等性之后,且缓存请求个数小于等于5,请求失败后,则会重试,等重试成功后再重新排序进行磁盘写入,保证消息单会话单分区有序性,那既然会重新排序的话,为什么重试大于0时且保证有序性的情况下还要限制max.in.flight.requests.per.connection 为1呢?为5不也可以保证有序性吗?
举个例子:
正常请求是:1,2,3,4,5
正常入队时是:5,4,3,2,1
假如异常情况下多个请求重试成功后入队(5,4,3均发生重试):5,4,3,2,1,这样不也可以保证有序性吗?