Redis队列

1.List

使用Lpush和Rpop命令来放入和读取消息。

缺点:当List中无数据时候,由于代码中会不断循环读取数据,Rpop命令不会停止,会一直运行,浪费cpu。

改进:

1、设置休眠时间,没隔一段休眠时间再读取。

2、使用BRPOP阻塞式,当有消息来的时候才会读取。

但仍有缺陷:1、不支持多个消费者消费同一条消息,2、消息丢失。当有消费者使用pop命令之后,这条消息就从链表中删除了,其他消费者也无法消费。

2、Pub/Sub模式

使用 SUBSCRIBE queue命令订阅queue这个消息队列,在多个redis客户端使用就能使得多个消费者订阅queue这个消息队列,而且是阻塞式读取。

然后使用PUBLISH queue msg1命令,让生产者在queue队列中生产msg1这条消息,于是订阅了queue这个队列的消费者就能读取到了。

而且还能够实现匹配订阅比如: PSUBSCRIBE queue.*,使用*匹配格式相同的消息队列,

当发布消息PUBLISH queue.p1 msg1,PUBLISH queue.p2 msg2,时候,消费者会收到来自queue.p1和queue.p2这两个消息队列的消息。

优点:多生产者,多消费者

缺点:数据丢失(Pub/Sub没有提供存储消息的机制,只是一个通道)

三种情况会导致数据丢失:1.消费者下线,重新启动后,只能接收最新的消息。

2.Redis宕机,消息会丢失。(不支持持久化)

3.消息积压。消费者有个缓冲区,redis先将消息放置这个缓冲区,然后消费者从缓冲区读取消息。当缓冲区内存不够了,消费者会被强制下线。

3、stream消息队列

通过命令XADD queue * name zhangsan 发布消息,*表示让redis生成一个id【时间戳-自增序列号】

通过XREAD COUNT 5 STREAMS queue 0-0读取消息,

1.可以阻塞式读取,XREAD COUNT 5 BLOCK 0 STREAMS queue 1618469127777-0,会阻塞读取这个id后的消息。

2.支持发布/订阅模式

生产者发布两条消息:

XADD queue * name zhangsan

XADD queue * name lisi

创建两个消费者组来消费,每个消费者组下都有一个消费者,>表示读取最新消息

XREADGROUP GROUP group1 consumer COUNT 5 STREAMS queue >

XREADGROUP GROUP group2 consumer COUNT 5 STREAMS queue >

3.stream能保证消息不丢失

当消费者消费完消息后,消费者会使用这个命令

XACK queue group1 1618472043089-0

表示该条消息已经被消费类,如果消费者宕机,则不会发出这条命令,redis就会将这个消息保存下来。当消费者重新启动后,redis便会将消费者没处理的消息重新发送给消费者。

4.Stream数据会通过RDB和AOF进行数据持久化

5.消息堆积时候,Stream也有应对策略:1.生产者限流。2.丢弃消息,丢弃旧的消息,保留固定长度的新消息。但消息堆积有容量限制。(也会有丢失消息的风险)

总的来说redis消息队列与专业的消息队列(Kafka、RabbitMQ)相比仍有差距;

1.Redis本身可能会丢弃数据(无论是RDB还是AOF策略,都有一定的时间间隔,有可能丢失数据)

2.有消息堆积的风险。(Kafka、RabbitMQ会将数据保存到硬盘上)。

你可能感兴趣的:(redis,数据库,缓存)