redis 做消息队列,控制队列的消费间隔。

最近遇到了一个难题。

我是用redis做消息队列的。每个队列都包含一个任务id,

简单的流程如下:

1、从list里面读取id,消费这个任务

2、根据id,从数据库读取这个任务的详细信息。

数据结构如下:比如

ID=1 URL:abc.com
ID=2 URL:abd.com
ID=3 URL:ab3.com
……

我现在需要做一个功能。

控制每个url的域名的访问间隔。 比如 任务里面的url里面有 abc.com 和 efg.com

我需要控制每隔5秒消费一个包含abc.com任务,每个10秒消费一个包含efg.com的任务

如果兼顾性能的同时又能完成这个功能?


加个条件:分布式、几百万个队列,几十台服务器


隔了不久回来看这个问题,redis做延时队列网上有很多文章。
专业的消息队列rabbitmq也有这方面的教程。

-0------------------

隔了一年,我才找到了正确答案,太恶心了。

答案:https://segmentfault.com/q/10...

阅读 6.3k
5 个回答

目前是我是这样处理的:

1、lpop任务。
2、检测这个任务是否间隔了X秒。
3、如果符合,则消费,如果不符合,不消费。如果不消费,使用lpush命令推入队列。

这个功能的挑战性在于性能。如果单单一台服务器,那没什么问题,几百万个任务队列的时候,问题就来了。
进行这些检测,每多一个步骤,都会增加很多额外的开销,qps会很高,有些队列本来可以及时消费,却没有去消费。造成很多累积。

執行結束後加個判斷 如果包含abc.com sleep(5)

还有一个问题,为什么不检测就会多次推入同一个任务呢?你不是先pop的么?

你可以存放到两个 zset 队列,以时间作为 score 排序,5s的zset1,插入时记录下可以消费的时间(当前时间+5),每次取最老的记录出来消费,判断当前时间是否超过消费时间,超过则消费。然后10s放入zset2,同理操作。

楼主可以了解下 beanstalked是内存队列

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