一种基于Redis的高并发延时任务系统和处理方法与流程

文档序号:20767846发布日期:2020-05-15 19:13阅读:628来源:国知局
一种基于Redis的高并发延时任务系统和处理方法与流程

本发明涉及一种基于redis的高并发延时任务系统,属于互联网技术领域。



背景技术:

随着互联网的高速发展,网络系统中的业务场景变得越来越复杂,延时任务场景也变得十分常见。如以下生活中常见的延时任务场景:活动结束前2小时给用户推送消息;优惠券过期前2小时给用户推送消息;下单后24小时未付款订单自动取消等。

针对这一类的延时任务场景,当下已有不少的解决方案。最常见的方案就是扫表。扫表是启用一个后台进程,每隔一段时间扫描数据库的整张数据表,判断每个任务是否达到触发的条件,如果达到条件就执行相应的业务。因为扫描全表对数据库压力较大,所以一般选择扫从库。扫表的最大优势是实现起来比较简单,而且数据本身存在db里,因此也不用担心任务数据会丢失,失败的任务可以下次扫描时再重入。此外也有些消息队列可以支持延时消息,如kafka,延时消息就是消息发送后,可以指定在多少时间之后才会发送到消息者那里。还有一种实现延时队列的方案是用环形队列做成时间片,环形队列的每个格子里维护一个链表,每个时刻有一个当前指针指向环形队列某个格子,定时器每超时一次,就把当前指针指向下环形队列的下一个格子,然后处理这个格子保存的链表里的任务。

以上几种延时任务解决方案都存在一些问题:扫表最大的问题就是会有延迟,不能在指定的时间触发,对于时效性高的场景,无法满足需求;消息队列实现延时任务的瓶颈在于延时任务需要重新更新时间的话就无法实现,因为消息已经发出去,无法收回;时间片轮询的方案在没有现成轮子的情况下开发成本较高。



技术实现要素:

为克服现有技术的不足,本发明提出一种基于redis的高并发延时任务系统,其能依赖于redis自身的持久化来实现持久化,依赖redis集群来支持高并发和高可用,开发成本小,实时性高。

为实现上述目的,本发明的一种基于redis的高并发延时任务系统,包括daemon组件、redis组件、event进程、消息队列组件和work组件,redis组件中具有若干个key,任务通过uuid进行hash路由到对应的key中,event进程对key进行轮询,event进程将任务写入消息队列组件中,work组件从消息队列组件取消消息并执行业务。

进一步地,key中储存有一个source和一个value,source为任务的执行时间,value为要执行的任务数据。

进一步地,event进程与key一一对应。

进一步地,还包括daemon组件,daemon组件实时监测任务和redis组件,当redis写入失败时,进行异步补偿。

进一步地,event进程多机部署,并设有zookeeper选主,由zookeeper选主的leader主机能够从redis取消息。

进一步地,zookeeper选主的leader主机宕机后,zookeeper选主重新选取新的leader主机。

进一步地,key的数量为可扩容的。

本发明还提出一种基于redis的高并发延时任务的处理方法,包括如下步骤:

s1:将任务的执行时间作为score,要执行的任务数据作为value,存放在zset中;

s2:用一个进程定时查询zset的score分数最小的元素,用zrangebyscore命令来实现;

s3:如果最小的分数小于等于当前时间戳,就将该任务取出来执行,否则休眠一段时间后再查询。

本发明的一种基于redis的高并发延时任务系统能依赖于redis自身的持久化来实现持久化,依赖redis集群来支持高并发和高可用,开发成本小,实时性高。

附图说明

下面结合附图对本发明作进一步描写和阐述。

图1是本发明首选实施方式的一种基于redis的高并发延时任务系统的结构框图。

具体实施方式

下面将结合附图、通过对本发明的优选实施方式的描述,更加清楚、完整地阐述本发明的技术方案。

如图1所示,本发明首选实施方式的一种基于redis的高并发延时任务系统,包括daemon组件、redis组件、event进程、消息队列组件和work组件。redis组件中具有若干个key,key的数量为可扩容的。key中储存有一个source和一个value,source为任务的执行时间,value为要执行的任务数据。任务通过uuid进行hash路由到对应的key中,event进程与key一一对应。event进程对key进行轮询,event进程将任务写入消息队列组件中,work组件从消息队列组件取消消息并执行业务。

