Redis学习之实现优先级消息队列
很久没有写博客了,最近简单的学习了一下Redis,其中学习了一下用Redis实现优先级消息队列。关于更多更为详细的可以在www.redis.cn找到相关资料。
对于熟悉Redis的童鞋提到队列很自然的想到使用Redis的列表类型。其中也自然能够想到LPUSH和RPOP命令实现队列的概念。如果要实现任务队列,只需要让生产者将任务使用LPUSH命令加入到某个键中,另一边让消费者不断使用RPOP命令从该键中取出任务即可。首先我们先进行简单测试,分别打开两个redis-cli实例
在第一个窗口中输入:
127.0.0.1:> LPUSH queue: yayun
(integer)
127.0.0.1:>
第二个窗口输入:
127.0.0.1:> RPOP queue:
"yayun"
127.0.0.1:> LLEN queue:
(integer)
127.0.0.1:>
可以看见马上就取出值了,再次查询的时候发现已经没有记录了,说明已经消费掉了。简单明了的生产者,消费者。
如果我们程序中使用RPOP命令,将导致队列中即使没有任务时,也会每秒都会调用RPOP命令,如果可以实现一旦有新任务加入就通知消费者,也就是我们的程序,那么将是最给力的,Redis都已经替我们想好了,我们可以使用BRPOP命令操作,BRPOP命令和RPOP命令相似,唯一的区别是当列表中没有元素时BRPOP命令会一直阻塞住连接,直到有新的任务加入。我们再次进行简单测试。
BRPOP命令接收两个参数,第一个是键名,第二个是超时时间,单位是秒。当超过了此时间没有获得性元素的话返回nil。如果设置为0,表示不限制等待时间,即如果没有新元素加入列表就会永远阻塞下去。
第一个窗口中输入(没有任务一直阻塞):
127.0.0.1:> BRPOP queue:
第二个窗口中输入:
127.0.0.1:> LPUSH queue: yayun
(integer)
127.0.0.1:>
当我们加入任务时,发现第一个窗口的输入如下:
127.0.0.1:> BRPOP queue:
) "queue:0"
) "yayun"
(.19s)
127.0.0.1:>
可以发现当加入任务时马上消费掉了,元素已经被取走。
下面说说如何实现优先级消息队列,最后结合python来一段简单代码演示一下。BRPOP命令可以同时接收多个键,起完整的命令格式为BRPOP key [ key ... ] timeout,例如BRPOP queue:0 queue:1 0。意思是同时检测多个键,如果所有键都没有元素则一直阻塞,如果其中有一个键有元素会从该键中弹出元素。如果多个键都有元素则按照从左到右的顺序取第一个键中的一个元素。下面进行简单的测试。打开两个实例:
第一个窗口中:
127.0.0.1:> LPUSH queue: yayun
(integer)
127.0.0.1:> LPUSH queue: dengyayun
(integer)
127.0.0.1:>
第二个窗口中:
127.0.0.1:> LPUSH queue: yayun
(integer)
127.0.0.1:> BRPOP queue: queue:
) "queue:0"
) "yayun"
127.0.0.1:> BRPOP queue: queue:
) "queue:1"
) "dengyayun"
127.0.0.1:>
从上面我们可以发现queue:0任务先执行了。好了,说了这么多了相信大家都测试体会到了,下面来一段简单的python脚本进行测试。python操作redis需要安装模块。
从https://github.com/andymccurdy/redis-py下载redis-py-master.zip安装,解压后进入到目录执行python setup.py install即可安装完成。关于相关操作说明这里说的非常清楚https://pypi.python.org/pypi/redis/以及解压后目录里的README.rst文件。都可以进行阅读。
生产着脚本如下:
#!/usr/bin/python import redis def producers():
for i in xrange(1000000):
str='low_task_queue %d' % i
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
r.lpush('low_task_queue',str) if __name__ == "__main__":
producers()
消费者脚本如下:
#!/usr/bin/python import redis, time def handle(task):
print task
time.sleep(1) def consumer():
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
while 1:
result = r.brpop(['high_task_queue', 'low_task_queue'], 0)
handle(result[1]) if __name__ == "__main__":
consumer()
打开2个窗口,分别执行两个脚本,然后打开第3个窗口手动添加元素,模拟优先级队列。
可以看见在处理队列了,我这里停顿了1秒才处理,是为了观看效果。
[root@mysql-server- ~]# python consumer.py
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
打开窗口手动插入元素:
127.0.0.1:> LPUSH high_task_queue 'high_task_queue 9999999'
(integer)
127.0.0.1:>
可以看见优先级队列已经处理。
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
high_task_queue
low_task_queue
low_task_queue
low_task_queue
low_task_queue
参考资料
<<Redis 入门指南>>
总结:
Redis功能强大,简单易用,还需要进一步好好学习。
Redis学习之实现优先级消息队列的更多相关文章
- 【框架学习与探究之消息队列--EasyNetQ(2)】
声明 本文欢迎转载,系博主原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7654902.html 前言 此文章,是承接上篇:[框架学习与探究之消息队列--Ea ...
- RabbitMQ学习笔记五:RabbitMQ之优先级消息队列
RabbitMQ优先级队列注意点: 1.只有当消费者不足,不能及时进行消费的情况下,优先级队列才会生效 2.RabbitMQ3.5以后才支持优先级队列 代码在博客:RabbitMQ学习笔记三:Java ...
- 【框架学习与探究之消息队列--EasyNetQ(1)】
前言 本文欢迎转载,实属原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7603554.html 废话 既然都是废话了,所以大家就可以跳过了,这里是博主有事没事 ...
- Redis 学习(三) —— 事务、消息发布订阅
一.Redis事务 Redis 提供的事务机制与传统的数据库事务有些不同,传统数据库事务必须维护以下特性:原子性(Atomicity), 一致性(Consistency),隔离性(Isolation) ...
- 用 Redis 实现 PHP 的简单消息队列
参考:PHP高级编程之消息队列 消息队列就是在消息的传输过程中,可以保存消息的容器. 常见用途: 存储转发:异步处理耗时的任务 分布式事务:多个消费者消费同一个消息队列 应对高并发:通过消息队列保存任 ...
- redis(五)---- 简单消息队列
消息队列一个消息的链表,是一个异步处理的数据处理引擎.不仅能够提高系统的负荷,还能够改善因网络阻塞导致的数据缺失.一般用于邮件发送.手机短信发送,数据表单提交.图片生成.视频转换.日志储存等. red ...
- 使用redis原生list结构作为消息队列取代celery框架。
1.web后台对大批量的繁重的io任务需要解耦使用分布式异步技术,否则会使接口阻塞,并发延迟,一般就选celery好了.此篇的取代主要是针对取代celery的worker模式.没有涉及到周期和定时模式 ...
- [转载] 基于Redis实现分布式消息队列
转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...
- 基于Redis的消息队列php-resque
转载:http://netstu.5iunix.net/archives/201305-835/ 最近的做一个短信群发的项目,需要用到消息队列.因此开始了我对消息队列选型的漫长路. 为什么选型会纠结呢 ...
随机推荐
- PAT甲级 1120. Friend Numbers (20)
1120. Friend Numbers (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Two in ...
- Codeforces821A Okabe and Future Gadget Laboratory 2017-06-28 14:55 80人阅读 评论(0) 收藏
A. Okabe and Future Gadget Laboratory time limit per test 2 seconds memory limit per test 256 megaby ...
- Hadoop/Spark相关面试问题总结
面试回来之后把其中比较重要的问题记了下来写了个总结: (答案在后面) 1.简答说一下hadoop的map-reduce编程模型 2.hadoop的TextInputFormat作用是什么,如何自定义实 ...
- kosaraju算法
这个是求一个图有几个强联通分量的算法 先讲一下应该流程 首先输入一个图G,创建一个反向的图GT 图G 对图进行dfs遍历,纪录每个点结束搜索的时间p[i] p[1]=2 p[2]=1 p[3]=5 ...
- hdu 4915 括号匹配+巧模拟
http://acm.hdu.edu.cn/showproblem.php?pid=4915 给定一个序列,由()?组成,其中?可以表示(或者),问说有一种.多种或者不存在匹配. 从左向右,优先填满n ...
- 安装json插件
谷歌浏览器中安装JsonView扩展程序 实际开发工作中经常用到json数据,那么就会有这样一个需求:在谷歌浏览器中访问URL地址返回的json数据能否按照json格式展现出来. 比如,在谷歌浏览器中 ...
- SQL Server 字符串拼接、读取
一.查询结果使用,字符串拼接 declare @names nvarchar(1000) declare @ParmDefinition nvarchar(1000) declare @sqltext ...
- 数据库操作类《SqlHelper》
一.背景 在看了一本书叫<Visual Studio 2010(C#)Windows数据库项目开发>后,觉得很多编程技术需要积累,因为一个简单的项目里包含的技术太多了,容易忘记.每次需要用 ...
- Flask系列07--Flask中的CBV, 蓝图的CBV
一.CBV使用 class base view 和django中类似 class Login(views.MethodView): # methods=["POST"," ...
- ZJOI Round2游记
虽然一试很惨但是二试还是要来玩一下的 Day 0 到余姚了,然后到余姚边上的宾馆住来下来 顺便一问老师们对边上是不是有什么误解-- 吃完晚饭就回宾馆颓了 话说半夜真刺激--住隔壁那一位手突然骨折了,本 ...