我想以发布 - 订阅的方式在应用程序之间传递数据。数据可能以比消耗的速度高得多的速度产生并且消息丢失,这不是问题。想象一下快速传感器和慢速传感器数据处理器。为此,我使用redis pub / sub并编写了一个充当订阅者的类,接收每条消息并将其放入缓冲区。当“真实”功能请求消息时,当或中的新消息无效时,将覆盖缓冲区。因此,当我问这个课时,我立即得到一个回应(暗示我的函数比数据进来慢)或者我必须等待(暗示我的函数比数据快)。
这对于数据快速进入的情况非常有用。但是对于相对来说相对较少的数据,让我们说每五秒钟,不工作:想象我的消费者在生产者之后稍微启动,第一条消息丢失了我的消费者需要等待将近五秒钟,直到它开始工作。
我想我必须使用Redis工具来解决这个问题。我可以简单地使用 get / set 方法代替 pub / sub ,从而直接将缓存功能放入Redis。但是,我的消费者必须轮询数据库,而不是我现在拥有的事件魔法。键看起来像“key:timestamp”,我的消费者现在必须get key:*
并比较永久性的时间戳,我认为这会导致很多负载。睡觉没有天生的可能性,因为虽然我不关心掉线信息(我无能为力),但我确实关心延迟。
有人使用Redis做类似的事情并且可以给我一些关于巧妙使用Redis工具和数据结构的提示吗?
修改的
理想情况下,我的程序流程如下所示:
key
key
”的变化。通过撰写本文,我们提出了一个想法:发布商不仅发布了关于主题message
的{{1}},还发布了key
。这样,应用程序最初可以set key message
,然后get
。
好主意还是不真实?
Keyspace通知真的是我在这里需要的。 Redis充当信息的主要来源,我的客户端订阅密钥空间通知,通知订阅者有关影响特定密钥的事件。现在,在我的客户端的异步部分,我订阅了关于我感兴趣的密钥的通知。这些通知设置了subscribe
标志。当我需要这个值时,我会从Redis key_has_updates
取消它并取消设置标志。使用unset标志,我知道服务器上的该键没有新值。如果没有密钥空间通知,这将是我需要轮询服务器的部分。优点是我可以使用各种数据结构,不仅是get
机制,而且慢速连接器错过了第一个事件始终能够pub/sub
初始化价值,get
会丢失。
当我需要该值时,我从Redis获取值并将该标志设置为false。
答案 0 :(得分:3)
一个想法是将数据推送到列表(LPUSH)并修剪它(LTRIM),因此如果没有消费者,它就不会永远增长。另一方面,消费者会从该列表中获取项目并处理它们。您还可以使用keyspace notifications,并在每次将项目添加到该队列时收到提醒。
答案 1 :(得分:3)
我使用两个本机redis命令在应用程序之间传递数据: rpush 和 blpop 。 " blpop在没有任何元素从任何给定列表弹出时阻止连接"。
代码shuold(用perl语言)
发件人(我们假设哈希传递)
#Encode hash in json format
my $json_text = encode_json \%$hash_ref;
#Connect to redis and send to list
my $r = Redis->new(server => "127.0.0.1:6379");
$r->rpush("shared_queue","$json_text");
$r->quit;
接收器(进入无限循环)
while (1) {
my $r = Redis->new(server => "127.0.0.1:6379");
my @elem =$r->blpop("shared_queue",0);
#Decode hash element
my $hash_ref=decode_json($elem\[1]);
#make some stuff
}
我发现这种方式非常有用,原因有很多:
答案 2 :(得分:0)
从Redis 5开始,有一种新数据类型称为“ Streams”,它是仅追加的数据结构。使用用户组概念Redis_Streams_MQ
,Redis流可用作点对点和多播通信的可靠消息队列。