最近遇到了一个难题。
我是用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------------------
隔了一年,我才找到了正确答案,太恶心了。
目前是我是这样处理的:
1、lpop任务。
2、检测这个任务是否间隔了X秒。
3、如果符合,则消费,如果不符合,不消费。如果不消费,使用lpush命令推入队列。
这个功能的挑战性在于性能。如果单单一台服务器,那没什么问题,几百万个任务队列的时候,问题就来了。
进行这些检测,每多一个步骤,都会增加很多额外的开销,qps会很高,有些队列本来可以及时消费,却没有去消费。造成很多累积。