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


 

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值