Redis消息队列那些常用指令,简单聊聊怎么用和注意点
- 问答
- 2026-01-10 03:10:53
- 3
说到Redis消息队列,最核心、最常用的就是List(列表)这种数据结构,你可以把它想象成一个两头都能进出的管道,基于这个管道,就产生了两种最简单的消息队列模式。
第一种,也是最简单的,叫LPUSH/RPOP模式。(来源:Redis官方文档对List命令的介绍)
- 怎么用:消息的生产者(比如一个后台任务)使用
LPUSH命令,把消息从管道的左边(头部)一个一个放进去,就像排队买票,后来的人站在队伍的左边末尾,消费者(比如处理任务的程序)则在管道的右边(尾部)用RPOP命令,把消息一个一个取出来处理,保证先来的消息先被处理(FIFO,先进先出)。 - 注意点:这里有个大问题!如果消费者使用
RPOP,它是一条“非阻塞”命令,意思是,当消费者去取消息时,如果管道是空的,它拿到一个nil(空值)后就立刻返回了,然后程序继续往下执行,那消费者怎么知道下一秒钟有没有新消息来呢?它只能傻傻地不停地用循环去问:“有消息吗?有消息吗?”,这种方式叫做“轮询”,非常浪费CPU资源,效率很低。
为了解决这个“傻等”的问题,就有了第二种更常用的模式,使用BRPOP命令。(来源:Redis官方文档对阻塞命令的介绍)
- 怎么用:这个模式生产者不变,还是用
LPUSH,但消费者变了,它使用BRPOP命令,这个“B”代表“Blocking”(阻塞),消费者执行BRPOP myqueue 0后,就会卡在那里静静地等待,这里的“0”代表超时时间,0就是无限等待,直到有消息进来,一旦生产者放入一条消息,消费者就会立刻被“唤醒”,拿到消息并进行处理,处理完后,它再次进入阻塞等待状态,这种方式非常高效,CPU不会被白白消耗。 - 注意点:
- 消息丢失风险:虽然
BRPOP解决了效率问题,但还有一个隐患,当消费者从队列里取出消息后,这条消息就在Redis里被删除了,如果消费者在处理消息的过程中突然崩溃了,还没来得及处理完,那这条消息就永远丢失了,这对于要求可靠性的业务(比如扣款、下单)是无法接受的。
- 消息丢失风险:虽然
为了解决消息丢失的问题,Redis提供了更高级的“可靠队列”模式,这就要用到Redis的另一个数据结构——Stream(流)。(来源:Redis官方关于Stream数据结构的文档)
- 怎么用:Stream就像是只能追加的日志文件,生产者用
XADD命令向一个Stream(流)中添加消息,每条消息都会有一个自动生成的唯一ID,消费者这边呢,它不再是简单地“取出并删除”消息,而是使用XREAD命令来“读取”消息,关键在于,每个消费者(或消费者组)都需要记录一个“最后处理的消息ID”(ACK),消费者读取一条消息后,开始处理,处理成功后,必须显式地发送一个XACK命令,告诉Redis:“这条消息我处理完了,你可以把它标记为已完成”,如果消费者崩溃了,当它重启后,可以根据自己记录的最后ID,去读取那些“已发送但未确认(ACK)”的消息,重新处理,这样就保证了消息至少被处理一次。 - 注意点:
- 复杂度更高:Stream的功能强大,但命令也比List复杂不少,需要理解消费者组(Consumer Group)、待处理条目(PEL)等概念。
- 资源消耗:因为消息不会被立刻删除(直到被明确确认或超过保留时间),Stream会比List消耗更多的内存,需要设置合理的消息留存策略。
- 重复消费:“至少一次”的语义可能导致同一条消息被处理多次(比如消费者ACK确认时网络失败),所以你的业务逻辑需要能够容忍重复处理,或者自己实现幂等性(即同一个操作执行多次,结果和执行一次一样)。
除了上述核心模式,还有一些常用的辅助指令和技巧:
- 发布/订阅(Pub/Sub):(来源:Redis官方文档对Pub/Sub的介绍)这严格来说不是队列,而是一种广播机制,生产者
PUBLISH一个消息到某个频道,所有订阅(SUBSCRIBE)了这个频道的消费者都会同时收到这条消息,它的问题是没有持久化,如果消费者当时不在线,就永远收不到这条消息了,通常用于在线聊天、实时状态广播等场景。 - 查看队列长度:用
LLEN key可以查看一个List队列里有多少条消息在等待处理,用于监控。 - 一次处理多条消息:使用
LPOP或RPOP时加上数量参数,LPOP myqueue 5,可以一次性取出多条消息,在某些场景下能减少网络交互,提升效率。
总结一下选择和注意点:
- 简单、可丢失的任务:比如更新内存缓存、发送一条不重要的统计日志,用
LPUSH+BRPOP就够了,简单粗暴。 - 重要、不可丢失的任务:比如订单处理、支付通知,必须使用 Stream 来保证可靠性。
- 广播类场景:比如通知所有在线用户系统要维护了,可以用 Pub/Sub,但要接受消息可能丢失。
- 通用注意点:
- 监控:一定要监控队列的长度,如果队列堆积越来越长,说明消费者处理不过来了,是系统瓶颈的预警信号。
- 序列化:存入Redis的消息通常是字符串,你需要把对象(比如一个JSON)序列化成字符串存进去,取出来再反序列化,要约定好格式,比如都用JSON。
- 键名设计:给队列起个清晰易懂的键名,
queue:order:pay(订单支付队列),方便管理。
Redis消息队列的魅力就在于它的轻量和灵活,用几个简单的命令就能搭建起不同特性的消息通路,但你需要根据业务的严肃性,在简单性和可靠性之间做出权衡。

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