Redis publish-subscribe:即使在巨大的压力下,Redis也能保证传递信息吗?

Redis publish-subscribe:即使在巨大的压力下,Redis也能保证传递信息吗?,redis,publish-subscribe,Redis,Publish Subscribe,如果订阅的客户端和发布消息的服务器都保持连接,那么即使在客户端和/或服务器承受巨大压力的情况下,Redis是否保证始终将发布的消息最终交付给订阅的客户端?或者,我是否应该计划Redis可能会在事情变得“热”时局部删除消息?Redis绝对不会为发布和订阅流量提供任何有保证的交付。此机制仅基于套接字和事件循环,不涉及队列(即使在内存中)。如果发布发生时订阅服务器未侦听,则此订阅服务器的事件将丢失 可以在Redis之上实现一些有保证的交付机制,但不能使用发布和订阅API。ReDIS中的列表数据类型可以

如果订阅的客户端和发布消息的服务器都保持连接,那么即使在客户端和/或服务器承受巨大压力的情况下,Redis是否保证始终将发布的消息最终交付给订阅的客户端?或者,我是否应该计划Redis可能会在事情变得“热”时局部删除消息?

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

可以在Redis之上实现一些有保证的交付机制,但不能使用发布和订阅API。ReDIS中的列表数据类型可以用作队列,并且作为更先进的排队系统的基础,但它不提供多播能力(因此不发布和订阅)。
顺便说一句,没有明显的方法可以轻松地使用Redis同时实现发布、订阅和保证交付。

Redis没有使用其发布/订阅机制提供保证交付。此外,如果订户未在某个频道上积极侦听,它将不会收到本应发布的消息

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

为了记录在案,以下是高层战略:

  • 当每个使用者启动并准备使用消息时,它通过将自身添加到表示队列上注册的所有使用者的集合中进行注册
  • 当生产者在队列上发布消息时,它:
    • 将消息内容保存在Redis密钥中
    • 迭代队列上注册的使用者集,并将消息ID推送到每个注册使用者的列表中
  • 每个消费者在其特定于消费者的列表中不断查找新条目,当一个消费者进来时,删除该条目(使用
    BLPOP
    操作),处理该消息并转到下一条消息
我还以开源方式提供了这些原则的Java实现:


这些原则已用于每秒处理来自单个Redis实例和两个消费者应用程序实例的约1000条消息,每个实例使用5个线程来消耗消息。

这里可能也有硬件限制条件-例如,如果磁盘空间不足,任何队列系统都会遇到问题。您可以将事情推到某个限制,超过该限制,任何系统都将开始失败。您必须提前计划您将收到的负载量,并为其提供足够的资源(在这种情况下,高硬件规格,可能还有一组redis机器来共享负载)。我必须补充:您只能通过自己进行彻底的负载测试来了解这一限制并计划容量。您好,Didier,一种模式是同时使用这两种机制。发布并将内容推送到列表中。工作人员从持久性队列(列表)中获取内容(取决于持久性配置)并发布该项,只有在收到足够的确认(可以通过发布/订阅本身接收ACK)时才将其删除,否则该项将重新排队等待以后的传递。通常您使用RPOPLPUSH/BRPOPLPUSH处理项目,以便将正在处理的项目移动到临时队列中。我知道不可能提供100%的保证,但提供了一个所有其他条件都完美的场景(订阅者正在收听,发布者正确发布消息,redis正常启动和运行,机器没有资源限制等),并隔离消息掉到redis软件本身的可能原因,在高压力情况下(例如,每秒数千次发布),redis本身是否有可能发生这种情况可能会局部删除本来应该通过的消息吗?这基本上是我想要理解的/cc@antirez假设没有TCP连接丢失,我会说数据不会被悄悄地丢弃。如果你向Redis发布太多流量,和/或该流量应该发送给太多订户,这将减慢Redis event循环。其结果将是输入套接字缓冲区中累积挂起的数据。当它们满时,您的发布客户端将变慢(由于TCP控制流)。我预计在这种情况下不会出现真正的数据丢失。@Didier Spezia,我想进一步澄清您的观点,即“当它们已满时,您的发布客户端将变慢(由于TCP控制流)。我预计在这种情况下不会出现真正的数据丢失。",我认为Redis publish-subscribe使用了fire-and-forget机制。请纠正我可能的误解。谢谢。fire-and-forget并不意味着它可以绕过TCP控制流。当套接字缓冲区已满时,相应文件描述符上的写入操作将被阻止。当publisher继续发布消息,但有一个消费者出于某种原因停止了消费?Redis是否继续累积消息?是的,消息保存在Redis的内存中,并充当缓冲区,直到至少有一个消费者恢复“在线”并开始使用消息在这种情况下,一个生产者有两个消费者,假设一个消费者的运行速度比另一个消费者慢,那么慢消费者的列表将继续增加,在某个时间点Redis将从慢消费者列表中删除元素或将耗尽内存。这是不是我们应该担心什么。我们正在探索Reddis,需要一些像t这样的答案