【问题标题】:What is the best practice to retry messages from Dead letter Queue for Kafka从 Kafka 死信队列重试消息的最佳实践是什么
【发布时间】:2021-04-21 03:26:37
【问题描述】:

我们使用 Kafka 作为微服务之间的消息传递系统。我们有一个 kafka 消费者监听一个特定的主题,然后将数据发布到另一个主题,由 Kafka 连接器获取,后者负责将其发布到一些数据存储中。

我们使用 Apache Avro 作为序列化机制。

我们需要启用 DLQ 来为 Kafka Consumer 和 Kafka Connector 添加容错功能。

由于多种原因,任何消息都可能移至 DLQ:

  1. 格式错误
  2. 错误数据
  3. 对大量消息进行限制,因此某些消息可能会移动到 DLQ
  4. 由于连接,发布到数据存储失败。

对于上述第 3 点和第 4 点,我们想从 DLQ 再次重试消息。

最好的做法是什么。请指教。

【问题讨论】:

    标签: apache-kafka error-handling


    【解决方案1】:

    仅推送到导致不可重试错误的 DLQ 记录,即:您的示例中的第 1 点(错误格式)和第 2 点(错误数据)。对于 DLQ 记录的格式,一个好的方法是:

    • 将与原始记录完全相同的 kafka 记录值和密钥推送到 DLQ,不要将其包装在任何类型的信封中。这使得在故障排除期间使用其他工具重新处理变得更加容易(例如,使用新版本的反序列化器等)。
    • 添加一堆 Kafka 标头来传达有关错误的元数据,一些典型的例子是:
      • 这条记录的原始主题名称、分区、偏移量和Kafka时间戳
      • 异常或错误消息
      • 未能处理该记录的应用程序的名称和版本
      • 出错时间

    通常我为每个服务或应用程序使用一个 DLQ 主题(不是每个入站主题一个,而不是跨服务共享的主题)。这往往会使事情保持独立和易于管理。

    哦,您可能希望对 DLQ 主题的入站流量进行一些监控和警报;)

    第 3 点(高容量),恕我直言,应该处理某种自动缩放,而不是使用 DLQ。尝试总是高估(一点)输入主题的分区数,因为您可以启动服务的最大实例数受此限制。过多的消息不会使您的服务过载,因为 Kafka 消费者在决定时会明确轮询更多消息,因此他们永远不会要求超出应用程序处理能力的更多消息。如果消息达到高峰会发生什么,只是它们会继续堆积在上游 kafka 主题中。

    第 4 点(连接)应直接从源主题重试,不涉及任何 DLQ,因为错误是暂时的。将消息丢弃到 DLQ 并获取下一条消息不会解决任何问题,因为连接问题仍然存在,并且下一条消息也可能会被丢弃。读取或不读取来自 Kafka 的记录不会让它消失,因此存储在那里的记录很容易稍后再次读取。只有当服务成功将结果记录写入出站主题时,您才能对服务进行编程以前进到下一个入站记录(请参阅 Kafka 事务:读取主题实际上涉及 write 操作,因为新消费者偏移量需要被持久化,因此您可以告诉您的程序将新的偏移量和输出记录作为同一原子事务的一部分持久化。

    Kafka 更像是一个存储系统(只有 2 个操作:顺序读取和顺序写入)而不是消息队列,它擅长持久性、数据复制、吞吐量、规模......(......和炒作;)) .它往往非常适合将数据表示为一系列事件,例如“事件溯源”。如果此微服务设置的需求主要是异步点对点消息传递,并且如果大多数场景更倾向于超低延迟并选择丢弃消息而不是重新处理旧消息(如列出的 4 点所示),那么也许像 Redis 队列这样的有损内存队列系统更合适?

    【讨论】:

    • 感谢您的详细回答。如果 DLQ 不是重试消息的理想场所,那么在这里创建一个重试主题怎么样。另外,我们应该重试多少次消息,比如说 3 或 5 次。如果它仍然失败,我们应该把它移到 DLQ 吗?
    • 嗨,Arupc。我认为如果服务从topicA 读取并写入topicB,那么topicA 已经是一个重试主题:之前读取的记录,比如连接问题,仍然存在并且可以从那里重试,不需要 DQL。请注意,对于写入topicB,重试机制已经是 kafka 生产者的一部分,您可以简单地设置 retriesretry.backoff.ms 参数(当然,这仅适用于写入 kafka 时)。我会设置大量的reties,可能是100000左右?,s.t. num_of_retries * retry_interval > time_it_takes_to_fix_connectivity_issue.
    猜你喜欢
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 2020-02-03
    • 2011-01-01
    • 2017-09-29
    • 2023-04-07
    相关资源
    最近更新 更多