一、Redis的消息队列
- list结构: 基于List结构模拟MQ
- PubSub: 基本的 P2P 模式的 MQ模型
- Stream: 比较完善的MQ模型
1、List模拟MQ: 通过LPUSH推送消息,RPOP接收消息,若想要阻塞队列的效果,可以通过BLPUSH,BRPOP指令进行。
(1)优点:
- 利用Redis存储,内存上限高
- 基于Redis的持久化机制,保证数据安全
- 可以满足消息有序性
(2)缺点:
- 无法避免消息丢失
- 只支持单消费者
(3)命令行形式进行模拟
sh
#存储商铺id, 优惠券id,用户id,并设置 3s 的TTL,避免等待时间过长
BLPUSH task:taskid voulerid uid
EXPIRE task:taskid 3
#取消息
BRPOP task:taskid
2、基于PubSub的消息队列: 一种Redis2.0版本引入的消息传递模型,消费者可以定义多个或多个通道,生产者想对应的通道发送消息后,所有订阅者都能收到相关消息。
(1)Redis命令:
- SUBSCRIBE channel [channel ...] : 订阅多个频道
- PUBLISH channel msg: 向一个频道发送消息
- PSUBSCRIBE pattern [pattern...]: 订阅与pattern格式匹配的所有频道
(2)优点:
- 采用发布订阅模型,支持多生产、多消费者的项目
(3)缺点:
- 不支持数据持久化
- 无法避免消息丢失
- 消息堆积有上限,超出时数据丢失
3、基于Stream的消息队列: Stream是Redis5.0发布的数据类型,支持数据持久化
(1)Redis指令:
- XADD key [NOMKSTREAM] [MAXLEN | MINID [= | ~] threshold [LIMIT count]] * |id field value [field value]:
- NOMKSTREAM: 若队列不存在是否自动创建队列,默认是自动创建。
- [MAXLEN | MINID [= | ~] threshold [LIMIT count]]: 设置消息队列最大消息数量
- * |id: * 代表Redis自动生成ID【格式:"时间戳-递增数字"】,id 代表用户指定ID
- XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key...] ID [ID...]:
- [COUNT count]: 每次读取消息的最大数量
- [BLOCK milliseconds]: 当没有消息时,是否阻塞、阻塞长
- STREAMS key [key...]: 从指定队列读取
- ID [ID...]: 起始id,只返回大于该ID的消息,0 = 表示从第一个开始,$ = 代表从最新的消息开始
(2)特点:
- 消息可回溯
- 一个消息可以被多个消费者获取
- 可以阻塞读取
- 有消息漏读的风险(同一时间内有多条消息)
4、基于Stream的消息队列-消费者分组
(1)消费者组的特点:
- 消息可回溯: 支持持久化缓存数据。
- 消息分流: 队列中的消息会分流给组内不同的消费者,而不是重复消费,从而加快消息处理的速度。
- 消息读取: 可以阻塞读取消息,消费者组会维护一个标识,记录最后一个被处理的消息,每次读取消息都根据标识开始读取。
- 消息确认机制: 消费者获取消息后,消息状态处于pending,并存入一个pending-list,当处理完成后通过XACK确认消息,标记消息已被处理,才会从pending-list移除。
(2)Redis命令:
- XGROUP CREATE key groupName ID [MKSTREAM]: 创建消费组
- XGROUP DESTROY key groupName: 删除消费组
- XGROUP CREATECONSUMER key groupName consumername: 给指定的消费者组添加消费者
- XGROUP DELCONSUMER key groupname consumername: 删除指定消费组的指定消费者
- XREADGROUP GROUP group cunsumer [COUNT count] [BLOCK milliseconds] STREAMS key [key...] ID [ID...]: 指定消费者组读取消息,若不存在消费者,则自动创建,ID 可以使用 > 表示从下一个未消费的消息开始读取
- XPADING key group [ [IDLE min-idle-time] start end count [consumer] ]: 读取消息队列中存在的未被处理的消息,通过设置空闲处理时间(通过- + 表示从最小到最大),读取数量来获取消息,指定消费者。
5、Redis三种消息队列的对比
List | PubSub | Stream | |
---|---|---|---|
消费持久化 | 支持 | 不支持 | 支持 |
阻塞读取 | 支持 | 支持 | 支持 |
消息堆积处理 | 受限于内存空间,可以利用多消费者加快处理 | 受限于消费者缓冲区 | 受限于队列长度,利用消费者组加快消费速度 |
消息确认机制 | 不支持 | 不支持 | 不支持 |
消息回溯 | 不支持 | 不支持 | 支持 |