消息队列

最简单的消息队列模型包括 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 XADDentryXREAD使

(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

 

posted @   半条咸鱼  阅读(304)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示