Redis实现MQ

MQ的提出

上游发出请求后阻塞等待下游给到反馈,否则整个流程将一直阻塞。

提出mq之后:即有producer mq consumer 三者


MQ的特点

异步解耦

在有了 mq 后,producer 不需要过分关心 consumer 的身份信息,只需要把消息按照指定的协议投递到对应的 topic 即可

producer 在处理请求时,只需要把消息投递到 mq 即可认为流程处理结束,相比于同步请求下游,整个流程会更加轻便灵活,拥有更高的吞吐量
流量削峰

因为有 mq 作为缓冲层. 下游 consumer 可以设定好合适的消费限流参数,按照指定的速率进行消费,能够在很大程度上对 consumer 起到保护作用

Redis自身的缺点(无论是做缓存还是做mq都存在的)
价格昂贵 :redis本身是基于内存的,相比传统的mq组件是基于磁盘的。因此总容量可能有限。
存在数据丢失:即使有RDB/AOF的持久化策略,也难免存在数据丢失的问题,因为这个持久化是异步执行的,只要是异步,都不能说它是百分百的。

Redis自身的优点:

轻量,部署方便,运维成本低。


基于List实现的消息队列

首先,在使用 list 充当消息队列时,list 对应的 key 则对应为消息的 topic 名称.

producer 在投递消息时,可以使用 lpush 指令

consumer 消费消息时,使用 rpop 指令

但是存在一定的缺陷:

首先,consumer 在消费时,一定是一个类似于 loop thread 的自旋模型,每一轮循环中,通过 rpop 指令尝试从 list 中读取消息,如果成功读取到了消息,则进行相应的逻辑处理.

然而在此处,redis 的 rpop 指令是非阻塞型 的,即在 list 没有数据时,也会即时返回一个结果为 nil 的响应,这样在自旋模型下,对CPU是一笔不小的损耗。

倘若我们在 rpop 捕捉到 nil 时,立即开启下一轮循环,则这个轮询行为可能是没有意义的,因为 list 中可能仍然不存在数据. 这样的高频率自旋,对于 cpu 资源是一种无谓的损耗

倘若我们选择让 consumer 休眠一段时间进行循环,这个休眠的时长又具有一定的人为误判性. 倘若我们把时长设得太短,仍然会存在 cpu 浪费的问题;倘若设得太长,则可能会导致消息处理不及时的问题

在这个过程中,最理想的实现方案是,在 list 中有数据到达时,我们令 consumer 即时获取到对应的结果;倘若 list 数据为空,则令 consumer 陷入阻塞等待的状态,直到有数据抵达时程序才被唤醒.

推出阻塞等待机制:

BRPop key 【阻塞等待的超时时长】

达到此阈值仍未获取数据时会返回 nil. 如果设置为 0 ,则代表没有这个超时限制.


基于Pub/Sub

相关推荐
程序猿小D1 小时前
第24节 Node.js 连接 MongoDB
数据库·mongodb·npm·node.js·编辑器·vim·express
果子⌂2 小时前
PostgreSQL --数据库操作
linux·数据库·postgresql
SeaTunnel2 小时前
如何将SeaTunnel MySQL-CDC与Databend 高效整合?格式与方案全解析
数据库·mysql·开源·数据集成·seatunnel·databend
在肯德基吃麻辣烫2 小时前
《Redis》持久化
数据库·redis·缓存
xiaolyuh1233 小时前
基于binlog恢复误删除MySQL数据
数据库·mysql
Gauss松鼠会3 小时前
GaussDB分布式数据库调优方法总结:从架构到实践的全链路优化指南
数据库·分布式·sql·database·gaussdb
码海漫游者83 小时前
让Python成为你的网站引擎:Django全栈开发初体验!!!
数据库·python·其他·django
Databend3 小时前
玩转 Databend UDF
数据库
曼汐 .3 小时前
数据库管理与高可用-PostgreSQL日常维护
数据库
小陈又菜3 小时前
SQL ConcurrencyControl(并发控制)
数据库·sql··并发控制