`
Deo
  • 浏览: 32085 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Redis实现任务队列

 
阅读更多

   实现任务队列之前,我们先了解一下使用任务队列有哪些好处:

   1. 松耦合。生产者和消费者无需知道彼此的实现细节,只需要约定好任务的描述格式。这使得生产者和消费者可以由不同的团队使用不同的编程语言编写。

   2. 易于扩展。消费者可以由多个,而且可以分布在不同的服务器中,借此可以轻易地降低单台服务器的负载。

 

    要实现队列很自然就想到Redis的列表类型,以及LPUSH和RPOP命令。如果要实现任务队列,只需要让生产者将任务使用LPUSH命令加入到某个键中,另一边让消费者不断的使用RPOP命令从该键中取出任务即可。Redis的伪代码实现如下:

# 无限循环读取任务队列中的内容
loop
    $task = RPOP queue
    if $task
        # 如果任务队列中有任务,则执行它
        execute($task)    
    else
         # 如果没有任务,则等待1秒,以免过于频繁的请求数据
         wait 1 second

     至此,一个使用Redis实现的简单任务队列就写好了,不过还有一点问题:当任务队列中没有任务时,消费者每秒都会调用一次RPOP命令查看是否有新任务。

    优化:借助BRPOP命令,可以实现一旦有新任务加入队列就通知消费者

    BRPOP命令接收两个参数,第一个是键名,第二个是超时时间,单位是秒。当超过了此时间仍然没有获得新元素的话就会返回nil。 如果超时时间设为“0”,表示不限制等待的时间,如果没有新元素加入列表就会永远阻塞下去。

    BRPOP 和 RPOP命令相似,唯一区别是:任务列表中没有元素时BRPOP命令会一直阻塞住连接,直到有新元素加入。上面的伪代码可以优化为:

loop
    # 如果任务队列中没有新任务,BRPOP命令会一直阻塞,不会执行execute()
    $task = BRPOP queue, 0
    # 返回值是一个数组,数组的第二个元素是我们需要的任务
    execute($task[1])

 

   

     队列有的时候需要优先级。比如:系统需要发送确认邮件和通知邮件两种任务同时存在时,应该优先执行确认邮件。具体场景如下,订阅一个名人的博客的用户有10万人,当该博客发布一篇新文章后,博客就会向任务队列中添加10万个发送通知邮件的任务。如果每一封邮件需要10ms,那么全部完成这10万个任务就需要:100 000 * 10 / 1000=1000秒(将近20分钟)。加入这期间有新用户想订阅该博客,当提交完自己的邮箱并看到网页提示查收确认邮件时,该用户并不知道向自己发送的确认邮件的任务被加入到已经有10万个任务的队列中,需要为此等待近20分钟。

    分析具体场景,发布新文章后通知订阅用户的任务并不很紧急,延迟20分钟完全可以接受。所以可以得出如下结论:当发送确认邮件和发送通知邮件两种任务同时存在时,应该优先执行前者。为了实现这一目的,我们需要实现一个优先级队列。

    BRPOP命令可以同时接受多个键,其完整的命令格式为:BRPOP key [key ...] timeout, 如:BRPOP queue1 queue2 0.着意味着同时检测多个键,如果其中有一个键有元素,则从该键中弹出元素;如果多个键都有元素,则按照从左到右的顺序取第一个键中的第一个元素。

    借此特性可以实现区分优先级的任务队列。我们分别使用queue:confirmation.email 和 queue.notification.email 两个键存储发送确认邮件和发送通知邮件两种任务,然后将消费者的伪代码修改为:

loop
    $task = 
    BRPOP  queue:confirmationl.email,
                queue:notification.email,
                0
    execute($task[1])

     这时,一旦发送确认邮件的任务被加入到queue.confirmation.email队列中,无论queue:notification.email还有多少任务,消费者都会优先完成发送确认邮件的通知任务。

    

 

 

 

 

分享到:
评论

相关推荐

    Redis延时消息队列基于swoole实现的多进程消费端

    标题中的“Redis延时消息队列基于swoole实现的多进程消费端”是指使用Redis作为消息队列,结合Swoole的多进程特性来构建一个高效、可扩展的延迟消息处理系统。在这个系统中,Redis作为一个可靠的键值存储,用于暂存...

    使用redis做任务队列分发子任务

    本篇将详细探讨如何利用Redis作为任务队列来分发子任务,特别是在分布式环境中的应用。 首先,我们要理解什么是Redis。Redis(Remote Dictionary Server)是一个开源的键值存储系统,它支持多种数据结构,如字符串...

    Go-用Redis实现分布式锁与实现任务队列

    接下来,我们讨论如何利用Redis实现任务队列。任务队列是一种异步处理机制,可以将耗时的操作推迟执行,以提高系统的响应速度。Redis提供了多种数据结构如List、Set和Sorted Set等,用于实现不同类型的队列。在这里...

    基于Redis实现分布式锁以及任务队列

    二、Redis实现任务队列 1. Redis中的有序集合(ZSet)常用于实现任务队列。入队操作使用`ZADD`命令,出队则通过`ZRANGE`或`ZREVRANGE`取出顶部的任务。此外,还可以通过`ZREM`删除指定任务,或`ZCOUNT`统计队列中的...

    PHP中利用redis实现消息队列处理高并发请求思路详解.rar

    后台工作者会从队列中取出任务并执行,从而实现了请求的非阻塞处理。这样,前端可以快速响应用户,而不会因为等待耗时操作而阻塞。 Redis作为一款高性能的键值数据库,常被用于构建消息队列,因为它提供了丰富的...

    Java利用Redis实现消息队列的示例代码

    * 消息队列可以应用于多种场景,如异步处理、任务队列、消息中间件等。 * 消息队列可以提高系统的可扩展性和可靠性。 六、为什么选择Redis * Redis是高速的NoSQL数据库,适合用于实现消息队列。 * Redis具有高性能...

    redis的sorted set实现延时队列

    在本篇文章中,我们将深入探讨如何利用 Redis 的有序集合(Sorted Set)来实现一个延时队列,这在很多场景下都是非常实用的,比如消息推送、定时任务等。 延时队列是一种特殊的队列,它的特性是元素不是立即被处理...

    redis实现延迟消息队列

    redis实现延迟消息队列 需求背景 最近在做一个排队取号的系统 在用户预约时间到达前XX分钟发短信通知 在用户预约时间结束时要判断用户是否去取号了,不然就记录为爽约 在用户取号后开始,等待XX分钟后要发短信...

    基于redis实现的消息队列

    标题中的“基于redis实现的消息队列”指的是使用Redis这一开源数据结构存储系统来构建消息队列(Message Queue, MQ)的解决方案。Redis以其高性能、丰富的数据结构和内存存储特性,常被用作构建消息队列的底层技术。...

    在springboot中利用Redis实现延迟队列完整案例

    利用Redis来实现延迟队列的主要思路是借助Redis的Sorted Set数据类型来实现。 具体做法是将任务的执行时间作为分数(score),任务的内容作为值(value),将任务按照执行时间排序存储在有序集合中。然后周期性地...

    PHP使用php-resque库配合Redis实现MQ消息队列的教程

    【PHP使用php-resque库配合Redis实现MQ消息队列的教程】 消息队列在Web项目中扮演着重要的角色,尤其对于提升用户体验至关重要。当需要执行耗时的后台任务,如发送邮件,消息队列能够避免用户等待,允许前端立即...

    Go-delay-queue基于Redis实现的延迟队列

    本项目是基于Go语言和Redis实现的延迟队列,借鉴了有赞(Zan)的设计思路,旨在提供一种高效、可靠的延迟服务。 首先,我们要理解Go语言的特点。Go,也称为Golang,是由Google开发的一种静态类型的编译型编程语言,...

    .NET MVC Redis 实现简单的抢购队列

    在.NET MVC应用中,使用Redis实现抢购队列是一种高效且可扩展的解决方案。Redis作为一个高性能的键值存储系统,其支持多种数据结构,如字符串、哈希表、列表、集合等,使得它非常适合用于构建高并发场景下的队列服务...

    Redis实现分布式队列浅析

    **Redis 分布式队列实现解析** Redis 是一个高性能、轻量级的键值存储系统,它以数据持久化和在网络中的高效传输而闻名。作为内存数据库,Redis 的设计目标是支持快速的数据读写和发布订阅功能,适用于缓存、计数、...

    DelayQueue延迟队列和Redis缓存实现订单自动取消功能

    这个特性使得DelayQueue成为实现定时任务和延迟操作的理想工具。在电商系统中,例如订单管理,这种功能非常有用,比如自动取消未付款的订单。 DelayQueue的核心接口是`java.util.concurrent.Delayed`,实现这个...

    redisMq(按任务批次分不同队列)

    5. `redisMq`:这可能是一个包含核心逻辑的类或模块,实现了基于Redis的消息队列功能,包括创建和管理不同批次的任务队列,以及发布和接收消息等功能。 总结来说,这个示例展示了如何利用Redis构建一个分布式任务...

    php+redis实现消息队列功能示例

    redis实现消息队列步骤如下: 1).redis函数rpush,lpop 2).建议定时任务入队列 3)创建定时任务出队列 文件:demo.php插入数据到redis队列 <?php $redis = new Redis(); $redis->connect('127.0.0.1',6379); $...

    Python-用FlaskRedis实现分布式任务分发

    **使用Flask和Redis实现任务分发** 1. **任务生产者**:在Flask应用中,你可以定义一个路由接收任务请求,然后使用Redis的`rpush`命令将任务详情推入队列。例如,创建一个名为`submit_task`的API接口,接收任务参数...

    该框架是基于redis实现的分布式队列

    在本案例中,我们关注的是一个基于Redis实现的分布式队列系统,名为KMQueue。 Redis是一个高性能的键值存储系统,常被用作数据库、缓存和消息代理。由于其内存存储和高速读写的特点,Redis非常适合构建分布式队列。...

Global site tag (gtag.js) - Google Analytics