基于Stream的Redis消息队列

news2024/9/23 21:27:41

目录

    • 一、消息队列
    • 二、基于List结构模拟消息队列
      • 基于List的消息队列的优点:
      • 基于List的消息队列的缺点:
    • 三、基于PubSub的消息队列
      • 基于PubSub的消息队列的优点:
      • 基于PubSub的消息队列的缺点:
    • 四、基于Stream的消息队列
      • 1、XADD语法
      • 2、XREAD 语法
      • 3、STREAM类型消息队列的XREAD命令特点:
    • 五、基于Stream的消息队列-消费者组
      • 1、消息分流
      • 2、消息标示
      • 3、消息确认
    • 六、消费者组常见命令
      • 1、创建消费者组
      • 2、删除指定的消费者组
      • 3、给指定的消费者组添加消费者
      • 4、删除消费者组中的指定消费者
      • 5、从消费者组读取消息
    • 七、STREAM类型消息队列的XREADGROUP命令特点
    • 八、三种方式对比
      • NoSQL数据库进阶实战
      • 哪吒精品系列文章

一、消息队列

消息队列(Message Queue),就是存放消息的队列。

最简单的消息队列模型包括3个角色:

  1. 消息队列:存储和管理消息,也被称为消息代理(Message Broker);
  2. 生产者:发送消息到消息队列;
  3. 消费者:从消息队列获取消息并处理消息;

Redis提供了三种不同的方式来实现消息队列:

  1. list结构:基于List结构模拟消息队列;
  2. PubSub:基本的点对点消息模型;
  3. Stream:比较完善的消息队列模型;

二、基于List结构模拟消息队列

LPUSH 结合 RPOP实现队列的入口,RPUSH 结合 LPOP实现队列的出口,当队列中没有消息时RPOP或LPOP操作会返回null。并不像JVM的阻塞队列那样会阻塞并等待消息。因此这里应该使用BRPOP或者BLPOP来实现阻塞效果。

基于List的消息队列的优点:

  1. 利用Redis存储,不受限于JVM内存上限;
  2. 基于Redis的持久化机制,数据安全性有保证;
  3. 可以满足消息有序性;

基于List的消息队列的缺点:

  1. 无法避免消息丢失;
  2. 只支持单消费;

三、基于PubSub的消息队列

PubSub(发布订阅)是Redis2.0版本引入的消息传递模型。顾名思义,消费者可以订阅一个或多个channel,生产者向对应channel发送消息后,所有订阅者都能收到相关消息。

  • SUBSCRIBE channel [channel] :订阅一个或多个频道;
  • PUBLISH channel msg :向一个频道发送消息;
  • PSUBSCRIBE pattern[pattern] :订阅与pattern格式匹配的所有频道;

基于PubSub的消息队列的优点:

  1. 采用发布订阅模型,支持多生产、多消费

基于PubSub的消息队列的缺点:

  1. 不支持数据持久化;
  2. 无法避免消息丢失;
  3. 消息堆积有上限,超出时数据丢失;

四、基于Stream的消息队列

Stream 是 Redis 5.0 引入的一种新数据类型,可以实现一个功能非常完善的消息队列。

1、XADD语法

XADD 命令将指定的流条目追加到指定 key 的流中。如果 key 不存在,将使用流的条目自动创建 key。

XADD key ID field value[field value ...]

ID 标识流内的给定条目。如果指定的 ID 参数是字符*(星号 ASCII 字符),XADD 命令会自动为您生成一个唯一的 ID。但是,也可以指定一个良好格式的 ID,以便新的条目以指定的 ID 准确存储,虽然仅在极少数情况下有用。

ID 是由-隔开的两个数字组成的:1798432684128-1。两个部分数字都是 64 位的,当自动生成 ID 时,第一部分是生成 ID 的 Redis 实例的毫秒格式的 Unix 时间。第二部分只是一个序列号,以及是用来区分同一毫秒内生成的 ID 的。

ID 保证始终是递增的:如果比较刚插入的条目的 ID,它将大于其他任何过去的 ID,因此条目在流中是完全排序的。为了保证这个特性,如果流中当前最大的 ID 的时间大于实例的当前本地时间,将会使用前者,并将 ID 的序列部分递增。例如,本地始终回调了,或者在故障转移之后新主机具有不同的绝对时间,则可能发生这种情况。

