订阅与发布

普通的链表结构无法满足消息多播。redis 使用发布者/ 订阅者模式

PubSub

频道 channel

Publisherchannel 中发布消息时,关注了指定 channelConsumer 就能够同时受到消息。想要 订阅多个 频道,那么就必须 显式地关注多个

订阅

当客户端订阅某一个频道之后,Redis 就在 pubsub_channels 字典中的这个频道的链表后添加客户端。

只要检查某个频道是否为字典的键,就可以知道该频道是否正在被客户端订阅。

发布

通过字典获取订阅频道的客户端,然后发送。

缺点

  • 没有 Ack 机制,也不保证数据的连续
  • 不持久化消息

stream

https://tva1.sinaimg.cn/large/007S8ZIlly1gghh0j4d8tj30yg0g1gnk.jpgstream

**Consumer Group **消费者组

记录流状态的一种数据结构。消费者既可以选择使用 XREAD 命令进行 独立消费,也可以多个消费者同时加入一个消费者组进行 组内消费。同一个消费者组内的消费者共享所有的 Stream 信息,同一条消息只会有一个消费者消费到,这样就可以应用在分布式的应用场景中来保证消息的唯一性。

last_delivered_id

消费者组消费在 Stream 上 消费位置 的游标信息。每个消费者组都有一个 Stream 内 唯一的名称

pending_ids

每个消费者内部都有的一个状态变量,用来表示 已经 被客户端 获取,但是 还没有 ack 的消息。记录的目的是为了 保证客户端至少消费了消息一次,而不会在网络传输的中途丢失而没有对消息进行处理。如果客户端没有 ack,那么这个变量里面的消息 ID 就会越来越多,一旦某个消息被 ack,它就会对应开始减少。

避免消息丢失

Redis 服务器将消息回复给客户端的过程中,如果客户端突然断开了连接,消息就丢失了。但是 PEL 里已经保存了发出去的消息 ID,待客户端重新连上之后,可以再次收到 PEL 中的消息 ID 列表