用Redis玩转队列,效率提升其实没那么难,聊聊那些细节和坑
- 问答
- 2026-01-25 22:32:51
- 7
用Redis玩转队列,效率提升其实没那么难,聊聊那些细节和坑
很多人一听到“消息队列”就觉得是Kafka、RabbitMQ那些大家伙,觉得搭建维护麻烦,其实对于很多日常场景,比如发个通知、扣个库存、导个数据,用Redis就能搞定,轻巧又方便,但用起来不讲究,坑也不少,下面就直接聊聊怎么用,以及要注意什么。
基本玩法:就靠两个命令
Redis做队列,最核心的就是列表(List)这个数据结构,主要用两个命令:LPUSH(或RPUSH)和BRPOP(或BLPOP)。
- 生产者往队列里放任务:用
LPUSH myqueue task_data,从左边塞进去。 - 消费者从队列取任务:用
BRPOP myqueue 0,从右边阻塞地取,0代表一直等。 这结构就是个简单的先进先出(FIFO)队列,足够应付很多异步处理的需求了,根据实际项目经验,这种模式在触发邮件发送、清理临时文件等场景非常有效。
那些容易忽略的细节
-
消费者挂了怎么办? 这是第一个大问题。
BRPOP取走任务,任务就从Redis里消失了,如果消费者拿到任务还没处理完就崩溃了,这个任务就丢了,不能光靠BRPOP。- 可靠队列(ACK机制):常见的办法是弄两个队列,一个叫“待处理队列”,一个叫“处理中队列”,消费者用
BRPOPLPUSH命令,原子操作,从主队列取出任务,同时塞到“处理中队列”,等业务代码真正执行成功了,再从“处理中队列”里把这个任务删掉,如果消费者挂了,重启后它可以先去检查“处理中队列”,把里面卡住的任务重新捞出来处理,根据网络技术社区的常见讨论,这是用Redis实现可靠消费的基础模式。 - 处理失败了怎么办? 任务可能因为数据问题永远失败,不能让它一直堵在“处理中队列”,要有个监控,对卡住太久的任务进行告警,或者转移到“死信队列”让人工处理。
- 可靠队列(ACK机制):常见的办法是弄两个队列,一个叫“待处理队列”,一个叫“处理中队列”,消费者用
-
一条消息只能给一个消费者吗? 上面说的列表是“点对点”模式,一个任务只能被一个消费者消费,如果你想搞“发布/订阅”,一个消息让多个消费者都收到,那得用Redis的 Pub/Sub 功能,但Pub/Sub消息是“即发即弃”的,消费者离线期间的消息全丢,不适合要求可靠的消息场景,根据Redis官方文档的说明,Pub/Sub更适用于实时通知场景,而非持久化任务队列。
-
队列空了,消费者就一直傻等吗?
BRPOP的参数是阻塞超时时间,设个合理值,比如30秒,不是一直阻塞,这样可以让消费者有机会做点别的,或者安全地退出,生产者在发完任务后,可以往一个特殊的“信号通道”发个消息,消费者同时订阅这个通道,收到信号再去主动拉取,能减少一些无效的阻塞等待。
实际踩过的坑
- 连接超时和心跳:消费者用
BRPOP长时间阻塞,可能会因为连接空闲太久,被中间的网络设备(如防火墙)或云服务商的负载均衡器给掐断,你发现消费者好像睡着了,其实是TCP连接断了,解决办法是给Redis连接设置合理的TCP Keepalive参数,或者不用那么长的阻塞时间,改用短超时并循环调用。 - 内存暴涨:这是最危险的坑,如果生产者速度远大于消费者,或者消费者挂了,消息就会在Redis里大量堆积,Redis数据全在内存,分分钟可能撑爆。必须监控队列长度,设定一个阈值(比如1万条),超过就报警,并考虑限流或增加消费者,根据运维经验,无监控的Redis队列是线上服务的潜在炸弹。
- 消息体别太大:Redis是内存数据库,队列里塞的应该是任务ID或简短的指令,而不是把一大段HTML内容或者整张图片的Base64编码往里扔,大对象不仅耗内存,还会增加网络传输和序列化/反序列化的开销,严重影响性能,大内容应该存到对象存储或数据库,队列里只存个地址。
- 重复消费:网络抖动或者消费者处理超时,都可能导致任务已经处理了,但ACK没成功,之后任务又被重新处理,所以业务逻辑要尽量设计成幂等的,就是同一个任务被处理多次,结果和一次是一样的,比如扣减库存用“设置”而不是“递减”,或者先查状态再处理。
- 不是万能的:Redis队列没有像专业MQ那样的严格顺序保证(在集群模式下,不同key可能散列到不同节点)、高级的路由规则、海量堆积能力,它胜在简单、快、延迟低,如果业务量巨大,或者有非常严格的顺序和可靠性要求,该上专业MQ还是得上。
总结一下:用Redis玩队列,对于中小规模、延迟敏感的场景是利器,核心是理解列表操作,并围绕“可靠性”自己处理好ACK和重试,时刻盯住内存和连接,消息体要小,业务逻辑最好能幂等,搞清楚这些细节和坑,用它来提升效率,就真的没那么难了。

本文由盘雅霜于2026-01-25发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://fdoe.haoid.cn/wenda/85937.html