【Redis笔记】Redis消息队列方案

Reids消息队列(Message Queue)

消息队列 是指利用 高效可靠 的 消息传递机制 进行与平台无关的 数据交流,并基于数据通信来进行分布式系统的集成。
消息队列具有 低耦合、可靠投递、广播、流量控制、最终一致性 等功能。
常见的消息队列 有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ 等。
通过提供 消息传递 和 消息排队 模型,它可以在 分布式环境 下提供 应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步 等功能。

基于List结构的模拟消息队列

Redis的list数据结构是一个双向链表,使用出队入队即可实现消息队列。

LPUSH 、RPOP 或 RPUSH 、 LPOP

LPUSH:将一个或多个值value插入到列表key的表头如果有多个value值,那么各个value值按从左到右的顺序依次插入到表头。
RPOP:移除并返回列表key的尾元素。
RPUSH与LPOP同理。
通过 LPUSH,RPOP 这样的方式,会存在一个性能风险点,就是消费者如果想要及时的处理数据,就要在程序中写个类似 while(true) 这样的逻辑,不停地去调用 RPOP 或 LPOP 命令,这就会给消费者程序带来些不必要的性能损失。

LPUSH、BRPOP 或 RPUSH、BLPOP

Redis 还提供了 BLPOP、BRPOP 这种阻塞式读取的命令(带 B-Bloking的都是阻塞式),客户端在没有读到队列数据时,自动阻塞,直到有新的数据写入队列,再开始读取新数据。这种方式就节省了不必要的 CPU 开销。

数据存入格式:lpush listname v1 v2 v3

v 表示存入链表的值

阻塞等待指令格式:blpop list_name timeout

listname 为 取出内容的列表名
timeout为等待超时时间,如果为0,则可无限等待

优点

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

缺点

  • 无法避免消息丢失:从redis中取出消息后,如果尚未处理完出现异常,取出的消息就丢失了
  • 只支持单消费者,一条消息被取走后,其他消费者无法再获取。

基于PubSub的消息队列

"发布/订阅"模式包含两种角色,分别是发布者和订阅者。订阅者可以订阅一个或者多个频道(channel),而发布者可以向指定的频道(channel)发送消息,所有订阅此频道的订阅者都会收到此消息。

常用的指令:
subscribe channel1 [channel...]: 订阅一个或多个频道
publish channel1 msg:向一个频道发送消息
psubscribe pattern [pattern]:订阅与pattern格式匹配的所有频道

pattern通配符:
h?llo:?可以替换为任意一个其他字母,比如hello;而hllo和hkkllo不行
hllo: 可以替换为0个或多个其他字母,比如hllo、hello、heeeello
h[ae]llo:可以替换为任意一个中括号中的字母,比如hallo、hello;而hillo不行

优点

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

缺点

  • 不支持数据持久化;如果出现网络断开、Redis 宕机等,消息就会被丢弃。假设一个消费者都没有,那消息就直接被丢弃了。
  • 无法避免消息丢失。
  • 消息堆积有上限、超出时数据丢失。

基于Stream的消息队列——单消费方式

Redis 5.0 版本新增了一个更强大的数据结构——Stream。它提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

存入消息的方式之一_XADD

命令格式:XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold [LIMIT count]] <* | id> field value [field value ...]

NOMKSTREAM:如果队列不存在,是否自动创建队列,默认自动创建
<MAXLEN | MINID> [= | ~] threshold [LIMIT count] :设置消息队列的最大消息数量
<* | id> 消息的唯一id,* 代表由redis自动生成。* 格式是"时间戳-递增数字",例如"1644804662707-0"
field value [field value …]:发送到队列中的消息队列,称为Entry。格式就是多个key-value键值对。

示例:

# 创建名为 users 的队列,并向其中发送一个消息,内容是:{name=jack,age=21},并且使用Redis自动生成id
XADD users * name jack age 21

读取消息的方式之一——XREAD

命令格式:XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]

[COUNT count]:每次读取消息的最大数量
[BLOCK milliseconds]:当没有消息时,是否阻塞、阻塞时长
STREAMS key [key …]:要从哪个队列读取消息,key就是队列名
起始id,只返回大于该id的消息;0代表从第一个消息开始;$代表从最新的消息开始

读取最新的消息示例:

XREAD COUNT 1 BLOCK 1000 STREAMS users $

优点

  • 消息可回溯
  • 一个消息可被多个消费者读取
  • 可以阻塞读取

缺点

  • 有消息漏读风险

基于Stream的消息队列——消费者组

消费者组:将多个消费者划分到一个组里,监听同一个队列。

