Redis作为消息队列的优劣

2023-11-08

Redis缓存问题

Redis作为消息队列的优劣

Redis集群模式下保证可迁移和高可用——一致性算法

Redis热Key问题解决方案汇总


Redis基于内存,高性能并且提供多种数据结构供使用,那么对于Redis能不能作为消息队列?以及与专业的消息队列,如RocketMQ,Kafka等差距又在哪里?

Redis提供多种方式实现消息队列,基于List,基于Pub/Sub等,如今基本广泛使用的是Redis5.0之后推出的Stream流格式,其具有支持持久化,支持消息的多播、分组消费,支持消息的有序性,支持消费者组等特点,考虑到和专业消息队列之间的区别,这里主要从以下三个角度考虑Redis作为消息队列的利弊:

生产者:

当生产者在发布消息时,可能发生以下异常情况:

  • 消息未发送:网络故障或其它问题导致发布失败,中间件直接返回失败

  • 发送状态不确定:网络问题导致发布超时,可能数据已发送成功,但读取响应结果超时了

这两种情况都可以通过重发消息解决,生产者一般会设定一个最大重试次数,超过上限依旧失败,需要记录日志报警处理。也就是说,生产者为了避免消息丢失,只能采用失败重试的方式来处理。这也意味着消息可能会重复发送。根据实际情况,需要在消费者端考虑幂等性。

所以,无论是 Redis 还是专业的队列中间件,生产者在这一点上都是可以保证消息不丢的。

消费者

当消费者拿到消息后,还没处理完成,就异常宕机了,那消费者还能否重新消费失败的消息?

要解决这个问题,消费者在处理完消息后,需要向中间件发送一个ACK, Redis也是可以做到的。

Redis本身

Redis 在以下 2 个场景下,都会导致数据丢失

  • AOF 持久化配置为每秒写盘,但这个写盘过程是异步的,Redis 宕机时会存在数据丢失的可能

  • 主从复制也是异步的,主从切换时,也存在丢失数据的可能(从库还未同步完成主库发来的数据,就被提成主库)

像 RabbitMQ 或 Kafka 这类专业的队列中间件,在使用时,一般是部署一个集群,生产者在发布消息时,队列中间件通常会写「多个节点」,以此保证消息的完整性。这样一来,即便其中一个节点挂了,也能保证集群的数据不丢失。

消息积压

因为 Redis 的数据都存储在内存中,这就意味着一旦发生消息积压,则会导致 Redis 的内存持续增长,如果超过机器内存上限,就会面临被 OOM 的风险。Redis 的 Stream 提供了可以指定队列最大长度的功能,就是为了避免这种情况发生。

但 Kafka、RabbitMQ 这类消息队列就不一样了,它们的数据都会存储在磁盘上,磁盘的成本要比内存小得多,当消息积压时,无非就是多占用一些磁盘空间,相比于内存,在面对积压时也会更加「坦然」。

综上,可以看到,把 Redis 当作队列来使用时,面临以下 2 个问题:

  • Redis 本身可能会丢数据

  • 面对消息积压,Redis 内存资源紧张

然而,Redis也并不是没有优点,如果你的业务场景足够简单,对于数据丢失不敏感,而且消息积压概率比较小的情况下,把 Redis 当作队列是完全可以的。而且,Redis 相比于 Kafka、RabbitMQ,部署和运维也更加轻量。

如果你的业务场景对于数据丢失非常敏感,而且写入量非常大,消息积压时会占用很多的机器资源,那么我建议你使用专业的消息队列中间件。

总结

