6

如果我使用的是 Kafka 异步生产者,假设缓冲区中有 X 条消息。当它们在客户端实际处理时,如果代理或特定分区关闭了一段时间,kafka 客户端将重试,如果一条消息失败,它是否会将特定消息标记为失败并继续下一条消息(这可能导致乱序消息)?或者,为了保持顺序,它是否会使批处理中的剩余消息失败?

我接下来要保持顺序,所以理想情况下希望 kafka 从失败的地方使批次失败,所以我可以从失败点重试,我将如何实现?

4

2 回答 2

1

就像它在关于重试的kafka文档中所说的那样

设置大于零的值将导致客户端重新发送发送失败并可能出现暂时性错误的任何记录。请注意,此重试与客户端在收到错误后重新发送记录没有什么不同。允许重试可能会改变记录的顺序,因为如果将两条记录发送到单个分区,并且第一条记录失败并被重试,但第二条记录成功,那么第二条记录可能首先出现。

因此,回答您的标题问题,没有 kafka 在异步发送下没有订单保证。


我正在根据彼得戴维斯的问题更新答案。

我认为,如果您想以批处理模式发送,保护它的唯一方法是设置, max.in.flight.requests.per.connection=1但正如文档所述:

请注意,如果此设置设置为大于 1 并且发送失败,则存在由于重试(即,如果启用重试)而导致消息重新排序的风险。

于 2016-02-08T13:54:49.770 回答
0

从 Kafka 0.11.0 开始,有记录enable.idempotence的设置。

enable.idempotence:当设置为true时,生产者将确保每条消息的副本都写入流中。如果false,生产者由于代理失败等原因重试,可能会在流中写入重试消息的副本。请注意,启用幂等性要求max.in.flight.requests.per.connection小于或等于5,重试次数大于 0 且acks必须为all。如果用户没有明确设置这些值,则将选择合适的值。如果设置了不兼容的值,ConfigException将抛出 a。

Type: boolean Default: false

这将保证消息是有序的,并且在生产者会话期间不会发生丢失。不幸的是,生产者无法设置序列 ID,因此 Kafka 只能在每个生产者会话中做出这些保证。

如果您需要设置序列 id,请查看 Apache Pulsar,这将允许您使用外部序列 id,这将保证在代理和生产者故障转移之间进行有序且一次性的消息传递。

于 2020-03-07T00:31:23.523 回答