【问题标题】:Reliable fire-n-forget Kafka producer implementation strategy可靠的 fire-n-forget Kafka producer 实现策略
【发布时间】:2017-06-01 01:21:10
【问题描述】:

我正在处理 Kafka 的第一英里问题。每个人都处理分区等问题,但是如何处理第一英里?

我的系统由许多应用程序组成,这些应用程序产生分布在节点上的事件。我需要以可靠/故障安全的方式将这些事件传递给一组充当消费者的应用程序。选择的消息传递系统是 Kafka(由于它的日志性质),但它并不是一成不变的。

事件应尽可能以解耦的即发即弃的方式传播。这意味着生产者应该对可靠地传递他们的消息负全部责任。这意味着产生事件的应用根本不应该担心事件传递。

生产者的可靠性模式必须考虑:

  • 盒子连接中断 - 在中断期间生产者根本无法访问网络;因此无法访问 Kafka 集群
  • box restart - 生产者和事件生产应用程序重启(独立);生产者应该保留正在进行的消息(在重试、批处理等期间)
  • 内部 Kafka 异常 - 消息太大;序列化异常;等

到目前为止,我检查过的任何库都没有涵盖这些情况。有没有建议的策略来解决这个问题?

我知道在 Producer 的send() 期间存在可重试和不可重试错误。对于那些可重试的,库通常在内部处理所有事情。但是,不可重试以异步回调中的异常结束...

我应该盲目地把这些回放到无穷大吗?对于网络中断,它应该可以工作,但是 Kafka 内部错误怎么样——比如消息太大。可能存在类似 DeadLetterQueue 的机制 + 重放。但是,如何处理消息计数...

关于持久性——一个轻量级的数据库后端应该可以解决这个问题。只需创建一个持久队列,然后删除那些已经发送/确认的。但是,如果它这么简单,恐怕很久以前它就已经在标准的 Kafka 库中实现了。性能可能会下降。

看到KAFKA-3686 或KAFKA-1955 之类的东西让我有点担心。

提前致谢。

【问题讨论】:

    标签: apache-kafka message-queue messaging reliability producer


    【解决方案1】:

    我们有一个生产系统,其主要用例是可靠的消息传递。我不能详细介绍,但是我可以分享我们如何实现这一点的高级设计。然而,这个系统保证了“至少一次交付”的消息语义。

    来源

    • 首先我们设计了一个消息模式,并将所有的消息发送到这个 系统必须遵循它。
    • 然后我们将消息写入一个mysql消息表,该表被分片 日期,带有标记为已交付或未交付的字段
    • 我们有一个应用程序不断轮询 db,行标记为未传递,拿起一行,构造消息并将其发送到负载均衡器,这是一个阻塞调用和 将消息行更新为已传递,仅在返回 200 时 在 5xx 的情况下,应用程序将在休眠后重试消息。您还可以根据需要配置重试次数。

    每个源系统都维护自己的轮询应用程序和数据库。

    生产者数组

    • 这基本上是负载平衡器下的一组机器等待传入消息并将这些消息生成到 Kafka 集群。
    • 我们为每个主题维护 3 个副本,并在生产者配置中保留 acks = -1 ,这对于您的即发即弃的要求非常重要。根据文档

    acks=all 这意味着领导者将等待完整的同步 副本以确认记录。这保证了记录 只要至少保留一个同步副本就不会丢失 活。这是最有力的保证。这是等价的 到 acks=-1 设置

    • 正如我所说的,producer 是一个阻塞调用,如果消息在所有 3 个副本中成功生成,它将返回 2xx。 4xx,如果消息不符合架构要求 5xx,如果 kafka 代理抛出异常。

    消费者数组

    • 这是一个正常的机器阵列,为主题的消费者组运行 Kafka 高级消费者。

    我们目前正在为生产中的一些其他功能流程运行这个设置,其中包含很少的附加组件,从源代码的角度来看,它基本上是“即火即忘”。

    这个系统解决了您的所有顾虑。

    1. 盒子连接中断:除非源轮询应用程序获得 2xx,否则它 将再次生成,这可能会导致重复。

    2. 盒子重启:由于源的重试机制,这也应该不是问题。

    3. 内部 Kafka 异常:注意通过轮询应用程序,因为生产者数组将回复 5xx 无法生产,并将进一步重试。

    Acks = -1,还确保所有副本都同步并拥有消息副本,因此代理宕机也不会成为问题。

    【讨论】:

    • 感谢您的回复。但是,我可以看到 MySQL 部分的弱点。当源 MySQL 死机、必须维护、升级等时,事件会发生什么?
    • @Yuri,MySQL 需要维护,但是主从集应该足够好......但是在所有数据存储中,mysql 需要最少的维护。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2021-10-12
    相关资源
    最近更新 更多