【问题标题】:Apache Pulsar message delivery semanticsApache Pulsar 消息传递语义
【发布时间】:2020-08-14 22:29:48
【问题描述】:

我浏览了有关消息传递语义的 Apache Pulsar 文档。 Apache函数提到的传递语义(至少一次,最多一次和一次有效),如果我们不使用Apache函数,那么有哪些不同的传递语义可用?

【问题讨论】:

    标签: queue message-queue apache-pulsar


    【解决方案1】:

    TL;DR:如今,Pulsar Functions、Pulsar+Spark (you will see duplicates) 和 Pulsar+Flink (you will see duplicates) 均不支持有效一次性语义又名 exactly-once 语义。只有在某些边缘情况下,您才能通过 DIY 设置手动实现此类语义。 Pulsar 目前支持的是 (1) at-most-once 语义 = 你可能会丢失数据和 (2) at-least-once 语义 = 你不会丢失数据但可能会看到重复。

    关于(3)一次有效的支持:我当然可以想象你一直很困惑。尽管 Pulsar 文档中声称支持有效的一次性语义,并且有几篇(不幸的是,误导性的)关于该主题的博客文章 (example),但 Pulsar 实际上并不支持这一点。 Pulsar 支持的是幂等生产者和消息的重复数据删除。这个功能确实是必需的,但是 - 这是重要的方面 - 对于完全一次语义来说,这足够。当前功能仅在生成一条消息且仅针对一个分区时才有效。例如,您现在无法使用 Pulsar 原子地向一个分区生成多条消息,更不用说多个分区了。这也意味着与状态的交互(例如,用于聚合数据,如计数、在数据流之间执行连接)不是一次性的。

    缺少什么,Pulsar 何时支持完全一次语义? 为了保证完全一次语义,Pulsar 必须首先添加对事务的支持。这确实是 2020 年 6 月发布的 Pulsar 2.6.0 原始 ETA 的计划功能,但截至今天有still a lot of work left to be done。恐怕我不知道有更新的预计到达时间。

    在哪里了解更多信息: 更详细地了解这一点的一个很好的 Pulsar 特定来源是 Pulsar 提交者在 2019 年 12 月的演示文稿Apache Pulsar: Transactions Preview,它总结了当前缺乏完全一次支持并解释了为什么需要支持 Pulsar 中的事务才能实现它。

    另一个理解这个棘手主题的好来源是这个由 3 部分组成的文章系列,关于 Apache Kafka(博客系列 part1part2part3)如何提供精确一次语义,这是一种类似于 Apache Pulsar 的技术。该系列解释了为什么幂等生产者只是难题的一部分,为什么需要事务(利用前者),以及如何在 Apache Kafka 中设计和实现它,并于 2017 年发布。这就是为什么您可以从确切中受益 -在 Kafka 中处理数据时的一次语义,例如Kafka Streams(包含在 Kafka 中)或 Kafka and Apache Flink。如果您查看 Pulsar 在 2020 年引入精确一次性支持的计划和路线图,您可以清楚地看到与 Kafka 的方法非常相似的地方。作为用户,显着的区别在于 Kafka 一次性发布了所有功能(这也解释了为什么 Kafka 社区需要花费数年时间来设计、构建和测试该功能),而不是逐个发布,更清楚地了解实际支持的内容与不支持的内容。

    免责声明:我为 Confluent 工作,这是为 Apache Kafka 做出贡献的公司之一。

    【讨论】:

      【解决方案2】:

      您可以实现您列出的所有消息传递语义,包括至少一次、最多一次和有效一次。

      最多一次,您将使用独占订阅类型来确保只有消费者收到消息,并让您的消费者确认收到的所有消息,无论是否发生异常。

      对于一次有效,您将使用独占订阅类型来确保只有消费者才能获得消息,并且只有在您能够成功处理消息(即没有异常等)时才发送确认,否则,您会否定确认消息以使其重新发送。

      所有其他行为组合都属于至少一次交付保证。

      https://pulsar.apache.org/docs/en/2.5.1/concepts-messaging/#consumers

      【讨论】:

      • 你所说的“有效一次”似乎是“至少一次”:如果消息被成功处理,并且客户端在它可以发送确认之前失败(如果客户端发送确认但它丢失了),消息将在我的理解恢复后传递给客户端。
      • 您是正确的,消息将被重新传递,这可以通过使用本博客中描述的生产者幂等性轻松处理(splunk.com/en_us/blog/it/…
      • producer幂等性如何避免多次读取消息?如果我有一个简单的消费者应用程序,那么就没有生产者。 -- 如果消息被重新传递,它至少是一次。
      • 使用消费者只需要处理一次消息的应用程序将不得不依赖某些外部系统来执行最终的重复数据删除。使用 Pulsar Reader API,应用程序可以将与最后成功处理的消息相关联的消息 ID 存储在外部系统中,并读取该值以知道从哪里恢复处理。对于生产者幂等性,我的意思是整个系统需要能够识别和丢弃已经发布的消息,并防止它们被重传(恢复后)
      【解决方案3】:

      Pulsar 提供至少一次语义。它还可以删除对其日志的重复写入(称为幂等生产),并且可以使用外部数据存储(与其他消息传递系统一样)有效地合成消费。对于自给自足的有效/精确一次处理,例如进行流处理,您需要使用 Kafka 或 Flink。

      【讨论】:

      猜你喜欢
      • 2022-11-02
      • 1970-01-01
      • 2019-11-19
      • 2020-03-12
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      相关资源
      最近更新 更多