用Redis搞消息队列,效率稳定还能挺靠谱,真没那么复杂
- 问答
- 2026-01-07 08:00:40
- 3
主要基于个人项目实践、Redis官方文档关于List/PubSub/Streams的章节,以及社区技术博客如“Redis Labs Blog”中的相关讨论)
用Redis搞消息队列,这事儿听起来可能有点技术宅,但说实话,用对了方法,它真的能成为一个效率又高、又稳定、还特别简单的消息传递工具,很多人一听说消息队列就想到Kafka、RabbitMQ这些大家伙,觉得它们功能全、企业级,靠谱,但很多时候,我们的项目根本没到那个量级,或者就是需要个轻快灵便的中间件来解耦一下服务、缓冲一下压力,这时候,Redis的优势就太明显了:你本来就在用Redis做缓存,现在让它顺便兼职个消息队列,不用引入新的技术栈,部署简单,学习成本几乎为零,而且速度飞快,因为数据都在内存里操作。
那具体怎么用Redis实现一个挺靠谱的消息队列呢?Redis自己就提供了好几种武器,咱们挨个看,你就知道该怎么选了。
最经典、最古老也是最简单的方式,就是用Redis的List数据结构,这玩意儿就是个双向链表,你可以把它当成一个队列来用,生产者用LPUSH命令,把消息从列表的左边塞进去,消费者用RPOP命令,从列表的右边把消息取出来处理,这不就是标准的先进先出队列嘛,简单直观,但这里有个小问题:如果列表里没消息,RPOP会返回空,消费者就得不停地轮询,问Redis“有消息了吗?有消息了吗?”,这太浪费资源了。
为了解决这个傻等的问题,Redis给了我们一个“聪明”的命令:BRPOP,这个B代表Block,阻塞,消费者可以执行BRPOP key timeout,意思是:我去这个队列等消息,如果有消息我立马拿走,如果没消息,我就在这儿等着,最多等timeout这么长时间,这样,消费者线程就挂起了,不占CPU,一旦有消息进来,它立马被唤醒干活,这种方式,对于单个生产者、单个消费者的简单场景,已经非常实用了,效率极高。
现实世界往往是多个消费者,List怎么应对呢?有两种模式,一种是“竞争消费”:比如你有三个消费者实例同时用BRPOP去等同一个队列,Redis会保证一条消息只会被其中一个消费者拿到,这很适合用来做负载均衡,把任务分给多个工人去并行处理,另一种是“广播”:如果你想一条消息让所有消费者都收到,List就做不到了,这时候就得请出Redis的第二个武器:Pub/Sub(发布/订阅)。
Pub/Sub就像个广播电台,生产者是发布者,它用PUBLISH命令向某个频道发送消息,消费者是订阅者,用SUBSCRIBE命令订阅自己关心的频道,一旦有消息发布到频道,所有订阅了这个频道的消费者都会同时收到一份完整的消息,这个模式非常适合做实时通知、事件广播,比如用户下单成功了,通知客服系统、日志系统、积分系统都来干点自己的事儿。
Pub/Sub有个关键特点:它不持久化,消息发出去了,如果当时没有订阅者,这条消息就永远消失了,如果消费者中途掉线了,重连之后也收不到掉线期间错过的消息,所以它适合那种“丢了就丢了”的实时场景,对于要求消息必达的任务队列,就不太合适。
有没有既能支持多消费者模式,又能保证消息不丢,功能更强大的方案呢?这就是Redis 5.0版本之后推出的“大杀器”——Streams数据结构,Streams可以说是Redis专门为消息队列场景设计的“亲儿子”,它吸收了很多专业消息队列的思想。
Streams本质上是一个只追加的日志,生产者用XADD命令往Stream里添加消息,每条消息都有一个唯一的、递增的ID,消费者呢,属于某个消费者组,Streams的精髓就在于这个消费者组的概念,你可以创建一个组,让组内的多个消费者来竞争消费Stream里的消息,Redis会负责把消息分发给组内空闲的消费者,并且确保一条消息只会被组内的一个消费者处理掉,这完美解决了负载均衡的问题。
更厉害的是,Streams是持久化的,消息会一直存在Redis里(除非你设置过期删除),每个消费者组都会跟踪自己处理到哪个消息ID了,当一个消费者从组里取走一条消息后,它需要显式地发送ACK(确认)命令,告诉Redis“这条我处理完了”,如果消费者挂了,没来得及ACK,过一段时间,这条消息就会被重新分配给组里的其他消费者去处理,这就实现了“至少一次”的可靠交付,消息基本不会丢。
你看,从最简单的List,到实时广播的Pub/Sub,再到功能完备的Streams,Redis提供了一套从简到繁的解决方案,你可以根据业务的轻重缓急来挑选:快速实现个异步任务?用List+BRPOP就够了,要做事件通知?Pub/Sub很合适,业务重要,要求消息不丢、能重试、有多消费者?那直接上Streams,它给你的可靠性远超你的想象,但使用起来依然比搭建和维护一个Kafka集群要简单太多了。
真别把消息队列想得太复杂,下次当你需要个轻量级的消息中间件时,先别急着去折腾那些大块头,想想你身边这个又快又熟的老朋友——Redis,它很可能已经准备好,用一种意想不到的简单方式,帮你把问题给解决了,只要理解了这几种模式的差别和适用场景,用Redis搞个效率稳定又靠谱的消息队列,真的没那么复杂。

本文由水靖荷于2026-01-07发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/76080.html
