Redis作为消息代理

时间:2014-08-05 07:22:53

标签: redis

问题

我想以发布 - 订阅的方式在应用程序之间传递数据。数据可能以比消耗的速度高得多的速度产生并且消息丢失,这不是问题。想象一下快速传感器和慢速传感器数据处理器。为此,我使用redis pub / sub并编写了一个充当订阅者的类,接收每条消息并将其放入缓冲区。当“真实”功能请求消息时,当中的新消息无效时,将覆盖缓冲区。因此,当我问这个课时,我立即得到一个回应(暗示我的函数比数据进来慢)或者我必须等待(暗示我的函数比数据快)。

这对于数据快速进入的情况非常有用。但是对于相对来说相对较少的数据,让我们说每五秒钟,工作:想象我的消费者在生产者之后稍微启动,第一条消息丢失了我的消费者需要等待将近五秒钟,直到它开始工作。

我想我必须使用Redis工具来解决这个问题。我可以简单地使用 get / set 方法代替 pub / sub ,从而直接将缓存功能放入Redis。但是,我的消费者必须轮询数据库,而不是我现在拥有的事件魔法。键看起来像“key:timestamp”,我的消费者现在必须get key:*并比较永久性的时间戳,我认为这会导致很多负载。睡觉没有天生的可能性,因为虽然我不关心掉线信息(我无能为力),但我确实关心延迟。

有人使用Redis做类似的事情并且可以给我一些关于巧妙使用Redis工具和数据结构的提示吗?

修改

理想情况下,我的程序流程如下所示:

  • 启动程序
  • 从Redis检索key
  • 告诉Redis,“嘿,通知key”的变化。
  • 以异步方式启动某些内容,并对新邮件进行回调。

通过撰写本文,我们提出了一个想法:发布商不仅发布了关于主题message的{​​{1}},还发布了key。这样,应用程序最初可以set key message,然后get

好主意还是不真实?

我得到下面的答案(接受的答案)之后我做了什么

Keyspace通知真的是我在这里需要的。 Redis充当信息的主要来源,我的客户端订阅密钥空间通知,通知订阅者有关影响特定密钥的事件。现在,在我的客户端的异步部分,我订阅了关于我感兴趣的密钥的通知。这些通知设置了subscribe标志。当我需要这个值时,我会从Redis key_has_updates取消它并取消设置标志。使用unset标志,我知道服务器上的该键没有新值。如果没有密钥空间通知,这将是我需要轮询服务器的部分。优点是我可以使用各种数据结构,不仅是get机制,而且慢速连接器错过了第一个事件始终能够pub/sub初始化价值,get会丢失。

当我需要该值时,我从Redis获取值并将该标志设置为false。

3 个答案:

答案 0 :(得分:3)

一个想法是将数据推送到列表(LPUSH)并修剪它(LTRIM),因此如果没有消费者,它就不会永远增长。另一方面,消费者会从该列表中获取项目并处理它们。您还可以使用keyspace notifications,并在每次将项目添加到该队列时收到提醒。

答案 1 :(得分:3)

我使用两个本机redis命令在应用程序之间传递数据: rpush blpop 。 " blpop在没有任何元素从任何给定列表弹出时阻止连接"。

  • 数据以json格式传递,在应用程序之间使用list作为队列。
  • 想要发送数据的应用程序(充当发布者)在列表中创建 rpush
  • 希望接收数据的应用程序(充当订阅者)在同一列表中创建 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
}

我发现这种方式非常有用,原因有很多:

  • 元素存储在列表中,因此临时禁用接收器不会丢失信息。当接收重新启动时,可以将所有项目处理到列表中。
  • 可以使用多个接收器实例处理高发送方率。
  • 多个发件人可以在唯一列表上发送数据。在这种情况下应该很容易实现数据收集器
  • 可以使用特定工具监控充当守护程序的接收程序进​​程(例如pm2

答案 2 :(得分:0)

从Redis 5开始,有一种新数据类型称为“ Streams”,它是仅追加的数据结构。使用用户组概念Redis_Streams_MQ

,Redis流可用作点对点和多播通信的可靠消息队列。