当用户为 XADD 命令指定显式 ID 时,最小有效的 ID 是0-1,并且用户必须指定一个比当前流中的任何 ID 都要大的 ID,否则命令将失败。通常使用特定 ID 仅在您有另一个系统生成唯一 ID(例如 SQL 表),并且您确实希望 Redis 流 ID 与该另一个系统的 ID 匹配时才有用。

最简单的xadd语句:XADD mystream * name nezha age 18

2、XREAD 语法

XREAD [COUNT count] [BLOCK < milliseconds >] STREAMS key [key ...] ID [ID ...]

  1. count:每次读取消息的最大数量;
  2. BLOCK:当没有消息时,是否阻塞,阻塞时长,如果是0,则表示一直阻塞;
  3. STREAMS:要从哪个队列读取消息,key就是队列名;
  4. ID:起始id,只返回大于该id的消息(0表示从第一个消息开始,$代表从最新的消息开始);

最简单的xadd语句(阻塞读取):XREAD COUNT 1 BLOCK 0 STREAMS mystream $

3、STREAM类型消息队列的XREAD命令特点:

  1. 消息可回溯;
  2. 一个消息可以被多个消费者读取;
  3. 可以阻塞读取;
  4. 有消息漏读的风险

五、基于Stream的消息队列-消费者组

消费者组(Consumer Group):将多个消费者划分到一个组中,监听同一个队列。具备下列特点:

1、消息分流

队列中的消息会分流给组内的不同消费者,而不是重复消费,从而加快消息处理的速度。

2、消息标示

消费者组会维护一个标示,记录最后一个被处理的消息,哪怕消费者宕机重启,还会从标示之后读取消息。确保每一个消息都会被消费。

3、消息确认

费者获取消息后,消息处于pending状态,并存入一个pending-list。当处理完成后需要通过XACK来确认消息,标记消息为已处理,才会从pending-list移除。

六、消费者组常见命令

1、创建消费者组

XGROUP CRATE key groupName ID [MKSTREAM]

  • key:队列名称;
  • groupName:消费者组名称;
  • ID:起始id标识,$代表队列中最后一个消息,0代表队列中的第一个消息;
  • MKSTREAM:队列不存在时,自动创建队列;

2、删除指定的消费者组

XGROUP DESTORY key groupName

3、给指定的消费者组添加消费者

XGROUP CREATECONSUMER key groupName consumername

4、删除消费者组中的指定消费者

XGROUP DELCONSUMER key groupName consumername

5、从消费者组读取消息

XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]

  1. group:消费组名称
  2. consumer:消费者名称,如果消费者不存在,会自动创建一个消费者
  3. count:本次查询的最大数量
  4. BLOCK milliseconds:当没有消息时最长等待时间
  5. NOACK:无需手动ACK,获取到消息后自动确认,自动ACK可能会出现消息丢失,所以一般需要手动ACK
  6. STREAMS key:指定队列名称
  7. ID:获取消息的起始ID:“>”:从下一个未消费的消息开;其它:根据指定id从pending-list中获取已消费但未确认的消息,例如0,是从pending-list中的第一个消息开始,消费完并确认后,则会从pending-list中移除,正常情况通过">"读取消息,出现异常情况后,再从pending-list中读取。

七、STREAM类型消息队列的XREADGROUP命令特点

  1. 消息可回溯
  2. 可以多消费者争抢消息,加快消费速度
  3. 可以阻塞读取
  4. 没有消息漏读的风险
  5. 有消息确认机制,保证消息至少被消费一次

八、三种方式对比

ListPubSubStream
消息持久化支持不支持支持
阻塞读取支持支持支持
消息堆积处理受限于内存空间,可以利用多消费者加快处理受限于消费者缓冲区受限于队列长度,可以利用消费者组提高消费速度,减少堆积
消息确认机制不支持不支持支持
消息回溯不支持不支持支持



NoSQL数据库进阶实战

NoSQL数据库进阶实战1,那些年学过的NoSQL基础