特点

  • 消费分流:队列中的消息会分流给组内的不同消费者,而不是重复消费,加快消息的处理速度。
  • 消息标识:消费者组会维护一个标示,记录组内最后一个被处理的消息,哪怕消费者宕机重启,还是能够从标示之后读取消息,确保每一个消息都被消费。
  • 消息确认:消费者获取消息之后,消息处于pending状态,并存入一个pending-list。当处理完后需要XACK来确认消息,标记消息已处理,之后才会从pending-list移除。

创建消费者组

XGROUP CREATE key groupName ID [MKSTREAM]

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

其他对应指令:

# 删除指定的消费者组
XGROUP DESTROY key group# 给指定的消费者组添加消费者
XGROUP CREATECONSUMER key group consumer# 删除消费者组中的指定消费者
XGROUP DELCONSUMER key group consumer

从消费者组读取消息

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

group:消费者组名称
consumer:消费者名称,如果消费者不存在,会自动创建一个消费者
count:本次查询的最大数量
BLOCK milliseconds:当前消息等待最大时长
NOACK:无需手动ACK,获取消息后自动确认
STREAMS key:指定监听一个或多个队列名称
ID:获取消息的起始ID:

  • “ >” 从下一个未消费的消息开始
  • 其他:根据指定ID从pending-list中获取一个消费但未确认的消息,例如0,是从pending-list中第一个消息开始

确认消息

XACK key group id [id ...]

key:消息队列名称
group:组名
id:确认的消息ID

查看未确认的消息

XPENDING key group [[IDLE min-idle-time] start end count [consumer]]

总结

如果业务要求较高,可以考虑使用更加专业的 Kafka、RocketMQ、RabbitMQ。

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

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

相关文章

ensp路由器将不同网络连通在一起

1.拓扑结构信息如下 二层交换机&#xff1a;lsw2,lsw3,lsw5,lsw6 不进行ip配置&#xff0c;只是定义vlan&#xff0c;和主机标注的保持一致&#xff0c;向下连接pc用access&#xff0c;向上连接路由交换机用trunk lsw2配置信息如下图 定义vlan&#xff0c;设置各个连接口的方式…

tcpdump 常用用法

简要记录下tcpdump用法 监控某个ip上的某个端口的流量 tcpdump -i enp0s25 tcp port 5432 -nn -S 各个参数作用 -i enp0s25 指定抓包的网卡是enp0s25 -nn 显示ip地址和数字端口 &#xff0c;如果只 -n 则显示ip&#xff0c;但是端口为services文件中的服务名 如果一个…

用python写一个自动化部署工具

效果 起因 现在springboot项目的自动化部署已经非常普遍&#xff0c;有用Jenkins的&#xff0c;有用git钩子函数的&#xff0c;有用docker的…等等。这段时间在玩python&#xff0c;想着用python实现自动化部署&#xff0c;即能锻炼下编码能力&#xff0c;又方便运维。于是开始…

每日学习总结20240228

每日总结 20240228 1.获取系统命令执行结果 #include <stdio.h>#define TRUE 1 #define FALSE 0int get_system_cmd_result(const char *command, char *buffer, int bufferLen) {FILE *pipe popen(command, "r");if (pipe NULL) {return FALSE;}while (f…

HTML-表格、表单和CSS初识,选择器,书写规范

&#xff11;. 表格标签 &#xff11;.&#xff11;创建表格 表格标签是一种用来处理&#xff0c;显示表格式数据的常用标签。 注意&#xff1a; &#xff11;. tr 用于定义表格中的一行&#xff0c;必须嵌套在 table标签中&#xff0c;在 table中包含几对 tr&#xff0c;就有…

实用指南:SOLIDWORKS数据失真问题的解决之道

在数据处理和模拟计算的过程中&#xff0c;数据失真是一个常见的挑战。数据失真指的是由于计算机或人为操作导致的原始数据与计算结果或实际情况之间的偏差。特别是在使用SOLIDWORKS这类工程设计软件时&#xff0c;数据失真可能由多种因素引起&#xff0c;如软件版本老旧、设置…

AI大模型-启航

文章目录 什么是大模型&#xff1f;&#xff08;大体现在参数量巨大&#xff09;大模型将会改变那些行业&#xff08;大模型有哪些作用&#xff1f;&#xff09;如何搞数据训练模型&#xff1f;LangChain带来的技术变革LangChain架构 什么是大模型&#xff1f;&#xff08;大体…

九、GG bond的逻辑运算

