问题
我想以发布-订阅方式在应用程序之间传递数据。数据可能会以比消费速率高得多的速度产生,并且消息会丢失,这不是问题。想象一下快速传感器和慢速传感器数据处理器。为此,我使用Redis pub/sub并编写了一个充当订阅者的类,接收每条消息并将其放入缓冲区中。当新消息进来时,缓冲区被覆盖或在“真实”函数请求消息时被清空。因此,在向该类提出问题时,我立即获得响应(表明我的函数比数据速度慢)或必须等待(表明我的函数比数据快)。
这对于数据快速到达的情况效果非常好。但是对于相对很少的数据,比如每五秒钟一次,这就行不通:想象一下我的消费者稍微晚于生产者启动,第一条消息丢失并且我的消费者需要等待近五秒钟才能开始工作。
我认为我必须使用Redis工具来解决这个问题。与其使用pub/sub,我可以直接使用get/set方法,从而将缓存功能直接放入Redis中。但是,我的消费者现在必须轮询数据库而不是我现在拥有的事件魔术。键可以看起来像“key:timestamp”,我的消费者现在必须get key:*
并持续比较时间戳,我认为这会导致很大的负载。没有自然的休眠可能性,因为虽然我不关心丢失的消息(我无能为力),但我确实关心延迟。
是否有人使用Redis进行类似的事情,并能够给我有关聪明使用Redis工具和数据结构的提示?
编辑
理想情况下,我的程序流程如下:
- 启动程序
- 从Redis检索
key
- 告诉Redis,“嘿,在
key
的更改上通知我”。
写这篇文章时,我想到了一个主意:发布者不仅可以在主题key
上发布message
,还可以set key message
。这样,应用程序可以先get
,然后再subscribe
。
这个主意好不好呢?
在我得到下面那个答案(被接受的答案)之后我做了什么
这里确实需要使用键空间通知。Redis作为信息的主要来源,我的客户端订阅键空间通知,通知订阅者有关影响特定键的事件。现在,在客户机的异步部分中,我订阅有关我的感兴趣的键的通知。这些通知设置一个key_has_updates
标志。当我需要该值时,我从Redis中获取它并取消设置标志。没有设置标志,我知道服务器上没有该键的新值。如果没有键空间通知,这将是我需要轮询服务器的部分。优点是我可以使用各种数据结构,而不仅仅是pub/sub
机制,而且缓慢加入者总是能够get
到初始值,这在pub/sub
中将会丢失。
当我需要该值时,我从Redis中获取该值并将标志设置为false。
get/set
操作来帮助“慢加入者”,但也允许通过sub
访问操作。 - wal-o-mat