还包括daemon组件,daemon组件实时监测任务和redis组件,当redis写入失败时,进行异步补偿。

event进程多机部署,并设有zookeeper选主,由zookeeper选主的leader主机能够从redis取消息。zookeeper选主的leader主机宕机后,zookeeper选主重新选取新的leader主机。

本发明还提出一种基于redis的高并发延时任务的处理方法,包括如下步骤:

s1:将任务的执行时间作为score,要执行的任务数据作为value,存放在zset中;

s2:用一个进程定时查询zset的score分数最小的元素,用zrangebyscore命令来实现;

s3:如果最小的分数小于等于当前时间戳,就将该任务取出来执行,否则休眠一段时间后再查询。

具体地:基于redis实现延时任务,是通过其数据结构zset来实现的。zset会储存一个score和一个value,可以将value按照score进行排序,而set是无序的。

延时任务实现分为以下几步来实现:

s1:将任务的执行时间作为score,要执行的任务数据作为value,存放在zset中;

s2:用一个进程定时查询zset的score分数最小的元素,用zrangebyscorekey-inf+inflimit01withscores命令来实现;

s3:如果最小的分数小于等于当前时间戳,就将该任务取出来执行,否则休眠一段时间后再查询。

redis的zset是通过跳跃表来实现的,复杂度为o(logn),n是存放在zset中元素的个数。用redis来实现可以依赖于redis自身的持久化来实现持久化,redis的集群来支持高并发和高可用。因此开发成本很小,可以做到很实时。

其中:

1、由于zset的时间复杂度为o(logn),如果在同一个时间点有多个任务时,一个key会分发不过来,造成拥堵。为了避免一个key存储的数据量变多以后导致查询速度变慢。故将其设计为多个key来存储,通过uuid进行hash路由到对应的key中,如果任务量增长,可以快速扩容rediskey的数量来抗住增长的数量。

2、event进程即为建立与多个key相同的进程或者线程数,每个进程一个编号,分别对应一个key,不断轮询相应的key。

3、event进程只查询出任务,但是不处理业务,将该任务写入到消息队列中。另外有work进行从消息队列取消息,然后执行业务。这样work可以进行分布式部署,event进行只需做分发,这样可以把并发做到非常高,即使同一时间有大量的任务,也能很小的延时内完成任务。

4、为了避免event进程单机部署,在机器宕机后导致无法取消息,redis储存的数据还会被积压。我们多机部署event进程,并使用zookeeper选主,只有leader主机上的进程才从redis取消息。leader主机宕机后,zookeeper会自动选择新的leader。

5、在实际的业务中,还会依赖db写入数据。延时任务产生是先修改db然后再向redis写入数据,那么就存在db更新成功,然后redis写失败的场景,这个时候首先是通过重试来减少redis写入失败的概率,如果重试任然不能成功,就发送一条消息给daemon进程进行异步补偿。

此外,延时任务如果还没有到达执行时间,那么该延时任务的时间是可以被更改的。为了实现这个需求,另外会给每个用户维护一个zset,这个zset中存放当前用户所有的延时任务。为了便于描述,将这个zset称为zset-user。如果用户需要修改其延时任务,如果没有办法从整体的延时任务的zset中找到这个任务,而是即使能找到,也只能遍历这个zset,显然这种方法太慢,太耗资源。本发明采取的方法是从zset-user中取出这个用户的延时任务,然后修改score,最后重新zadd到延时任务zset和zset-user中,zadd会覆盖原来的任务,而score则发生了更新。从而达到了修改延时任务时间的效果。

本发明的一种基于redis的高并发延时任务系统可以依赖于redis自身的持久化来实现持久化,依赖redis集群来支持高并发和高可用,开发成本小,实时性高。并且该架构还支持自主修改延时任务的延时时间,为延时任务场景提供了一种更优的方案选择。

上述具体实施方式仅仅对本发明的优选实施方式进行描述,而并非对本发明的保护范围进行限定。在不脱离本发明设计构思和精神范畴的前提下,本领域的普通技术人员根据本发明所提供的文字描述、附图对本发明的技术方案所作出的各种变形、替代和改进,均应属于本发明的保护范畴。本发明的保护范围由权利要求确定。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1