2011-05-31 49 views
36

我一直在寻找使用Redis Pub/Sub作为RabbitMQ的替代品。Redis Pub/Sub与可靠性

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

一个可能的解决方案是使用列表(并阻止等待)将所有消息和pub/sub存储为通知机制。我认为这会让我走到最后,但我仍然对失败案例有所担忧。

  1. 当用户死亡并重新联机时会发生什么情况,应该如何处理所有未决消息?
  2. 当系统出现格式错误的信息时,您如何处理这些异常? DeadLetter队列?
  3. 是否有执行重试策略的标准做法?
+0

......我想送位置更新给客户....而一旦断开,我不知道如何客户端和服务器之间的数据同步...你解决问题?如果是的话,怎么样? – 2016-05-14 08:15:18

+0

您可以在http://redis.io/commands/rpoplpush检查一个可靠的队列Redis的模式 – hgf 2014-10-23 01:21:02

回答

28

当用户(消费者)死亡后,您的列表将继续增长,直到客户端返回。一旦达到特定的限制,你的制作人可以调整列表(从任一侧),但这是你需要在应用程序级别处理的事情。如果您在每封邮件中包含时间戳,则假设您在邮件使用年限内拥有要执行的应用程序逻辑,那么您的客户可以根据邮件的年龄进行操作。

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

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

不知道更多关于您的应用程序需求,很难知道如何明智地选择。通常,如果您的消息需要完整的ACID保护,那么您可能还需要使用redis事务。如果您的消息只在及时发送时才有意义,则可能不需要交易。这听起来好像你不能容忍丢弃的消息,所以你使用列表的方法是好的。如果您需要为消息实现优先级队列,则可以使用排序集(Z命令)来存储消息,并将其优先级用作分数值以及轮询消费者。

3

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

本质上是爱德华所说的,但随着密钥存储在有序集中的扭曲,因为我的信息可能相当大。

希望这会有所帮助!

0

如果您想要一个发布/订阅系统,订阅者在死后不会丢失消息,请考虑使用Redis Streams而不是Redis Pub/sub。

Redis的流有自己的架构和利弊/缺点,Redis的发布/订阅。使用Redis Streams,用户可以发出命令:

我收到的最后一条消息是X,现在给我下一条消息; 如果没有新消息,则等待一个到达。

上面链接的Antirez的文章是一个很好的介绍Redis流与更多的信息。

警告:此功能仅在Redis的不稳定(测试版)版本存在的现在。

我也是有同样的问题