Redis Pub / Sub可靠性

我一直在使用Redis Pub / Sub作为RabbitMQ的替代品。

根据我的理解,Redis的pub / sub持有与每个订户的连接,如果连接终止,所有未来的消息都将丢失并丢弃。

一个可能的解决scheme是使用一个列表(和阻塞等待)来存储所有的消息和pub / sub作为一个通知机制。 我认为这是最让我感到满意的方式,但我仍然对失败案例有所顾虑。

  1. 当一个用户死了,又回到了在线状态,应该怎么处理所有未决的消息呢?
  2. 当系统出现格式错误的消息时,你如何处理这些exception? DeadLetter队列?
  3. 是否有执行重试策略的标准做法?

当用户(消费者)死亡时,您的列表将继续增长,直到客户返回。 一旦达到特定的限制,你的制作者可以修改列表(从任何一方),但这是你需要在应用程序级别处理的东西。 如果在每条消息中包含一个时间戳记,那么假设您在消息时代拥有要执行的应用程序逻辑,那么消费者可以根据消息的年龄进行操作。

我不确定格式错误的消息是如何进入系统的,因为与Redis的连接通常是TCP完整性保证。 但是,如果发生这种情况,可能是由于生产者层的消息编码中存在一个错误,你可以通过保持一个接收消费者exception消息的生产者队列来提供处理错误的一般机制。

重试策略将取决于您的应用程序需求。 如果您需要100%确保已收到并处理消息,则应考虑使用Redis事务(MULTI / EXEC)来封装消费者完成的工作,以确保客户端不会除去消息,除非它已经完成了它的工作。 如果您需要明确的确认,那么您可以在专用于生产者进程的队列上使用明确的ACK消息。

在不了解应用程序需求的情况下,很难知道如何明智地select。 通常,如果您的邮件需要完整的ACID保护,那么您可能还需要使用redis事务。 如果你的消息只在及时的时候才有意义,那么交易可能就不需要了。 这听起来好像你不能容忍丢弃的消息,所以你使用列表的方法是好的。 如果您需要为消息实现优先级队列,则可以使用sorting集(Z命令)来存储消息,并将其优先级用作得分值,同时还有一个轮询消费者。

我所做的是使用一个有序集合,使用时间戳作为分数,以数据的关键字作为成员值。 我用最后一个项目的分数来检索接下来的几个,然后拿到钥匙。 一旦工作完成,我将包含zrem和del在MULTI / EXEC事务中。

爱德华所说的基本上是这样,但是把密钥存储在sorting集合中,因为我的信息可能相当大。

希望这可以帮助!