NoSQL数据库进阶实战2,NoSQL数据存储模式

Redis缓存穿透、击穿、雪崩到底是个啥?7张图告诉你

Redis分布式锁的实现方式

Redis分布式缓存、秒杀

哪吒精品系列文章

Java学习路线总结,搬砖工逆袭Java架构师

10万字208道Java经典面试题总结(附答案)

Java基础教程系列

Java高并发编程系列

数据库进阶实战系列
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/132132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ Primer笔记——allocator、unique_ptr和release、智能指针与动态数组、阻止拷贝

目录 一.P418 unique_ptr和release 二.P426 智能指针与动态数组 &#xff08;一&#xff09;.unique_ptr &#xff08;二&#xff09;.shared_ptr 三.P428 allocator &#xff08;一&#xff09;.申请空间 &#xff08;二&#xff09;.初始化构造 &#xff08;三&#…

活动星投票少儿模特大赛网络评选制作一次图文分组投票怎么制作

关于微信投票&#xff0c;我们现在用的最多的就是小程序投票&#xff0c;今天的网络投票&#xff0c;在这里会教大家如何用“活动星投票”小程序来进行投票。我们现在要以“国际车展少儿模特大赛”为主题进行一次投票活动&#xff0c;我们可以在在微信小程序搜索&#xff0c;“…

aws cloudformation 使用模板配置 ecs 蓝绿部署

参考资料 Perform ECS blue/green deployments through CodeDeploy using AWS CloudFormationAWS::CodeDeployBlueGreen 在之前的文章中&#xff0c;使用codepipeline中通过控制台的方式创建了ecs蓝绿部署的demo。实际上可以单独通过codedeploy完成ecs服务的蓝绿部署 参考官…

【ARMv8 SIMD和浮点指令编程】Libyuv I420 转 ARGB 流程分析

Libyuv 可以说是做图形图像相关从业者绕不开的一个常用库&#xff0c;它使用了单指令多数据流提升性能。以 ARM 处理为主线&#xff0c;通过 I420 转 ARGB 流程来分析它是如何流转的。 Libyuv 是一个开源项目&#xff0c;包括 YUV 的缩放和转换功能。 使用邻近、双线性或 box…

QThread、moveToThread用法详述

1.吐槽 QThread类提供了一种平台无关的方法对线程进行管理。但对于QThread类的熟练使用&#xff0c;即使是从事Qt开发多年的程序猿们&#xff0c;往往也会踩雷、入坑。总之&#xff1a;QThread类不好用、如果对该类理解不透&#xff0c;很容易导致程序崩溃。本人强烈建议&#…

(函数介绍)puts()函数

功能介绍 1. puts()函数用来向标准输出设备屏幕输出字符串并换行。 2. 函数的参数就是一个起始的地址&#xff0c;然后就从这个地址开始一直输出字符串&#xff0c;直到碰到\0就停止&#xff0c;然后这个\0是不进行输出的&#xff0c;是不能够算在里面的。与此同时&#xff…

十、字节缓冲流、字符流、转换流、对象操作流、对象序列化流

字节缓冲流 构造方法 字节缓冲流介绍 BufferedOutputStream&#xff1a;该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用BufferedInputStream&#xff1a;创建BufferedInputStream将创建一个内部缓冲区数…

2022年为什么要学习C语言?

为什么学习c语言 为什么学C语言逻辑&#xff1f; 为什么要学习C语言&#xff1f; 学习C语言的主要理由有以下几点&#xff1a; C语言可以作为学习计算机程序设计语言的入门语言&#xff1b; C语言是编写操作系统的首选语言&#xff0c;与计算机硬件打交道时灵巧且高效&…

labelImag安装与使用及构造数据集

在做目标检测任务时&#xff0c;需要进行标注&#xff0c;选择了LabelImg作为标注工具&#xff0c;下面是安装及使用过程。 我们使用Anconda的虚拟环境进行安装&#xff0c;激活环境后&#xff0c;执行&#xff1a; pip install labelimg -i https://pypi.tuna.tsinghua.edu.c…

代码随想录算法训练营第四天 java : 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交,142环形链表II

