使用 redis 实现消息队列

    • [方案1: 使用list做消息队列](#方案1: 使用list做消息队列)
        • [问题1: 如何保证消息不丢失](#问题1: 如何保证消息不丢失)
        • [问题 2: 重复消费/幂等](#问题 2: 重复消费/幂等)
    • [方案 2: zset实现消息队列](#方案 2: zset实现消息队列)
    • [方案 3: 发布/订阅(pub/sub)](#方案 3: 发布/订阅(pub/sub))
        • [问题1: 如何保证消息不丢失](#问题1: 如何保证消息不丢失)
        • [问题 2: 重复消费/幂等](#问题 2: 重复消费/幂等)
    • [方案 4: Stream 实现消息队列](#方案 4: Stream 实现消息队列)
        • [问题1: 如何保证消息不丢失](#问题1: 如何保证消息不丢失)
        • [问题 2: 重复消费/幂等](#问题 2: 重复消费/幂等)

方案1: 使用list做消息队列

  • 生产消息: LPUSH
  • 消费消息: RPOP
问题1: 如何保证消息不丢失
  1. 生产者不丢失: 失败重试
  2. 消费者不丢失: POP同时储存到另一个(zset: score 为当前时间的时间戳)做临时备份,ACK 后删除临时备份的数据;定时将超时没有 ACK 的消息重新投入消息队列(做一个定时任务)
  3. redis 不丢失: 使用 kafka 类似的逻辑,集群所有从节(冗余节点)点写成功才算成功.
问题 2: 重复消费/幂等
  • 唯一 Id 做去重(消费者)

方案 2: zset实现消息队列

  • zset 与 list 的核心区别

    • 消费后消息不会自动在 zset 中删除,需要手动删除
    • 排序方式: list 是根据加入消息的先后顺序排的;而 zset 根据 score 进行排序的
  • zset 适合做延时消息队列(比如到一段时间消费的任务)

方案 3: 发布/订阅(pub/sub)

  • 生产: PUBLISH 命令
  • 消费(订阅): SUBSCRIBE 命令
问题1: 如何保证消息不丢失
  1. 生产者不丢失: 发送失败重试
  2. 消费者不丢失: 消费者没有接收到消息(网络问题/之前没有消费的消息)就会丢失,无法找回!
  3. redis 不丢失: 使用 kafka 类似的逻辑,集群所有从节(冗余节点)点写成功才算成功.
问题 2: 重复消费/幂等
  • 唯一 Id 做去重(消费者)

  • 发布/订阅的方式可以有多个消费者,多次消费; 但是有消息丢失的风险

方案 4: Stream 实现消息队列

  • 生产: XADD
  • 普通消费: XREAD
  • 消费者组消费:XREADGROUP GROUP

具体参考:https://www.runoob.com/redis/redis-stream.html

问题1: 如何保证消息不丢失
  1. 生产者不丢失: 失败重试
  2. 消费者不丢失: 有 ack 机制;在消费逻辑执行完成后再 ack,保证 "最少一次" 消费
问题 2: 重复消费/幂等
  • 生产的时候使用唯一 Id 作为消息的 key
  • 消费者使用唯一 Id 做去重
相关推荐
异世界贤狼转生码农1 小时前
MongoDB Windows 系统实战手册:从配置到数据处理入门
数据库·mongodb
QuZhengRong2 小时前
【数据库】Navicat 导入 Excel 数据乱码问题的解决方法
android·数据库·excel
码农阿豪2 小时前
Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南
数据库·windows
时序数据说7 小时前
时序数据库市场前景分析
大数据·数据库·物联网·开源·时序数据库
听雪楼主.11 小时前
Oracle Undo Tablespace 使用率暴涨案例分析
数据库·oracle·架构
我科绝伦(Huanhuan Zhou)11 小时前
KINGBASE集群日常维护管理命令总结
数据库·database
妖灵翎幺11 小时前
Java应届生求职八股(2)---Mysql篇
数据库·mysql
HMBBLOVEPDX11 小时前
MySQL的事务日志:
数据库·mysql
weixin_4196583113 小时前
MySQL数据库备份与恢复
数据库·mysql
如白驹过隙13 小时前
cloudflare缓存配置
前端·缓存