Redis Stream 实现 MQ 的可行性

202 天前
 xiaohupro

早在 4 年前,当我发现 Redis5 中增加了 Stream 类型后我就觉得它的这些特性完全可以实现一个完整的 MQ 中间件功能,当时我还在交控工作,当时的项目刚好涉及到大量数据入库的一个需求,当时这个项目不算很大,所以我就想把这个新的技术引入到项目中,实现一个轻量级的基于 Redis 的消息队列。

最终基本上实现了这个功能,当时也做了一个基于 SpringBoot 的 Demo ,后来又改了一版基于 Jedis 版本的,因为可以自己定义和操作多线程,更加灵活自由的实现一些细节。

最近提离职后正在交接期,自己的时间比较多,又翻出这个早起的 Demo ,想改造一下,用到我的心情记录员项目中,如果精力和时间有的话我更想将它完善为一个完整的、可复用的项目。

心情记录员小程序为什么要用到这个?以及为什么不用其他成熟的 RabbitMQ ,首先不用其他成熟的原因是我不想搞太多中间件,一个项目中 Redis 安装是大多数情况,因此我想在保持单体应用的基础上实现一个 MQ ,另外的一个原因就是折腾,这也是我本人的一个“缺点”,什么都喜欢自己折腾一下,验证可行性。接下来说说应用场景吧,心情记录员这款小程序目前调用的 AI 是 Kimi 的平台,目前因为是前期,因此是免费版本,并发数限制到了 1 ,这就会导致一个问题,如果同时有两个或者多个(意淫一下,哈哈哈)同时点了记录的时候,这时候有一个肯定会报错,这时候就可以用到消息队列了,将请求的数据先放入队列,等前一个 AI 生成结束后再次调用,就这?……,一个队列不就搞定了吗?当然还有场景了,那就是目前 AI 生成我采用的是 Stream 流式返回,而我是在点击记录后就开始生成,点击记录后会跳转到结果页面,为了使用户跳过去立马就感觉到在生成,因此我就将调用 AI 接口的动作提前到跳转页面前点击记录按钮后,然后给一定到 Loading 延迟在跳转,跳转到结果页后建立 WebSocket 连接,根据 openId 标识接收消息,这时候这个消息其实已经在上一步中在生成了,这里就可以用到消息队列了,根据对应的 openId 到消息队列中取内容,服务端的 WebSocket 只需要根据标识从消息队列中缓存的生成结果进行返回即可,提升了响应速度。

大概流程就像下图这样:

4 年前这个项目的库和博客:

Gitee-redismq (原谅我以前使用 Gitee 的行为,哈哈哈)

CSDN 博客(如果对 CSDN 排斥可以访问下面我自己网站的文章)

个人网站文章地址

5773 次点击
所在节点    Redis
61 条回复
coderge
202 天前
黑马的 Redis 教程里有个小项目 《黑马点评》也用了 Stream 实现 MQ
suifengba
202 天前
我们之前随便 lpush,rpop 都没事
v2e0xAdmin2
202 天前
我用 mq 实现的
v2e0xAdmin2
202 天前
说错了,我用 mysql 实现的 mq
zeusho871
201 天前
交控我看到第一反应是不是干信号的,没想到真是。。。。用过卡斯柯/网新的东西 交控接触的少
xiaohupro
201 天前
@zeusho871 是的轨道交通信号,CBTC 系统,不过我当时所在组主要是给工程数据人员开发数据平台和公司内部的一些系统,真正干信号的同时都是 C 或者 C++
zeusho871
201 天前
@xiaohupro 信号系统底层这块接触的不多,我是使用者😂 卡斯柯这边用的 qt 写的 hmi ,前期 bug 也挺多。 感觉信号系统处理的数据量应该很大吧,各种车载 cc 那边的数据加上轨旁数据,回访日志啥的😂😂😂
xuanbg
201 天前
@likeme 对的,定时任务扫一把数据库最简单了。唯一的条件就是:只要扫得过来就行。
macaodoll
201 天前
简单需求 Redis list 业务需求还是得上 mq
wm5d8b
201 天前
消息队列有 n 种选择,甚至 redis4 也能做。对于缓存,redis 算不算垄断性的存在?有没有竞品或替代品
iamtuzi3333
201 天前
@suifengba 我也用的这个,但是有一个 bug ,就是入队的时候速度很快,然后我 websocket 每秒轮询读取整个 list 数据,会出现偶尔跳过或者重复数据。
suifengba
201 天前
@iamtuzi3333 这个是因为你并发了吧
iamtuzi3333
201 天前
@suifengba 没并发吧,list 每秒队伍插入一条数据,然后每秒会自动取出 list 的所有数据,时不时就会出现跳过一条数据或者重复一条数据
c332030
201 天前
丢数据自己修就好了
noreplay
200 天前
我觉得可以,我都是这样做
mark2025
200 天前
@xiaohupro 数据量大用主流 mq , 如果一致性、事务性重要可以考虑 pgmq (数据库实现的轻量级队列,用数据库来保证事务性、一致性、持久性)
roundgis
38 天前
一直用 redis list 当队列和 rpc 用

Redis 只用内存模式 不开 aof
RedisMasterNode
4 天前
@mark2025 redis 没有持久性吗..?
mark2025
1 天前
@RedisMasterNode redis ,kafka 这些为了实现持久化/一致性让系统变得复杂,还不如直接用天生就支持一致性、持久化 ACID 的数据库来干这事嘛
RedisMasterNode
1 天前
@mark2025 强可靠性并不是楼主的需求,小项目可能过一辈子都不会成长为大的、成功的项目。简洁的方案并不一定就不好,redis 的持久化也并不需要让什么东西变复杂,开启持久化只需要修改 1 个配置,nothing else 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1114525

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX