Kafka Async Producer在故障期间如何保证订购?

时间:2016-02-08 04:16:36

标签: apache-kafka kafka-producer-api

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

我接下来要维护订单,所以理想情况下希望kafka从批次失败的地方失败,所以我可以从失败点重试,我将如何实现?

2 个答案:

答案 0 :(得分:2)

就像kafka文档中关于重试

的说法一样
  

设置大于零的值将导致客户端重新发送任何值   记录的发送失败并带有潜在的瞬态错误。注意   这种重试与客户对记录不满意情况没有什么不同   收到错误。允许重试可能会改变   记录的排序,因为如果将两个记录发送到单个记录   分区,第一个失败并重试,但第二个成功,   那么第二条记录可能会先出现。

所以,回答你的标题问题,没有kafka在异步发送下没有订单保证。

我根据Peter Davis的问题更新答案。

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

  

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

答案 1 :(得分:0)

从Kafka 0.11.0开始,有enable.idempotence设置为documented

enable。幂等:设置为true时,制作人将确保 每条消息的一个副本恰好写入流中。如果false, 由于经纪人失误等导致生产者重试,可能会重复 流中重试的消息。请注意,启用幂等 要求max.in.flight.requests.per.connection小于或 等于5,请重试大于0,并且acks必须为all。如果 这些值不是用户明确设置的,合适的值将 被选中。如果设置了不兼容的值,则ConfigException将是 抛出。

Type: boolean Default: false

这将确保按顺序订购消息,并且在生产者会话期间不会造成任何损失。不幸的是,生产者无法设置序列ID,因此Kafka只能在每个生产者会话中做出这些保证。

如果需要使用set the sequence id,请查看Apache Pulsar,这将允许您使用外部序列ID,这将确保在代理和生产者故障转移之间的消息传递是有序且一次的。