815 字
4 分钟
Redis09-消息队列
2023-07-08
2023-11-25
无标签

Redis消息队列#

基于List的消息队列#

消息队列(Message Queue),字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色:

  • 消息队列:存储和管理消息,也被称为消息代理(Message Broker)
  • 生产者:发送消息到消息队列
  • 消费者:从消息队列获取消息并处理消息

Redis提供了三种不同的方式来实现消息队列:

  • list结构:基于List结构模拟消息队列
  • PubSub:基本的点对点消息模型
  • stream: 比较完善的消息队列模型

基于List结构模拟消息队列
消息队列(Message Queue),字面意思就是存放消息的队列。而Redis的list数据结构是一个双向链表,很容易模拟出队列效果。
队列是入口和出口不在一边,因此我们可以利用结合RPOP、或者RPUSH结合LPOP来实现。
不过要注意的是,当队列中没有消息时RPOP或LPOP操作会返回null,并不像JVM的阻塞队列那样会阻塞并等待消息。因此这里应该使用BRPOP或者BLPOP来实现阻塞效果。

基于List的消息队列有哪些优缺点?

优点:

  • 利用Redis存储,不受限于JVM内存上限
  • 基于Redis的持久化机制,数据安全性有保证
  • 可以满足消息有序性

缺点:

  • 无法避免消息丢失·只支持单消费者

基于PubSub的消息队列#

Redis PubSub 向在线订阅者分发同一消息

发布者把消息发送到频道,当前在线且订阅该频道的多个订阅者各自接收一份,这与把任务分摊给单个消费者不同。频道不保存供离线订阅者补读的历史,也没有消费组的确认与待处理记录;断开连接期间错过的消息,不能仅靠重新订阅自动恢复。

基于PubSub的消息队列有哪些优缺点?

优点:

  • 采用发布订阅模型,支持多生产、多消费

缺点:

  • 不支持数据持久化
  • 无法避免消息丢失
  • 消息堆积有上限,超出时数据丢失

基于Stream的消息队列#

Redis Stream 的消费组分摊、pending 与确认流程

Stream 保存带标识的消息记录,不同消费组维护各自进度,同组消费者可以分摊新消息。组内消息交付后进入待确认记录,业务处理成功再确认;确认移除的是待确认状态,不是流中的消息正文。失败消息需要显式恢复或认领,重复交付仍可能发生,因此处理逻辑必须考虑幂等。

消费组并不会替应用判断业务是否真正完成。消费者应在处理成功后确认,处理中断时由恢复逻辑检查待确认记录并安排重试或认领。消息保留、裁剪与 Redis 持久化配置还会影响可恢复范围;确认机制不自动提供端到端恰好一次处理,并发消费者的完成顺序也不必等于消息写入顺序。