描述 GG bond想要锻炼自己的逻辑能力&#xff0c;于是输入了两个整型变量x和y&#xff0c;分别判断它们的与、或、非关系&#xff0c;你能帮他输出x与y&#xff0c;x或y&#xff0c;非x&#xff0c;非y的值吗&#xff1f; 输入描述&#xff1a; 输入两个整数x和y&#xff0c…

Vue+SpringBoot打造不良邮件过滤系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统用户模块2.2 收件箱模块2.3 发件箱模块2.4 垃圾箱模块2.5 回收站模块2.6 邮箱过滤设置模块 三、实体类设计3.1 系统用户3.2 邮件3.3 其他实体 四、系统展示五、核心代码5.1 查询收件箱档案5.2 查询回收站档案5.3 新…

Linux学习-etcdctl安装

etcdctl3.5下载链接 1. 先通过上面链接下载gz包2. 解压 [rootk8s-master ~]# tar xf etcd-v3.5.11-linux-amd64.tar.gz [rootk8s-master etcd-v3.5.11-linux-amd64]# ls Documentation etcd etcdctl etcdutl README-etcdctl.md README-etcdutl.md README.md READMEv2-e…

图像分割 - 查找图像的轮廓(cv2.findContours函数)

1、前言 轮廓,是指图像中或者物体的外边缘线条。在简单的几何图形中,图形的轮廓是由平滑的线条构成,容易被识别。但不规则的图形或者生活中常见的物体轮廓复杂,识别起来比较困难 2、findContours函数 这里先介绍函数的参数,具体的含义会在下面实验中阐述 opencv 提供的轮…

『大模型笔记』自用的“科技文章翻译 GPT”和它的 Prompt

自用的“科技文章翻译 GPT”和它的 Prompt 你是一位精通简体中文的专业翻译,尤其擅长将专业学术论文翻译成浅显易懂的科普文章。请你帮我将以下英文段落翻译成中文,风格与中文科普读物相似。规则: - 翻译时要准确传达原文的事实和背景。 - 即使上意译也要保留原始段落格式,…

每天一个数据分析题(一百八十四)

在下列哪种情况下线性回归模型不适合代替逻辑回归模型&#xff1f; A. 预测的目标变量是连续型的并且分布范围不受限制 B. 预测的目标变量是二元的并且服从二项分布 C. 自变量与因变量之间的关系可以假设为线性关系 D. 需要预测客户的具体购买金额 题目来源于CDA模拟题库 …

React入门之React_渲染基础用法和class实例写法

渲染元素 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>04元素渲染</title><script src&…

什么是RPC?谈谈你对RPC的理解

RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种计算机通信协议。它允许一台计算机&#xff08;客户端&#xff09;通过网络调用另一台计算机&#xff08;服务器&#xff09;上的程序&#xff0c;并等待该程序的结果返回。RPC抽象了网络通信的…

go mod中如何解决 xxx/yyy/lib@v1.1.0: unrecognized import path

需要检查的几个地方 这个错误通常出现在 Go 模块系统无法找到指定版本的模块时。有几种可能的原因和解决方法&#xff1a; 模块未被发布或标记&#xff1a; 确保 xxx/yyy/lib 模块的版本 v1.1.0 已经被正确地发布或标记。你可以在对应的 GitLab 仓库中查看是否存在 v1.1.0 标签…

2024-2-29-网络编程作业

1>TCP 源代码: 服务器端&#xff1a; #include <myhead.h> #define SER_IP "10.168.1.111" #define SER_PORT 8888 #define MAXSIZE 128 int main(int argc, char const *argv[]) {int sfd socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in sin;sin…

代码随想录算法训练营|day47

第九章 动态规划 198.打家劫舍213.打家劫舍II337.打家劫舍III代码随想录文章详解 198.打家劫舍 dp[i]表示偷第i家及之前所能获取的最大金额 偷第i家&#xff1a;dp[i] dp[i-2]nums[i]&#xff0c;不偷第i家&#xff1a;dp[i] dp[i-1] func rob(nums []int) int {if len(num…

RDD简介与基础编程

1. 什么是RDD&#xff1f; RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做弹性分布式数据集&#xff0c;是Spark中最基本的数据处理模型。在代码中&#xff0c;RDD是一个抽象类&#xff0c;他代表着一个弹性的、不可变的、可分区的、里面的元素可并行计算的集…

android TextView 实现富文本显示

android TextView 实现富文本显示&#xff0c;实现抖音直播间公屏消息案例 使用&#xff1a; val tvContent: TextView helper.getView(R.id.tvContent)//自己根据UI业务要求&#xff0c;可以控制 图标显示 大小val levelLabel MyImgLabel( bitmap 自己业务上的bitmap )va…