消息队列
最简单的消息队列模型包括 3 个角色
1、消息队列:存储、管理消息,也被称为消息代理(Message Broker)
2、生产者:发送消息到消息队列
3、消费者:从消息队列获取消息,并处理消息
Redis 提供三种实现
1、List结构:基于 List 结构模拟消息队列
2、PubSub:基本的点对点消息模型
3、Stream:比较完善的消息队列模型
List
1、双向链表
(1)容易模拟出队、入队
(2)队列的入口、出口不在同一边,可以利用:LPUSH 结合 RPOP、或 RPUSH 结合 LPOP
(3)注意:当队列中没有消息时,RPOP 或 LPOP 返回 null,并不阻塞并等待消息,因此应该使用 BRPOP 或 BLPOP 实现阻塞效果
2、优点
(1)利用 Redis 存储,不受限于 JVM 内存上限
(2)基于 Redis 持久化机制,数据安全性有保证
(3)可以满足消息有序性
3、缺点
(1)无法避免消息丢失
(2)只支持单消费者
PubSub(发布订阅)
1、Redis 2.0 引入的消息传递模型
(1)消费者可以订阅一个或多个 channel
(2)生产者向对应 channel 发送消息后,所有订阅者都能收到相关消息
2、优点:采用发布订阅模型,支持多生产、多消费
3、缺点
(1)不支持数据持久化
(2)无法避免消息丢失
(3)消息堆积有上限,超出时数据丢失
Stream
1、Redis 5.0 引入的一种新数据类型,可以实现一个功能非常完善的消息队列
2、将指定的流 entry 追加到指定 key 的流中
XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold [LIMIT count]] <* | id> field value [field value ...]
(1)如果 key 不存在,将使用流的 entry 自动创建 key
(2)一个 entry 是由一组键值对组成,它基本上是一个小的字典
(3)键值对以用户给定的顺序存储,并且读取流的命令(如 XRANGE 或 XREAD) 可以保证按照通过 XADD 添加的顺序返回
(4)XADD 是唯一可以向流添加数据的 Redis 命令
(5)如果指定 ID 参数是字符 *(星号 ASCII 字符),XADD 命令会自动生成一个唯一 ID
(6)可以指定一个良好格式 ID,以便新的 entry 以指定 ID 准确存储, 虽然仅在极少数情况下有用
(7)ID 由 - 隔开的两个数字组成:两个部分数字都是 64 位,当自动生成 ID 时,第一部分是生成 ID 的 Redis 实例的毫秒格式的 Unix 时间,第二部分只是一个序列号,以及用来区分同一毫秒内生成的 ID
(8)ID 保证始终递增,因此 entry 在流中是完全排序的,为了保证这个特性,如果流中当前最大 ID 的时间,大于实例的当前本地时间,将会使用前者,并将 ID 的序列部分递增
(9)当用户为 XADD 指定显式 ID 时,最小有效的 ID 是 0-1,并且用户必须指定一个比当前流中的任何 ID 都要大的 ID,否则命令将失败
(10)通常使用特定 ID,仅在有另一个系统生成唯一 ID(例如 SQL 表), 并且确实希望 Redis 流 ID 与该另一个系统的 ID 匹配时才有用
(11)MAXLEN 限制流中的最大元素数量
(12)MAXLEN ~ 实际计数,不是精确指定数量,可以多几十个 entry,但不能少于指定数量,通过~,仅当移除整个节点时候才执行修整,这使得命令更高效
(13)返回添加的 entry 的 ID,如果 ID 参数传 *,则 ID 是自动生成的,否则,命令仅返回用户在插入期间指定的相同的 ID
3、从一个或多个流中读取数据,仅返回ID大于调用者报告的最后接收ID的条目
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
(1)如果未提供 BLOCK,此命令是同步的,并可以认为与 XRANGE 有些相关:它将会返回流中的一系列项目,但与 XRANGE相比它有两个基本差异(若只考虑同步使用)
(2)如果从多个键同时读取,则可以使用多个流调用此命令,在使用 BLOCK 进行阻塞时,能够通过单个连接监听多个键
(3)XRANGE 返回一组 ID 中的项目,XREAD 更适合用于从第一个 entry 开始使用流,因此传递给 XREAD 的是,对于每个流,我们从该流接收的最后一个 entry 的 ID
(4)COUNT 对于每一个流,调用将返回每个流最多 count 个元素
(5)STREAMS 强制,并且必须是最后一个选项,只返回大于指定 ID 的消息;
(6)不完整 ID 有效,如果部分 ID 缺少,将总是被解释为 0
(7)BLOCK,指定超时前阻塞毫秒数,请求的 key 之一接收数据,自动解除阻塞,超时时间已到但没有新数据到达,返回 nil,这个命令是扇形分发到所有正在等待相同ID范围的客户端,因此每个消费者都将得到一份数据副本
(8)STREAMS
(9)该命令返回一个二维数组,每个一维数组都是一个由两个元素组成(键名、为该键报告的 entry),报告的 entry 是完整的流 entry,具有 ID、所有字段、值的列表,返回 entry 及其字段和值的顺序,与使用 XADD 添加它们的顺序完全一致
消费者组
1、Consumer Group
2、将多个消费者划分到一个组中,监听同一个队列
3、特点
(1)消息分流:队列中的消息会分流给组内的不同消费者,而不是重复消费,从而加快消息处理的速度
(2)消息标示:消费者组会维护一个标示,记录最后一个被处理的消息,哪怕消费者宕机重启,还会从标示之后读取消息,确保每一个消息都会被消费
(3)消息确认:消费者获取消息后,消息处于 pending 状态,并存入一个 pending-list,当处理完成后需要通过 XACK 来确认消息,标记消息为已处理,才会从 pending-list 移除
4、该命令用于管理流数据结构关联的消费者组
XGROUP [CREATE key groupname id-or-$] [SETID key id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
(1)创建与流关联的新消费者组
XGROUP CREATE key groupname id-or-$
(2)$:从该消费者组获取数据的消费者,只能看到到达流的新元素
(3)0:消费者组获取整个流的历史记录
(4)如果指定的消费者组已经存在,则该命令将返回 -BUSYGROUP 错误,否则将执行该操作并返回 OK
(5)可以为给定的流关联无限多的消费者组,没有硬性限制
(6)销毁一个消费者组,即使存在活动的消费者、待处理消息,消费者组也将被销毁
XGROUP [DESTROY key groupname]
(7)从消费者组中移除指定的消费者
XGROUP [DELCONSUMER key groupname consumername]
(8)通常情况下,在消费者创建时设置下一个 ID,作为 XGROUP CREATE 最后一个参数
(9)将消费者组的最后交付 ID,设置为要传递的下一条消息,返回消费者在被删除之前,所拥有的待处理消息数量
XGROUP [SETID key id-or-$]
(10)每当某个命令提到新的消费者名称时,就会自动创建消费者组中的消费者
5、XREADGROUP 是 XREAD 特殊版本,支持消费者组
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
(1)组名只是关联到流的消费者组的名称,该组是使用 XGROUP 创建
(2)消费者名称是客户端用于在消费者组内,标识自己的字符串,消费者会在第一次出现在消费者组内时,被自动创建,不同的消费者应该选择不同的消费者名称
(3)当使用 XREADGROUP 读取时,服务器将会记住已经传递的某个给定消息:消息会被存储在消费者组内的待处理条目列表(PEL)中,即已送达但尚未确认的消息 ID 列表
(4)客户端必须使用 XACK 确认消息处理,以便从待处理条目列表中删除待处理条目,可以使用 XPENDING 检查待处理条目列表
(5)STREAMS >:消费者希望只接收从未发送给任何其他消费者的消息,即新的消息
(6)STREAMS 任意其他 ID:让客户端访问它的待处理条目列表(PEL)
(7)当消息被传递给消费者时,如果消息从未被发送给其他消费者,则创建待处理条目列表(PEL)
(8)如果该消息已经发送给该消费者,并且它只是再次重新获取相同的消息,那么最后送达时间会被更新为当前时间,并且送达次数会加 1
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战