使用Redis实现任务队列

说到队列很自然就能想到Redis的列表类型,3.4.2节介绍了使用LPUSH和RPOP命令实现队列的概念。如果要实现任务队列,只需要让生产者将任务使用LPUSH命令加入到某个键中,另一边让消费者不断地使用RPOP命令从该键中取出任务即可。

在小白的例子中,完成发邮件的任务需要知道收件地址、邮件主题和邮件正文。所以生产者需要将这三个信息组成对象并序列化成字符串,然后将其加入到任务队列中。而消费者则循环从队列中拉取任务,就像如下伪代码:

  1. # 无限循环读取任务队列中的内容
  2. loop
  3. $task = RPOR queue
  4. if $task
  5. # 如果任务队列中有任务则执行它
  6. execute($task)
  7. else
  8. # 如果没有则等待1秒以免过于频繁地请求数据
  9. wait 1 second

到此一个使用Redis实现的简单的任务队列就写好了。不过还有一点不完美的地方:当任务队列中没有任务时消费者每秒都会调用一次RPOP命令查看是否有新任务。如果可以实现一旦有新任务加入任务队列就通知消费者就好了。其实借助BRPOP命令就可以实现这样的需求。

BRPOP命令和RPOP命令相似,唯一的区别是当列表中没有元素时BRPOP命令会一直阻塞住连接,直到有新元素加入。如上段代码可改写为:

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

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

当获得一个元素后BRPOP命令返回两个值,分别是键名和元素值。为了测试BRPOP命令,我们可以打开两个redis-cli实例,在实例A中:

  1. redis A> BRPOP queue 0

键入回车后实例1会处于阻塞状态,这时在实例B中向queue中加入一个元素:

  1. redis B> LPUSH queue task
  2. (integer) 1

在LPUSH命令执行后实例A马上就返回了结果:

  1. 1) "queue"
  2. 2) "task"

同时会发现queue中的元素已经被取走:

  1. redis> LLEN queue
  2. (integer) 0

除了BRPOP命令外,Redis还提供了BLPOP,和BRPOP的区别在与从队列取元素时BLPOP会从队列左边取。具体可以参照LPOP理解,这里不再赘述。

以上转自:http://book.51cto.com/art/201305/395461.htm

续:因为要做nodejs的任务队列,所以查找到此资料。无意间,竟然发现这个可以很好地解决我之前做的服务器程序中的另外一个问题,BRPOP可以很完美的解决这个问题。加上redis缓存之前用于比对seq的功能,redis一箭双雕地完美解决。

redis 任务队列的更多相关文章

  1. php连接redis数据库 操作redis任务队列

    首先你的安装phpredis扩展在你的服务器上 $redis = new Redis(); $redis->connect('119.29.10.xx',6379); $redis->au ...

  2. Redis命令

    redis的常用命令主要分为两个方面.一个是键值相关命令.一个是服务器相关命令(redis-cli进入终端) 1.键值相关命令 keys * 取出当前所有的key exists name 查看n是否有 ...

  3. Redis分布式队列和缓存更新

    原文链接:https://www.cnblogs.com/hua66/p/9600085.html 在使用Redis中,我们可能会遇到以下场景: 例如: 某用户向服务器中发送一个请求,服务器将用户请求 ...

  4. redis 高级特性 不要太好用

    Redis高级特性及应用场景 redis中键的生存时间(expire) redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它. 过期时间可以设置为秒或者毫秒精度. ...

  5. Redis高级特性及应用场景

    Redis高级特性及应用场景 redis中键的生存时间(expire) redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它. 过期时间可以设置为秒或者毫秒精度. ...

  6. C# 多线程及同步简介示例

           60年代,在OS中能拥有资源和独立运行的基本单位是进程,然而随着计算机技术的发展,进程出现了很多弊端,一是由于进程是资源拥有者,创建.撤消与切换存在较大的时空开销,因此需要引入轻型进程: ...

  7. 初学者的分布式Python爬虫教程

    下面是一个超级计算机的排行榜,如果我们能拥有其中任意一个,那么我们就不需要搞什么分布式系统.可是我们买不起,即使买得起,也交不起电费,所以我们只好费脑子搞分布式. 分布式的本质就如上期提到的一个概念: ...

  8. python之Django实现商城从0到1

    dailyfresh-B2Cdailyfresh mall based on B2C model 基于B2C的天天生鲜商城 项目托管地址:https://github.com/Ylisen/daily ...

  9. 用Redis实现分布式锁 与 实现任务队列(转)

    这一次总结和分享用Redis实现分布式锁 与 实现任务队列 这两大强大的功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意 ...

随机推荐

  1. 杨辉三角(生成器generator)

    生成器:(Python中,这种一边循环一边计算的机制,称为生成器:generator) 创建generator的方法: 1.把列表生成式的[]变为(),就创建了一个generator 例: 可以通过n ...

  2. 关于“Durian”调查问卷的心得体会

    这周我们做了项目着手前的客户需求调查,主要以调查问卷的方式进行.其实做问卷调查并不是想象中的那么简单,首先要确定问卷调查的内容,每一个问题都要经过深思熟虑,字字斟酌,既要切合问卷主要目的,又要简洁扼要 ...

  3. 日志记录发布网站之后不成功,对路径“C:\Inetpub\wwwroot\***\***.xls”的访问被拒绝。

    主要是web程序的根目录文件夹路径访问权限不够,新增加一个everyone的完全控制读写的权限即可!---------折磨了两天,才发现使劲使错了地方. 另外: 一定谨记!!!!! 所写的路径如果不存 ...

  4. 《Visual C++开发实战1200例 第1卷》扫描版[PDF]

    [内容简介:] <Visual C++开发实战1200例(第1卷)>是“软件开发实战1200例”丛书之一.<Visual C++开发实战1200例(第1卷)>,编程实例的四库全 ...

  5. C++ auto

    auto用来声明自动变量.它是存储类型标识符,表明变量(自动)具有本地范围.块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型. 好处:auto变量在离开作用域是会变程序自动释放,不 ...

  6. ServiceStack支持跨域提交

    //ServiceStack对浏览器有一定的限制 //修改AppHost.cs文件 using Funq;using ServiceStack;using ServiceStackTest.Servi ...

  7. vim之quickfix

    [vim之quickfix] quickfix功能将编译过程中产生的错误信息保存到文件中,然后vim利用这些信息跳转到源文件的对应位置,我们就可以进行错误的修正,之后跳到下一个错误重复上述操作,从而极 ...

  8. PID算法(C语言)

    /************ PID算法(C语言) ************/ #include <stdio.h> #include<math.h> struct _pid { ...

  9. Codeforces 595B. Pasha and Phone 容斥

    B. Pasha and Phone time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  10. Telnet 协议详解

    Telnet 协议详解 一.概述 ============================================================ Telnet 协议是 TCP/IP 协议族中 ...