大部分使用消息队列的场景都可以使用stream替代。基于redis的高性能和使用内存的机制使得其的性能优于大部分消息队列。在小规模场景会有更出色的表现。但是针对大流量的场景不推荐使用Redis,毕竟内存的大小是有限的,并且Redis也是不可靠的,这也是所有redis实现的消息队列的局限之处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis作为消息队列的优劣 的相关文章

  • 使用 TLS PSK 加密时如何正确检测流结束?

    我已经准备好了一个简单的 TLS PSK 客户端测试用例 https github com afarber jetty newbie tree master TlsPskClient2 src main java de afarber tl
  • 在java代码中创建postgresql表

    我有一个与 postgreSQL 数据库连接的 java 代码 现在 我希望当它连接到数据库时 我还将创建数据库表 但我的问题是 它不会创建数据库 我不知道问题是什么 这是我的代码 Statement st null ResultSet r
  • Selector.close() 是否关闭所有客户端套接字?

    我是 nio 套接字的新手 我已经使用 nio 套接字编写了一个服务器 现在我正在尝试编写关闭钩子以确保通过清理资源正常退出 我的问题是Selector close 方法关闭所有客户端套接字 如果没有 请告诉我如何访问所有客户端套接字 而无
  • Java 错误和警告列表

    在哪里 如何获得所有 java 和 javac 的错误和警告消息的列表 This http mindprod com jgloss compileerrormessages html我认为页面是您所需要的
  • 二元运算符 >=、-、* 的错误操作数类型

    我无法弄清楚如何修复代码中不断出现的这些错误 import java util Scanner public class Unit02Prog1 public static void main String args Scanner inp
  • Spring Data Jpa OneToMany 同时保存子实体和父实体?

    这是我的父实体 注意 为了简洁起见 删除了 getter setter lombok 注释 Entity public class Board Id GeneratedValue strategy GenerationType IDENTI
  • 无法在 Intellij 中运行主类[重复]

    这个问题在这里已经有答案了 我有以下项目结构 ProjectRoot src Main examples libs My src文件夹被标记为sources在 Intellij 中 现在 当我想运行 Main 类时 出现以下错误 Excep
  • 是否可以创建 Java RAM 磁盘以与 java.io.* API 一起使用?

    我正在使用一个第三方库 它基本上创建一个输出目录 其中包含不同类型的文件和子目录 我希望能够编写单元测试来确认输出正确 我希望能够将库与 RAM 磁盘一起使用 这样库所做的任何事情都不会以任何方式接触实际的磁盘板 这个想法是让测试运行和清理
  • 生成一定长度的所有排列

    假设我们有一个字母表 abcdefghiklimnop 如何以有效的方式以五个一组的形式重复该字母表来递归生成排列 几天来我一直在为此苦苦挣扎 任何反馈都会有帮助 本质上这与 生成给定字符串的所有排列 https stackoverflow
  • 扩展多个类

    我知道 Java 不支持多重继承 因为不允许扩展多个类 我只是想知道我的问题是否有解决方法 我有一个名为CustomAction需要扩展两个抽象类 BaseAction and QuoteBaseAction 我无法更改这些抽象类中的任何一
  • 从字符串中删除重音符号

    Android 中有没有什么方法 据我所知 没有 java text Normalizer 可以从字符串中删除任何重音 例如 变成 eau 如果可能的话 我想避免解析字符串来检查每个字符 java text NormalizerAndroi
  • BigDecimal汇总统计

    我有一个 BigDecimal 列表 List
  • React Native v0.71.8 React-native-vector-icons 你看不到的图标

    我在用react native版本v0 71 8 我安装了react native vector icons库 但图标未显示 似乎链接在最新版本的 React Native 中不再起作用 所以我按照说明进行操作 但它不再编译 出现以下错误
  • Hybris:如何在impex中导入zip文件中的媒体?

    我知道我们可以导入未像这样压缩的图像 siteResource jar com project initialdata constants ProjectInitialDataConstants projectinitialdata imp
  • 如何使用 AffineTransform.quadrantRotate 旋转位图?

    我想旋转一个bitmap关于它的中心点 然后将其绘制成更大的图形上下文 位图是40x40 pixels 图形上下文是500x500 pixels 这就是我正在做的 BufferedImage bi new BufferedImage 500
  • 难以理解 通配符

    我有一个非常基本的问题 下面的代码无法编译 假设 Apple Extends Fruit List
  • 为什么/何时应该使用泛型方法?

    学习Java的时候遇到过通用方法 public
  • Spring MVC:通用 DAO 和服务类

    我正在 Spring MVC 中编写网页 我使用 Generic DAO 编写了所有 DAO 现在我想重写我的服务类 我该如何写 通用服务 我的 DAO 如下 DAO package net example com dao import j
  • Axis2 的 wsdl2java 在 RPC/Encoded 样式 Web 服务上失败

    Axis2 有替代方案吗 或者让它工作的方式 例如不同的数据绑定 Retrieving document at Exception in thread main org apache axis2 wsdl codegen CodeGener
  • MyBatis 枚举的使用

    我知道以前有人问过这个问题 但我无法根据迄今为止找到的信息实施解决方案 所以也许有人可以向我解释一下 我有一个表 状态 它有两列 id 和 name id是PK 我不想使用 POJO Status 而是使用枚举 我创建了这样一个枚举 如下所

