Redis实现消息队列

  1.                                      **List**
    

首先List是十分适合做消息队列的数据结构
存在问题:队列为空时,while死循环消费者频繁的拉取消息造成大量CPU资源的浪费,
改进:当队列为空的时候,消费者可以休眠一会,这样避免了资源的大量浪费
在这里插入图片描述

问题又来了,当消费者休眠时,消息来了,引发延迟,又改怎么办?鱼和熊掌不可兼得,总是存在问题
Redis存在这样一种阻塞式BRPOP机制,
使用这种机制的时候,没消息的时候阻塞等待,有消息的时候再去获取

在这里插入图片描述
但是仍然存在问题:1.不支持对消息的重复消费,一旦一条消息从List删除后,无法被其他消费者再次消费
怎么才能够有多个消费者?
2.消息的丢失:消费者拉取到消息后一旦发生异常,就会宕机,消息丢失
那么Redis怎么解决的?
发布订阅模型:Redis提供了publish和subscribe命令来完成发布订阅
2个消费者共同订阅了同一个队列
在这里插入图片描述
发布订阅模型最大的优点就是支持多组生产者和消费者
但是消费者必须先订阅队列,防止消息的丢失
但是仍然存在一个问题就是:数据的丢失,发布订阅模型没有提供任何数据持久化的能力,一旦发生宕机,里边的消息全部丢失
同时当消息积压的时候。-------当发布者发布消息的时候,Redis先把消息写到对应消费者的缓冲区中之后消费者不断地从缓冲区中拿消息消费
但是缓冲区的大小是有限的,一旦超过了极限就会把这个消费者强制下线
这样消费者就会消费失败,同时也会丢失数据
而Pub/Sub模型和List最大不同处就在于一个是一直积压在内存中,消费者来拉取
而前者是推消息到缓冲区
Pub/Sub的优缺点:
1.支持发布订阅的模式,支持多组生产者和消费者。
2.消费者一旦下线消息就会丢失
3.不支持数据持久化,Redis宕机后数据也会丢失
4.消息一旦堆积,消费者被下线,消息也会丢失

那么该怎么办呢?曙光出现了
趋于成熟的队列:Stream
1.Stream支持阻塞式的拉取消息
2.支持了发布订阅的模式
在这里插入图片描述
3.消息处理异常的时候,能否保证消息的不丢失
拉取消息的时候要用到消息ID,这里为了保证重新的消费也用到了消息ID
当一组消费者处理完消息后,需要执行XACK命令告知Redis让其标记为处理完成的消息
这样一旦消费者异常宕机的时候,不会发送XACK,Redis就知道出了问题就会保留这条消息
然后等消费者重新上线案后把之前没处理的数据再次发送给消费者,这样就不会丢失数据了。
Stram数据类型的每个写操作都支持RDB,AOF的持久化,这样即使宕机也能回复
消息堆积时,Stream会丢弃消息防止积压
思考:怎么样才不会丢失信息,提高可用性
1.生产者不会丢失信息----------失败重试的方式
2.消费者不会丢失信息-------消费者么此处理完后返回一个信息告知中间件处理完成
3.中间件不会丢失信息------Redis显然达不到要求
在宕机的时候,主从复制异步的时候,主从切换的时候(从库没来及发送消息就被提成了主库)
Redis本身就无法保证严格的数据完整性
那么专业的消息队列时怎么做的?
像RabbitMQ和Kafka,一般会部署一个集群,生产者在发布消息的时候队列中间件会写入多个节点,保证完整性,即使单个节点挂掉,也能保证集群的数据不丢失
在面对消息积压时,专业队列会把数据存储在磁盘,多占用一些磁盘空间而已。
所以因为Redis本身的特点,它永远不可能时专业的消息队列
但是如果可以忍受偶尔的数据丢失,接受Redis的缺点的时候,它依然轻量的一个很好选择

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值