Redis Stream 实现 MQ 的可行性

2025 年 2 月 27 日
 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 排斥可以访问下面我自己网站的文章)

个人网站文章地址

9699 次点击
所在节点    Redis
61 条回复
maocat
2025 年 2 月 27 日
我的评价是,专业的事交给专业的中间件去做
Yukineko
2025 年 2 月 27 日
可以用、不好用、没必要
imokkkk
2025 年 2 月 27 日
可以 但没必要
adoal
2025 年 2 月 27 日
如果为了部署架构简单,而选择用软件 A 做 功能 B 的事,那我可能会更倾向于 everything in PostgreSQL 😄
gesse
2025 年 2 月 27 日
交控,大量数据入库

是不是 mqtt+时序数据库好点?
xiaohupro
2025 年 2 月 27 日
@gesse 不是,你说的这个是信号系统里面的,当时其他项目组这个方面是用 C++开发的,我这个是工程数据 Excel 数据例如电子地图、各种其他表:VOBC 、联锁表等等,当时的这个数据平台设计的时候我才用了精确到单元格级别的存储,方便后面功能的扩展,所以数据量比较大,一个一个工程线路下来有一百万左右的数据入库
Rat3
2025 年 2 月 27 日
我现在就在用 RedisSteam 用来做简单的 MQ
spritecn
2025 年 2 月 27 日
个人觉得 list 的 right push + left pop 更靠谱
abccccabc
2025 年 2 月 27 日
@Meld 大哥,RedisSteam 用来做简单的 MQ 和 redis list 如何更好的区别应用场景呢??
starryin
2025 年 2 月 27 日
可以,我就这么用过,而且看场景可能是完全是有必要的,说白了一切看需求和成本,尤其是给多个 B 端客户在硬件有限但是流量不小的交付场景,说“没必要”,“everything”就是项目做的少
stephenxiaxy
2025 年 2 月 27 日
去年,我们也用 redis stream 做的 mq
starryin
2025 年 2 月 27 日
@abccccabc stream 有 maxlen 可以控制容量,如果你不希望消费比生产慢把内存爆掉的话
xiaohupro
2025 年 2 月 27 日
@stephenxiaxy 嗯嗯,这个 Demo 刚写完时就有一个老哥咨询,他最终是用到了他们网站短信发送功能了,用 Redis Stream 做的消息队列,性能还可以
bronyakaka
2025 年 2 月 27 日
如果消息量很少没事,量大上 kafka ,几十亿几百亿消息
xiaohupro
2025 年 2 月 27 日
@bronyakaka 嗯嗯,是的,这种只适合轻量应用,如果数据量那么大的话就不需要在乎多加额外中间件成文的问题了
starryin
2025 年 2 月 27 日
@xiaohupro #15 并不见得是这样,kafka 需要落盘和不平衡同样会带来让人头疼的问题,单技术维度思考会带来很严重的后果
starryin
2025 年 2 月 27 日
@xiaohupro #15 实际上我们当时 Redis 和 Kafka 两个都上了,Redis 的原因是吞吐,限流,Kafka 是为了落盘持久化,而且硬盘的总 IO 有限,都留给 Kafka 了
bronyakaka
2025 年 2 月 27 日
@starryin #17 那是没设计好,涉及分布式大数据不管啥组件都需要考虑这些问题。这种情况还用 redis 直接爆内存直接不可用
Ayanokouji
2025 年 2 月 27 日
可以,也可以用这个代替 redis 。https://nats.io
xiaohupro
2025 年 2 月 27 日
@starryin 确实,业务场景的复杂程度也决定了重要的一环

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

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

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

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

© 2021 V2EX