随机推荐

  • 根节点左边POJ 1456 Supermarket根节点左边

    今天一直在学习根节点左边之类的问题 现在正好有机会和大家共享一下 心贪的目题 用并查集优化 取d左边近来的一点为根节点 include
  • 挂钩(HOOK)

    5 5 挂钩 HOOK 5 5 1 为什么引入挂钩 在Apache1 3版本中 对HTTP 请求的处理包括若干个固定阶段 比如地址转换阶段 身份确认阶段 身份认证阶段 权限确认阶段 MIME类型识别阶段等等 这也意味着Apache1 3 中
  • Qt Creator静态成员变量、全局变量、静态成员函数。

    静态成员变量 是一个全局区域的变量 不同 cpp文件间可以相互访问 记得包含 cpp对应的头文件 1 在mainwindow h中定义 public MainWindow QWidget parent nullptr MainWindow
  • 解决docker nginx无法查看日志的问题

    我们知道 Nginx的日志默认存放在 var log nginx access log var log nginx error log 但在使用nginx镜像构建的容器时 出现无法查看日志的问题 用cat命令后无反应 通过如下命令可以看到
  • android面试题-ActivityRecord TaskRecord和ProcessRecord之间的关系

    转自 http blog csdn net mwq384807683 article details 72529285 源码分析相关面试题 Volley源码分析 注解框架实现原理 okhttp3 0源码分析 onSaveInstanceSt
  • 数据分析之训练数据集处理

    在训练dbnet的时候 需要进行数据分析的一些方法来分割数据集 这里刚好整理一下 coding utf 8 用于解决编码问题 x strip strip 方法删除前导空格和尾随空格 with open as 方法 with open 1 t
  • 外向交货单发货过账BAPI:BAPI_OUT…

    前面说过 可以使用 WS DELIVERY UPDATE 进行外向交货单的发货过账 当然 这个可实现的很多 过账 冲销 删除都可以 但是这个不是bapi 是个函数 则会缺少bapi自带的那些校验 为了更安全 其实建议是使用 BAPI OUT
  • 创建Gravatar头像

    Gravatar Globally Recognized Avatar的缩写 是一项用于提供在全球范围内使用的头像服务 只要你在Gravatar的服务器上上传了你自己的头像 你便可以在其他任何支持Gravatar的博客 论坛等地方使用它 它
  • shared-service.ts

    shared service ts import Observable from rxjs Observable import Injectable from angular core import Subject from rxjs Su
  • npm link

    正文 npm link的用法 假如我们想自己开发一个依赖包 以便在多个项目中使用 一种可行的方法 也是npm给我们提供的标准做法 那就是我们独立开发好这个 依赖包 然后将它直接发布到 npm镜像站 上去 等以后想在其他项目中使用的时候 直接
  • 为什么说测试岗位是巨坑?10年测试人告诉你千万别上当

    每次都有人问我软件测试的前景是什么样的 每年也会有人很多人纷纷涌入测试的岗位上 希望自己能够进入阿里 华为等大厂 但是测试岗位真的那么吃香吗 今天我结合从零基础小白到测试开发的成长经历 来说下这个行业的发展前景 以及要入行的同学应该从哪个地
  • MinIO安装配置访问以及SpringBoot整合MinIO

    MinIO 1 MinIO安装 Minio 是个基于 Golang 编写的开源对象存储服务 存储非结构化数据 如 图片 视频 音乐等 官网地址 https min io 中文地址 http minio org cn 官网文档 中文 地址 h
  • C高级 day4

    1 有m1 txt m2 txt m3 txt m4 txt 分别创建出对应的目录 m1 m2 m3 m4 并把文件移动到对应的目录下 1 sh bin bash touch m1 txt m2 txt m3 txt m4 txt for
  • 【Ant Design】<a-date-picker>只选择今天之前的日期

  • LeetCode-N数之和类问题总结(双指针法)

    两数之和 给定一个整数数组 nums 和一个目标值 target 请你在该数组中找出和为目标值的那两个整数 并返回他们的数组下标 你可以假设每种输入只会对应一个答案 但是 你不能重复利用这个数组中同样的元素 示例 给定 nums 2 7 1
  • jsp中编码问题(自认为这个最好)

    在JSP Servlet中主要有以下几个地方可以设置编码 pageEncoding UTF 8 contentType text html charset UTF 8 request setCharacterEncoding UTF 8 和
  • python pdf转word

    转自 https yq aliyun com articles 487610 spm a2c4e 11153940 blogcont493499 12 655a7962KsKW7M 1 安装pdfminer3k模块 安装anaconda后
  • java listnode 合并链表_剑指offer:合并两个排序的链表(Java)

    1 问题描述 输入两个单调递增的链表 输出两个链表合成后的链表 当然我们需要合成后的链表满足单调不减规则 2 思路 方法1 非递归方法 根据题目这个很类似排序中的外排过程 两个数组分别排好序 然后再把他们整体进行排序 所以这道题思想很简单
  • Nvidia Jetson 编解码开发(6)Jetpack 4.x版本Multimedia API 硬件编码开发--输入端对接Camera V4L2采集

    1 前言 Nvidia Jetson 编解码开发 2 Jetpack 4 x版本Multimedia API 硬件编码开发 集成encode模块 free xx的博客 CSDN博客 基于上篇继续开发 由于上篇只集成了encode模块 但是编
  • Redis作为消息队列的优劣

    Redis缓存问题 Redis作为消息队列的优劣 Redis集群模式下保证可迁移和高可用 一致性算法 Redis热Key问题解决方案汇总 Redis基于内存 高性能并且提供多种数据结构供使用 那么对于Redis能不能作为消息队列 以及与专业