能否把 Redis 当做消息队列来用呢?

2024-03-27 16:52

本文主要是介绍能否把 Redis 当做消息队列来用呢?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个问题并不是面试中经常会问到的问题,而是我在平时看一些大牛写的技术文章的时候看到的一个问题,这个问题引发了我强烈的思考,我感觉我想通了这个问题之后,对redis和kafka都有了一个全新的认识,感觉像发现了新大陆这种感觉。这其实是一个泛问题,如果一个人对redis和kafka都很了解,那回答这个问题绝对是侃侃而谈的。我这几天一直在思考这个问题,感觉已经将redis和kafka的这个脑图都给构建出来了。

在我看来,Redis 其实就是一个内存存储系统。我的理解就是 Redis 是一个可以用来存数据的系统,就这么简单。Redis 支持很多种数据结构,我的理解就是你的那些数据可以按照不同的结构存储在 Redis 中。比如 Redis 有 List 这种数据结构,那数据在 Redis 中就很有可能是排成一列这样子存放的。

所以这就引出了一个问题:既然 Redis 支持数据排成一列存放,那 Redis 可不可以用作消息队列呢?我听到最多的消息队列是 activemq、rabbitmq、rocketmq、kafka 这些,我基本没听说过 Redis 消息队列。

假如我们现在有一个最简单的 Redis 内存系统,那这个系统会有什么不足呢?首先 Redis 支持 List 这种数据结构,而 List 的底层实现是链表。按理来说,在头尾操作元素是很方便的事情,用作消息队列天然适配。但是,由于是链表,你在取消息的时候是直接把消息取出来的,取出来后,链表就会删除这个元素。万一现在有很多个消费者都想消费这条消息,本来这条消息是共享的,结果你直接自己消费了,其他消费者消费不了就很难受,而且万一你自己还消费不成功这条消息,想再从队列里取出来再消费一次,已经没机会了,你刚刚已经拿出来了,所以这样子是不行的。

所以后来才有了发布/订阅者模式,这种模式就可以完美的解决上述的问题。

其实,现在的 Redis 是有发布/订阅者模式的,但是其实还是有不足的地方,问题出在哪里?Redis 在关于数据不丢失问题做不到严格的保证。你想想,Redis 保证数据不丢失,也就是我们平时说的 Redis 数据持久化的时候,无非就是用 AOF日志 和 RDB内存快照,这两种方式都不能严格的保证数据不丢失,反而消息队列比如 kafka 这种,就使用 leader-follower 模式来严格的保证数据不丢失,而且 kafka 在生产者那里为了保证数据不丢失也做了处理,甚至在消费者那里,都考虑到关闭offset 这个参数,这种对数据不丢失的严谨性是 Redis 比不了的。

当然,这也很正常,毕竟 Redis其实都不是很在乎数据丢不丢,因为 Redis 用的最多的就是做缓存,丢一点数据其实对整体没有什么大的影响。不仅是保证不了消息不丢,在保证消息不被重复消费,保证消息被有序消费这些点上,Redis 都无能为力。

当然,我这里说的 Redis 是早期的 Redis,现在的 Redis 肯定不是这样子的。比如说在保证数据不丢这点,Redis 现在已经做的很好了,它采用了主从复制+哨兵选举的方式,感觉和 kafka 保证数据不丢的思路是有点相似的。此外,它还用了分片集群,通过分片集群,Redis 就可以轻松的进行横向扩展,处理更大规模的数据了。

上面就是我自己对于这个问题的理解。因为这是一个开放性的问题,所以不同的人都会有自己不同的理解。当然,假如你对 Redis 和 kafka 掌握的越好,那你回答这道题就越能侃侃而谈,甚至通过这道题把你懂得的所有 Redis 和 kafka 的细节都说出来。我觉得我应该多思考这种开放性的问题,研究这种问题感觉是有利于促进对知识点的理解的。这种问题也有利于检测对一个知识点的理解到底掌握到哪种程度。复习的时候,也可以用这个问题当做复习,就是问你这道题,你把你懂的关于 Redis 和 kafka 的所有知识点都讲出来。

这篇关于能否把 Redis 当做消息队列来用呢?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/852804

相关文章

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2431 poj 3253 优先队列的运用

poj 2431: 题意: 一条路起点为0, 终点为l。 卡车初始时在0点,并且有p升油,假设油箱无限大。 给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。 问最少加几次油可以到达终点,若不能到达,输出-1。 解析: 《挑战程序设计竞赛》: “在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

POJ2010 贪心优先队列

c头牛,需要选n头(奇数);学校总共有f的资金, 每头牛分数score和学费cost,问合法招生方案中,中间分数(即排名第(n+1)/2)最高的是多少。 n头牛按照先score后cost从小到大排序; 枚举中间score的牛,  预处理左边与右边的最小花费和。 预处理直接优先队列贪心 public class Main {public static voi

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因