Redis Stream 实现 MQ 的可行性

201 天前
 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 排斥可以访问下面我自己网站的文章)

个人网站文章地址

5760 次点击
所在节点    Redis
61 条回复
starryin
201 天前
@bronyakaka #18 张嘴就来分布式大数据高可用?做 waf 防应用层攻击的时候给你额外落盘处理的时间?爆内存就加内存,redis stream 文档里的的 maxlen 参数看过吗? kafka 不均衡爆盘是不是只会找运维?一再说看需求看成本,你要是拿着八股文 chatgpt 干得更好
simenet
201 天前
我的评价是,专业的事交给专业的中间件去做
ymy3232
201 天前
我们用 redis stream 好几年了,每天五六十亿数据是有的,我们业务对数据不敏感,数据差异小范围都可以接受,实际用起来也没发现多大差异,从成本上来看对比 kafka 便宜太多
starryin
201 天前
@xiaohupro #20 打个比方说,小公司给客户交付的一台服务器连软件开发加硬件就五万块,你得算计硬盘多少钱,内存多大多少钱,是雇个光会打嘴炮懂个半吊子 MQ 的,还是 redis 和应用层能一把抓的,这种事情很要命,直接决定生死,但是大公司是另一回事,有专门的维护每个中间件的工程师(是不是真熟悉底层另一说),成本收不收回来那也是商业策略问题和员工没关系
guanhui07
201 天前
专业的事交给专业的中间件去做 可以使用 kafka rabbitmq
bronyakaka
201 天前
@starryin #21 你张嘴就拿 WAF 和实时性说事,Redis Stream 的吞吐和 maxlen 能撑小规模没错,但消息量一上来,内存爆炸是你加内存就能随便解决的? Kafka 不均衡、落盘慢是设计没做好,你拿运维当挡箭牌,原帖想做“完整项目”,扩展性是以后要考虑的事情,
更何况我提 Kafka 是给选项,你扣个八股文帽子以为自己懂需求懂成本?技术选型不是靠意气用事,Redis 做大数据场景就是自欺欺人,而且我也没让楼主这种小场景上 kafka ,这点数量级不用 redis 直接进程内异步处理都行,你非要瞎杠
bronyakaka
201 天前
@starryin #21 我都说的很清楚了看数据量级,几十亿几百亿消息你还用 redis 脑子怕是有点问题
bronyakaka
201 天前
@starryin #21 有脸说别人看八股文,我不知道你是读不懂我看数量级的意思还是觉得自己很牛逼,我生产维护的集群每天几十亿消息
bronyakaka
201 天前
@starryin #21 你一说 maxlen 说我都想笑,消息高峰就把你老消息删了,怎么敢的,也就你这种日志场景无所谓是吧,坑别人
TGhoull
201 天前
挺好的,我看国外好多用 redis 做消息队列的,甚至有看到数据库来做消息队列的😂,前提是吞吐量要求不是特别严苛的情况下,另外前两天看一篇技术博客分享 kafka 在低负载下表现很差,我觉得根据自己应用的场景来选择最合适的才是正解。
xiaohupro
201 天前
请大家友好讨论,没有绝对的对错,不要太有攻击性
ppllss
201 天前
的确项目刚开始启动完全没有必要引入大量的中间件,除非就是上线就是高并发
mark2025
201 天前
一致性,持久性?
DonaldY
201 天前
可以用的。IM 中离线消息就放 redis 队列里。
likeme
201 天前
之前尝试过使用 redis key 过期做延迟任务,比如订单创建 30 分钟后自动触发取消订单,后面开发新项目的时候,有类似的需求,直接使用定时任务一把梭。小项目尽量避免使用更多的组件。当然这是我对“小项目”的理解~
dxddd
201 天前
我很久之前用 Redis List 去实现消息队列用于发短信,当时是一个小项目,但是突然涌入大良用户导致调用短信服务商 HTTP 请求阻塞。所以说当不想引入 MQ 中间件,这么做问题不大。
starryin
201 天前
@xiaohupro #25 我挖了个坑,他没注意到,我就知道他什么水平了,已经 block 了
所有无脑劝你用大厂流行技术的回帖,都没有任何价值
有价值的贴子只有两种,一种是用了和你一样的技术,成功了,那他们是什么业务和压力场景,这里的业务当然包含数据价值,比如可不可以丢,延迟多少可以接受,另一种是用了和你一样的技术结果失败了,他们碰到了什么具体绕不过的问题
我在 V2 上并不喜欢发言,因为肉眼可见的菜鸟太多,没精力理会,恰好你这个场景我们以前做过而已,而一开始一水的大厂狗让你换中间件,显然会把人带歪,还好后边跟贴里有不少其他人的实际用例,就不多说了
billbob
201 天前
消息不多用 event,大点 redis,集群才上 mq
bxb100
201 天前
@adoal
8355
201 天前
自己封装了啊 我也现在就在用好用的不得了,延迟极低,对于可靠性要求不是特别高的业务很好用,redis 本身很便宜。

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

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

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

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

© 2021 V2EX