使用 Redis List 和 Pub/Sub 实现简单的消息队列

使用 Redis List 和 Pub/Sub 实现简单的消息队列

Redis 本身不是专门的消息队列系统,但它提供了多种数据结构(如 List、Pub/Sub、Stream)来实现消息队列功能。根据不同的业务需求,可以选择不同的方式:

在 Redis 中,可以使用 ListPub/Sub 模块实现简单的消息队列。两者的适用场景和实现方式有所不同:

  • List(列表) :适用于任务队列(Task Queue),支持持久化存储,消费者可以消费历史消息,支持 多消费者竞争消费(类似于 Kafka)。
  • Pub/Sub(发布/订阅) :适用于实时推送(Event Notification),不存储消息,消费者只能接收发布时刻的消息,适合 多消费者广播消费(类似于 RabbitMQ Fanout)。

方式一:使用 Redis List 实现简单的消息队列

Redis 的 LPUSHBRPOP 操作可以用来构建一个 基于拉取的消息队列

1. 生产者(Producer)

生产者将消息推送到 Redis List 的尾部:

bash 复制代码
LPUSH my_queue "message1"
LPUSH my_queue "message2"

或在 Python 中:

python 复制代码
import redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.lpush('my_queue', 'message1')
r.lpush('my_queue', 'message2')
  • LPUSH my_queue "message":将新消息插入队列的 左侧(头部)
  • RPUSH my_queue "message" 也可以使用,它会将消息插入队列的 右侧(尾部)

2. 消费者(Consumer)

消费者使用 BRPOP(阻塞)或 RPOP(非阻塞)从队列的 右侧 弹出消息:

bash 复制代码
BRPOP my_queue 0

或在 Python 中:

python 复制代码
while True:
    msg = r.brpop('my_queue', timeout=0)  # 阻塞模式
    if msg:
        print("Received:", msg[1])  # msg[1] 是消息内容
  • BRPOP my_queue 0:如果队列为空,则 阻塞 等待新的消息。
  • RPOP my_queue:如果队列为空,直接返回 None,不会阻塞。

3. 多消费者

多个消费者可以竞争消费消息,即每条消息只会被 其中一个 消费者消费。例如,有两个消费者在 BRPOP 同一个队列,Redis 只会把某个消息分配给其中一个。

4. 消息确认与持久化

由于 Redis List 只存储消息,不支持自动重试,因此可以配合 LPUSH+RPOPLPUSH 事务 实现持久化:

  • 先用 RPOPLPUSH my_queue processing_queue 把消息从 my_queue 转移到 processing_queue,然后再处理。
  • 处理完成后,从 processing_queue 中删除该消息。
python 复制代码
msg = r.rpoplpush('my_queue', 'processing_queue')  # 转移到处理中队列
if msg:
    process_message(msg)  # 处理消息
    r.lrem('processing_queue', 1, msg)  # 处理完成后删除

方式二:使用 Redis Pub/Sub 实现消息队列

Pub/Sub 适用于实时消息推送,消息不会存储,适合事件广播。

1. 生产者(Publisher)

发布者向某个频道(channel)发送消息:

bash 复制代码
PUBLISH my_channel "message1"

或在 Python 中:

python 复制代码
r.publish('my_channel', 'message1')

2. 消费者(Subscriber)

订阅者监听消息:

bash 复制代码
SUBSCRIBE my_channel

或在 Python:

python 复制代码
pubsub = r.pubsub()
pubsub.subscribe('my_channel')

for message in pubsub.listen():
    if message['type'] == 'message':
        print("Received:", message['data'].decode())

3. Pub/Sub 适用场景

  • 实时消息推送(如 WebSocket、聊天室)。
  • 事件驱动系统(如日志收集、状态变更通知)。
  • 多消费者广播消费,所有订阅者都会收到相同的消息。

4. Pub/Sub 局限性

  • 消息 不会持久化,如果订阅者掉线,它不会收到丢失的消息。
  • 不能确保 消息按顺序消费
  • 无法回溯历史消息(相比 Kafka)。

总结:Redis List vs Pub/Sub

特性 Redis List Redis Pub/Sub
消息存储 存储在 List,直到被消费 不存储,实时传输
消费者模型 多消费者竞争消费(类似任务队列) 多消费者广播消费(类似事件通知)
可靠性 支持重试和确认机制 订阅者掉线会丢失消息
适用场景 任务队列(如延迟任务、任务分发) 实时推送(如聊天、事件通知)

如果需要 持久化队列 ,建议使用 Redis List ;如果只是 实时推送 ,可以用 Pub/Sub


相关推荐
vivo互联网技术7 分钟前
号码生成系统的创新实践:游戏周周乐幸运码设计
redis·后端·架构
都叫我大帅哥29 分钟前
Redis中zset内存变形记
java·redis
大只鹅41 分钟前
两级缓存 Caffeine + Redis 架构:原理、实现与实践
redis·缓存·架构
都叫我大帅哥43 分钟前
Redis的ZSet:从“青铜”到“王者”的排序神器
java·redis
小小霸王龙!1 小时前
互联网大厂Java面试实录:Spring Boot与微服务在电商场景中的应用
java·spring boot·redis·微服务·电商
混乱意志1 小时前
dgraph example数据导入
数据库·后端
Web极客码1 小时前
WordPress 站点漏洞利用:数据库恶意注入与多重感染的案例分析
数据库·wordpress·网站安全·数据库注入·wordpress漏洞·wordpress安全插件
刺客xs1 小时前
MySQL数据库----DML语句
数据库·mysql
都叫我大帅哥1 小时前
Redis BitMap 深度解剖:比特世界的精密引擎
redis
嘉讯科技HIS系统1 小时前
嘉讯科技:医疗信息化、数字化、智能化三者之间的关系和区别
大数据·数据库·人工智能·科技·智慧医疗