Redis发布 - 订阅:Redis是否保证即使在巨大压力下也能传递消息?

Mah*_*ahn 13 publish-subscribe redis

如果订阅的客户端和发布消息的服务器都保留了连接,那么即使在客户端和/或服务器受到巨大压力的情况下,Redis仍保证始终将发布的消息最终传递给订阅的客户端吗?或者我应该计划Redis可能会在事情变得"热"的时候偶尔丢弃消息?

Did*_*zia 15

Redis绝对不会为发布和订阅流量提供任何保证交付.此机制仅基于套接字和事件循环,不涉及任何队列(即使在内存中).如果订阅者在发布时没有收听,则该订阅者将丢失该事件.

可以在Redis之上实现一些有保证的传递机制,但不能使用发布 - 订阅API.Redis中的列表数据类型可以用作队列,也可以用作更高级的排队系统的基础,但它不提供多播功能(因此不提供发布和订阅).

AFAIK,没有明显的方法可以与Redis同时轻松实现发布 - 订阅和保证交付.

  • Hello Didier,一种模式是将两种机制结合使用.将推送内容发布到列表中.工作人员从持久的队列(列表)中获取内容(取决于持久性配置)并发布项目,只有在收到足够的确认时才删除它(可以通过Pub/Sub本身接收ACK),否则项目重新开始以后送货.通常使用RPOPLPUSH/BRPOPLPUSH处理项目,以便在临时队列中移动正在处理的项目. (3认同)
  • 假设没有TCP连接丢失,我会说数据不会被静默丢弃。如果您向Redis发布过多的流量,并且/或者应该将此流量发送给太多的订阅者,那么这将减慢Redis事件循环的速度。结果将是输入套接字缓冲区中未决数据的积累。当它们已满时,发布客户端将变慢(由于TCP控制流)。在那种情况下,我预计不会出现真正的数据丢失。 (2认同)

Dav*_* M. 5

Redis不使用其Pub/Sub机制提供有保证的传递.此外,如果订户没有主动收听频道,则它将不会接收已发布的消息.

我之前写了一篇详细的文章,描述了如何结合使用Redis列表BLPOP来实现可靠的多播发布/订阅交付:

http://blog.radiant3.ca/2013/01/03/reliable-delivery-message-queues-with-redis/

为了记录,这是高级策略:

  • 当每个使用者启动并准备好使用消息时,它会通过将自身添加到表示队列中注册的所有使用者的Set来进行注册.
  • 当生产者在队列上发布消息时,它:
    • 将消息内容保存在Redis密钥中
    • 迭代在队列中注册的消费者集合,并在列表中为每个注册的消费者推送消息ID
  • 每个消费者在其特定于消费者的列表中不断寻找新条目,当其中一个进入时,删除条目(使用BLPOP操作),处理消息并转到下一条消息.

我也已经开源的这些原则的Java实现:https: //github.com/davidmarquis/redisq

这些原则已用于从单个Redis实例和消费者应用程序的两个实例每秒处理大约1,000条消息,每个实例消耗5个线程的消息.

  • @SaloniVithalani这些都是有效的担忧...Redis本身不是一个消息队列...它可以用作满足简单需求的队列,但如果您的担忧在您的环境中有效,那么您可能会更好地使用实际的消息队列(即RabbitMQ、ZeroMQ等...) (2认同)