原文链接:https://mp.weixin.qq.com/s/_q0bI62iFrG8h-gZ-bCvNQ
现如今的互联网应用大都是采用 分布式系统架构 设计的,所以 消息队列 已经逐渐成为企业的应用系统 内部通信 的核心手段,
它具有 低耦合、可靠投递、广播、流量控制、最终一致性 等一系列功能。
当前使用较多的 消息队列 有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ 等,而部分数据库 如 Redis、MySQL 以及 phxsql ,如果硬搞的话,其实也可实现消息队列的功能。
可能有人觉得,各种开源的 MQ 已经足够使用了,为什么需要用 Redis 实现 MQ 呢?
- 有些简单的业务场景,可能不需要重量级的 MQ 组件(相比 Redis 来说,Kafka 和 RabbitMQ 都算是重量级的消息队列)
那你有考虑过用 Redis 做消息队列吗?
这一章,我会结合消息队列的特点和 Redis 做消息队列的使用方式,以及实际项目中的使用,来和大家探讨下 Redis 消息队列的方案。
一、回顾消息队列
消息队列 是指利用 高效可靠 的 消息传递机制 进行与平台无关的 数据交流,并基于数据通信来进行分布式系统的集成。
通过提供 消息传递 和 消息排队 模型,它可以在 分布式环境 下提供 应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步 等等功能,其作为 分布式系统架构 中的一个重要组件,有着举足轻重的地位。
现在回顾下,我们使用的消息队列,一般都有什么样的特点:
- 三个角色:生产者、消费者、消息处理中心
- 异步处理模式:生产者 将消息发送到一条 虚拟的通道(消息队列)上,而无须等待响应。消费者 则 订阅 或是 监听 该通道,取出消息。两者互不干扰,甚至都不需要同时在线,也就是我们说的 松耦合
- 可靠性:消息要可以保证不丢失、不重复消费、有时可能还需要顺序性的保证
撇开我们常用的消息中间件不说,你觉得 Redis 的哪些数据类型可以满足 MQ 的常规需求~~
二、Redis 实现消息队列
思来想去,只有 List 和 Streams 两种数据类型,可以实现消息队列的这些需求,当然,Redis 还提供了发布、订阅(pub/sub) 模式。
我们逐一看下这 3 种方式的使用和场景。
2.1 List 实现消息队列
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
所以常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。
Redis 提供了好几对 List 指令,先大概看下这些命令,混个眼熟
List 常用命令
挑几个弹入、弹出的命令就可以组合出很多姿势
- LPUSH、RPOP 左进右出
- RPUSH、LPOP 右进左出
127.0.0.1:6379> lpush mylist a a b c d e
(integer) 6
127.0.0.1:6379> rpop mylist
"a"
127.0.0.1:6379> rpop mylist
"a"
127.0.0.1:6379> rpop mylist
"b"
127.0.0.1:6379>
即时消费问题
通过 LPUSH,RPOP 这样的方式,会存在一个性能风险点,就是消费者如果想要及时的处理数据,就要在程序中写个类似 while(true) 这样的逻辑,不停地去调用 RPOP 或 LPOP 命令,这就会给消费者程序带来些不必要的性能损失。
所以,Redis 还提供了 BLPOP、BRPOP 这种阻塞式读取的命令(带 B-Bloking的都是