一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式。利用redis这两种场景的消息队列都能够实现。
定义:

  • 生产者消费者模式:生产者生产消息放到队列里,多个消费者同时监听队列,谁先抢到消息谁就会从队列中取走消息;即对于每个消息只能被最多一个消费者拥有。
  • 发布者订阅者模式:发布者生产消息放到队列里,多个监听队列的消费者都会收到同一份消息;即正常情况下每个消费者收到的消息应该都是一样的。

那么如此多的MQ产品,为什么要使用redis作消息队列呢?以下附上一份总结了别人的一些report或blog的表格,以及当初用来说服整个team的一句结论。

MQ Env. Weight Disadvantage      
RabbitMQ Erlang Heavy Bad scalability;Low speed;    
ZeroMQ C Light difficult for development    
ActiveMQ Java - Low performance      
Redis C - Low performance while enqueuing big data (>= 10k) 

Redis is easy to use and configure since we have experience in Redis, and most importantly, its performance satisfies our requirement.

Then, how to use redis as a MQ?

首先,redis的队列实际在代码逻辑中不需要由我们自己实现,因此一个所谓的 RedisMQ 对象实际是一个 redis key以及对其操作的一些封装。

PubSub Mode:

redis 从 2.0.0 版本开始支持 pub/sub 指令。详情见 http://redis.io/topics/pubsub

实现思想很简单,Publisher调用redis的publish方法往特定的channel发送消息,Subscriber在初始化的时候要subscribe到该channel,一旦有消息就会立即接收。

比较简单的demo可参见:http://shift-alt-ctrl.iteye.com/blog/1867454 ,此链接博客中写得已较详细,本文便不再赘述。

Producer/Consumer Mode:

该方法是借助redis的list结构实现的。

Producer调用redis的lpush往特定key里塞入消息,Consumer调用brpop去不断监听该key。

producer:

 // producer code
String key = "demo:mq:test";
String msg = "hello world";
redisDao.lpush(key, msg);

consumer:

 // consumer code
String key = "demo:mq:test";
while (true) {
// block invoke
List<String> msgs = redisDao.brpop(BLOCK_TIMEOUT, listKey);
if (msgs == null) continue;
String jobMsg = msgs.get(1);
processMsg(jobMsg);
}

当有多个consumers的时候,它会按照brpop调用的顺序分派消息,并非随机。

BLOCK_TIMEOUT不建议设成infinity(有些redis驱动也直接不支持inifinity),我们目前设成30(单位是秒)情况良好。

P.S. 本文时间较久远,适合redis 2的版本,不保证redis自己会不会有其他新特性 ;同时消息队列产品有很多种,这里列的只是早年常用的,近两三年的kafka和阿里的rocketmq也很火,至于怎么选择,一部分是根据数据量,若数据量不大,容错要求不是极高,redis是个高效开发易维护的好选择;如果数据量很大或对消息准确性有一定要求,那应当考虑更成熟的消息队列产品比如kafka等。所以mq的选型并不是本文的重点,本文只是介绍一下基于redis 2.6的mq的简单封装实现。

Redis 做消息队列的更多相关文章

  1. Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流

    1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...

  2. 程序员过关斩将--redis做消息队列,香吗?

    Redis消息队列 在程序员这个圈子打拼了太多年,见过太多的程序员使用redis,其中一部分喜欢把redis做缓存(cache)使用,其中最典型的当属存储用户session,除此之外,把redis作为 ...

  3. Redis做消息队列

    1.连接从Redis中获取日志文件并存储到ES中 [root@Logstash ~]# vim /usr/local/logstash/config/redis.conf input {     be ...

  4. 使用Redis做消息队列

    基于内存的单线程数据库,使Redis的线程安全性极高.而Redis的双向链表数据类型(List)天生就可作为消息队列存储消息. 在这里就不说消息队列的等等一些优点.但是补充一下Redis的List类型 ...

  5. RabbitMQ跟Redis做消息队列的区别

    区别 https://www.zhihu.com/question/20795043 https://blog.csdn.net/dd18709200301/article/details/79077 ...

  6. Redis做消息队列文章两篇

    介绍:http://www.cnblogs.com/lhfcws/p/3732535.html 具体做法:http://shift-alt-ctrl.iteye.com/blog/1867454 另外 ...

  7. 使用Redis Stream来做消息队列和在Asp.Net Core中的实现

    写在前面 我一直以来使用redis的时候,很多低烈度需求(并发要求不是很高)需要用到消息队列的时候,在项目本身已经使用了Redis的情况下都想直接用Redis来做消息队列,而不想引入新的服务,kafk ...

  8. PHP使用Redis实现消息队列

    消息队列可以使用MySQL来实现,可以参考博客PHP使用MySQL实现消息队列,虽然用MySQL可以实现,但是一般不这么用,因为MySQL的数据都存在硬盘中,而从硬盘中对MySQL的操作,I/O花费的 ...

  9. rabbitmq和redis用作消息队列的区别

    将redis发布订阅模式用做消息队列和rabbitmq的区别: 可靠性redis :没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中:r ...

随机推荐

  1. 50. 树的子结构[subtree structure in tree]

    [本文链接] http://www.cnblogs.com/hellogiser/p/subtree-structure-in-tree.html [题目] 输入两棵二叉树A和B,判断B是不是A的子结 ...

  2. C++开始前篇,深入编译链接

    C++开始,为什么要写这个东西,因为按照课堂进度的话,现在的C++已经学到模板以及重载了,有时却仍然因为一些小问题无法解答,原因是忘记了开始时学到的知识,深知不能像猴子掰棒子一样,掰一个扔一个,因此, ...

  3. iOS 自动追加版本时间版本号脚本

    buildNumber=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${PROJECT_DIR}/${I ...

  4. JS中获得当前时间的年月

    //获取完整的日期 var date=new Date; var year=date.getFullYear(); var month=date.getMonth()+1; month =(month ...

  5. javascript 框架、根基技巧、布局、CSS、控件 JavaScript 类库

    预筹备之 JavaScript 今朝支流的 JavaScript 框架排名中,jQuery 和 Ext 可算是佼佼者,得到了用户的普遍好评.海内的一些框架许多也是模仿 jQuery 对 JavaScr ...

  6. 一个从数据库中把数据导成txt的笨办法

    create directory DIR_DUMP as '/oradata/data_dump'; CREATE OR REPLACE PROCEDURE anlp_to_txt IS testji ...

  7. RHEL6.5安装11.2.0.3 RAC并打补丁

    [TOC] 一,主机配置 1.修改hosts文件(两节点) #127.0.0.1 localhost localhost.localdomain localhost4 localhost4.local ...

  8. “Operation is not valid due to the current state of the object.”

    将Repeater单页显示的2000条数据一次性提交的时候出现这个错误: Operation is not valid due to the current state of the object. ...

  9. RANSAC算法笔记

    最近在做平面拟合,待处理的数据中有部分噪点需要去除,很多论文中提到可以使用Ransac方法来去除噪点. 之前在做图像配准时,用到了Ransac算法,但是没有去仔细研究,现在好好研究一番. 参考: ht ...

  10. MMU工作原理

    MMU的工作原理就是把虚拟地址转换成物理地址. 虚拟地址:由编译器和连接器在定位程序时分配. 物理地址:用来访问实际的主存硬件模块. 使用虚拟存储器的系统都使用一种称为分页(paging).虚拟地址空 ...