文章目录Leetcode 24. 两两交换链表中的节点题目链接本题思路需要注意的点AC 代码Leetcode 19.删除链表的倒数第N个节点题目链接需要注意的点AC代码Leetcode面试题 02.07. 链表相交题目链接这个略了Leetcode 142环形链表II题目链接难点:AC代码今日收获**一朵玫瑰正马不停蹄地成…

【Linux】Linux下基本指令(三)

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Linux》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 1. Linux基本指令&#xff1a;&#xff08;续&#xff09; 1.1zip指令和u…

极智编程 | C++模板函数

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多笔记分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍一下 C模板函数。 模板函数是 C 中一种特殊的函数&#xff0c;它的类型参数列表用尖括号 <> 括起来&#xff0c;放在函数名的后面。使用模板函数&a…

Go 并发

来自 《Go 语言从入门到实战》 的并发章节学习笔记&#xff0c;欢迎阅读斧正&#xff0c;感觉该专栏整体来说对有些后端编程经验的来说比无后端编程经验的人更友好。。 Thread VS Groutine 创建时默认 Stack 大小&#xff1a;前者默认 1M&#xff0c;Groutint 的 Stack 初始化…

C语言可变参数与内存管理

有时&#xff0c;您可能会碰到这样的情况&#xff0c;您希望函数带有可变数量的参数&#xff0c;而不是预定义数量的参数。C 语言为这种情况提供了一个解决方案&#xff0c;它允许您定义一个函数&#xff0c;能根据具体的需求接受可变数量的参数。下面的实例演示了这种函数的定…

LeetCode题解 二叉树(八):404 左叶子之和;513 找树左下角的值;112 路径总和;113 路径总和II

二叉树 404 左叶子之和 easy 左叶子结点也好判断&#xff0c;若某结点属于左结点&#xff0c;且无子树&#xff0c;就是左叶子结点 即也如此&#xff0c;所以如果要判断&#xff0c;必然要从父结点下手&#xff0c;涉及到三层结点的处理 如果要使用递归法&#xff0c;要使用…

(二十三)大白话数据库服务器上的RAID存储架构的电池充放电原理

文章目录 1、RAID卡的缓存2、RAID卡的缓存里的数据会突然丢失怎么办?3、锂电池存在性能衰减问题1、RAID卡的缓存 服务器使用多块磁盘组成的RAID阵列的时候,一般会有一个RAID卡,这个RAID卡是带有一个缓存的,这个缓存不是直接用我们的服务器的主内存的那种模式,他是一种跟内…

网络静态路由综合实验

1.首先分配ip,配置ip和环回 [Huawei]sysname R1 [R1]interface LoopBack 0 [R1-LoopBack0]ip add 192.168.1.33 28 [R1-LoopBack0]q [R1]int l 1 [R1-LoopBack1]ip add 192.168.1.49 28 [R1-LoopBack1]q [R1]int g 0/0/0 [R1-GigabitEthernet0/0/0]ip add 192.168.1.1 30 [R1-…

JVM与Java体系结构

目录 前言 架构师每天都在思考什么&#xff1f; Java vs C Java生态圈 字节码 多语言混合编程 虚拟机与Java虚拟机 虚拟机 Java虚拟机 JVM的位置 JVM整体结构 Java代码执行流程 JVM的架构模型 举例 字节码反编译 总结 栈 JVM生命周期 虚拟机的启动 虚拟机的…

时间从来不语,确回答了所有问题——我的2022年终总结

趁着没阳&#xff0c;趁着电脑还能开机&#xff0c;趁着还能写&#xff0c;赶紧小结过去这一年。没有别的感觉&#xff0c;就是感觉太快&#xff0c;时间太过匆匆.....最大的感触是两个字“变化”&#xff0c;如果非要说四个字是“变化太快”&#xff0c;就如当下的yi情政策&am…

多线程_进阶

文章目录线程通信概念使用方式案例单例模式阻塞式队列线程池常见的锁策略乐观锁 悲观锁CASCAS存在的问题:ABA问题读写锁自旋锁公平锁 非公平锁非公平锁公平锁synchronizedjvm对synchronized的优化:锁升级synchronized的其他优化Lock体系synchronized vs lock独占锁vs共享锁独占…