Redis作为一款高性能的键值存储系统,不仅可以作为缓存使用,还可以作为消息队列来实现异步操作和数据解耦。本指南将带你从零开始,轻松上手Redis消息队列,掌握List、Pub/Sub、Streams三种常用模式的应用。通过实际代码示例,快速实现订单处理、邮件发送等场景的异步化,提升系统性能和可维护性。
使用Redis List实现简单消息队列
Redis List是最简单的方式来实现消息队列。我们使用LPUSH将消息推入队列头部,RPOP从尾部取出消息。生产者代码:redis.lpush('order_queue', json.dumps({'order_id': 123}));消费者代码:while(true){ let msg = redis.rpop('order_queue'); if(msg) processOrder(JSON.parse(msg)); }为了避免阻塞,可以用BRPOP设置超时。
Pub/Sub模式实现发布订阅
Redis Pub/Sub适合一对多的广播场景。发布者:redis.publish('user_events', json.dumps({'user_id': 456, 'action': 'login'}));订阅者:redis.subscribe('user_events', (msg) => { console.log('收到事件:', msg); });它解耦了生产者和消费者,但订阅者离线时消息会丢失。
Redis Streams高级消息队列
Streams是Redis 5.0引入的专业消息队列,支持消费者组、消息确认、持久化。添加消息:redis.xadd('order_stream', '*', 'order_id', 789, 'amount', 100);读取:redis.xreadgroup('group1', 'consumer1', 'streams', [['order_stream', '0']]);确认:redis.xack('order_stream', 'group1', msgId);完美支持Exactly-Once语义。
异步订单处理实战案例
用户下单后,不同步调用支付和发货接口,使用Redis队列解耦:lpush('payment_queue', orderData);lpush('shipping_queue', orderData);独立消费者进程处理各自队列,避免主流程阻塞,用户体验丝滑。还可以添加死信队列处理失败消息:rpoplpush('main_queue', 'dead_queue')。
性能优化与注意事项
List队列单线程吞吐可达10w+/s,但长队列影响内存;Pub/Sub内存友好但无持久化;Streams支持ACK和Pending列表,适合金融场景。监控队列长度:llen('queue_name'),设置最大长度避免OOM。结合Lua脚本实现原子操作,提升并发安全。
与其他消息队列对比
对比RabbitMQ,Redis部署简单无依赖,延迟更低;对比Kafka,Redis内存占用小适合中小流量。适用场景:实时性要求高、数据量不大的业务。缺点是持久化不如专业MQ可靠,可结合AOF+RDB弥补。
FAQ
Q: Redis List和Streams哪个更好用?
A: List适合简单场景,Streams功能完整支持消费者组和确认,推荐生产环境用Streams。
Q: 消息丢失怎么处理?
A: 用Streams的ACK机制,或List结合持久化;重要消息可冗余多队列。
Q: 怎么监控队列积压?
A: 用INFO命令查看内存,LLEN查看长度,结合Prometheus+Grafana报警。
Q: 支持多少消费者?
A: 单实例支持多消费者,集群模式无限扩展,注意网络带宽。