目录
2、Message retention and expiry 消息保留和过期
(1)Producer idempotency 生产者的幂等性
(2)Deduplication and effectively-once semantics 去重和一次有效
4、Delayed message delivery 消息延迟传递
1、Message deduplication 消息重传
Apache Pulsar 能很好的进行故障处理,确保关键数据不会丢失。软件总是会有意外的情况,有时候 pulsar 中的消息可能也无法传递成功。因此,建立一套处理故障的内置机制非常重要,尤其是在异步传递消息时,意外的情况如下:
- 当消费者与数据库或 HTTP 服务器断开连接时,消费者不能将数据写入数据库,同时也不能调用外部的 HTTP 服务器。// 数据没被消费
- 消费者因为崩溃、连接中断等原因,与代理(broker)断连。此时,未确认的消息会被传递给其他可用的消费者。// 数据可能被重复消费
Apache Pulsar 使用至少一次传递机制来避免消息传递失败,同时确保 Pulsar 可以多次处理消息。
使用消息重传,需要启用消息重传机制,然后代理才能重新发送未确认的消息。您可以通过以下三种方式触发消息重传:
- Negative Acknowledgment // 否定确认
- Acknowledgement Timeout // 超时确认
- Retry letter topic // 重传消息主题
2、Message retention and expiry 消息保留和过期
默认情况下,Pulsar brokers 会执行以下两个操作:
- 立即删除消费者已经确认的所有消息
- 把所有未确认的消息持久化到消息的 backlog 日志中
但是,Pulsar 有两个特性可以让你覆盖此默认行为:// 配置自定义的消息持久化策略
- 消息保留策略(Message retention)可以让 pulsar 存储消费者已确认过的消息
- 消息过期策略(Message expiry)可以为尚未确认的消息设置过期时间(TTL)
消息保留和过期策略都在命名空间级别进行管理。有关操作方法,请参阅 Message retention and expiry cookbook。
下图说明了这两个概念:
顶部展示的是消息保留策略,该策略作用于命名空间下的所有消息,即使某些消息已经被确认过,也会持久存储在 Pulsar 中。没有被保留策略覆盖的已确认过的消息将会被删除。
底部展示的是消息过期策略,在该策略下,一些尚未被确认的消息将会被删除。该策略根据命名空间规定的 TTL (过期时间),如果尚未被确认的消息已经过期,这些消息也会被删除(比如,TTL 被设置为 5 分钟,而尚未被确认的消息已经存在了 10 分钟)。
3、Message deduplication 消息去重
当 Pulsar 多次持久化同一条消息时会触发消息去重。消息去重是 Pulsar 的可选功能,为了避免消息重复,一条消息被接收了多次的情况下,pulsar 也只会对这条消息处理一次。
禁用消息去重的情况:// 重复持久化数据
启用消息去重的情况:// 只持久化一次数据
在禁用消息去重场景中,生产者发布了一个主题的消息 Message -1;消息到达 Pulsar broker ,并保存到 BookKeeper 。然后,生产者再次发送 Message -1(由于某种重传逻辑),消息被代理接收并再次存储在 BookKeeper 中,这意味着发生了消息重复。
在第二个场景中,启用消息去重,生产者发布 Message -1,Message -1 由代理接收并持久化,如第一个场景中所示。然而,当生产者再次尝试发布 Message -1 时,代理知道它已经收到过 Message -1,因此不会再持久化该消息。
消息去重是在命名空间级别或主题级别处理的。有关更多说明,请参阅消息去重文档。你可以在 PIP-6 中阅读消息去重的设计。
(1)Producer idempotency 生产者的幂等性
另一种可用的消息去重方式是确保每条消息只生产一次。这种方式通常称为生产者的幂等性。但是,该方式的缺点是,它将消息去重工作放到了应用程序。在 Pulsar 中,生产者的幂等性是在代理(broker)级别处理的,因此无需修改 Pulsar 客户端代码。相反,你只需要进行管理方式的更改。有关详细信息,请参阅 Managing message deduplication。
(2)Deduplication and effectively-once semantics 去重和一次有效
消息去重使得 Pulsar 可以作为一个非常不错的消息处理系统,跟流处理引擎(SPE)一样,能够和其他具备消息去重要求的系统相结合使用。那些不提供自动消息去重的消息系统,都需要借助流处理引擎(SPE)或其他系统来保证消息去重,这样意味着,消息去重是以加重应用程序负担为的代价的。而使用 Pulsar 中,消息去重并不会带来任何应用程序级别的成本。
你可以在这篇文章中找到更深入的信息。// 有关于一次有效的更深层次的探讨
4、Delayed message delivery 消息延迟传递
消息延迟传递可以够使消息延迟消费。在这种机制下,消息存储在 BookKeeper 中。当消息发布到代理之后,DelayedDeliveryTracker 在内存中维护了时间索引(time->messageId)。一旦指定的延迟时间结束,该消息将会传递给消费者。// 定时传递
消息延迟传递仅在共享订阅类型(Shared )中有效。在独占和容错订阅类型中,会立即发送延迟消息(也就是说,不存在消息延迟)。
下图说明了消息延迟传递的概念:
代理(broker)无需任何检查即可保存消息。当消费者消费消息时,如果消息是延迟消息,则会把消息添加到 DelayedDeliveryTracker(延迟传递跟踪器)。订阅会检查并从 DelayedDeliveryTracker 中获取超时消息。// 也就是,说维护消息延迟是由订阅去做的,跟 broker 无关。
(1)Broker 代理
pulsar 默认开启消息延迟传递机制。你也可以在 broker 的配置文件中更改它,如下所示:
# Whether to enable the delayed delivery for messages.
# If disabled, messages are immediately delivered and there is no tracking overhead.
delayedDeliveryEnabled=true
# Control the ticking time for the retry of delayed message delivery,
# affecting the accuracy of the delivery time compared to the scheduled time.
# Default is 1 second.
delayedDeliveryTickTimeMillis=1000
(2)Producer 生产者
以下是使用 Java 代码的生产者消息延迟传递的示例:
// message to be delivered at the configured delay interval
producer.newMessage().deliverAfter(3L, TimeUnit.Minute).value("Hello Pulsar!").send();
至此,全文结束。