Redis做消息队列

Redis可以作为消息队列使用,通过List和Streams数据类型实现。List满足消息保序,但需要BRPOP进行阻塞读取。Streams提供全局唯一ID,支持XREAD的阻塞读取和XGROUP消费组,实现消费者间的负载均衡以及消息处理可靠性。文章讨论了如何利用Redis解决消息处理中的速度匹配、重复处理和可靠性问题。
摘要由CSDN通过智能技术生成

redis可以做消息队列吗

这个问题隐含着两个问题:

消息队列的消息存取需求是什么

redis如何实现消息队列的消息存取需求

消息队列的消息存取需求

在分布式系统中,当两个组件要基于消息队列进行通信的时候,一个组件会被要处理的请求放入消息队列中,自己就可以执行其他操作了,远端的另一个组件从队列中把消息队列取出来,再在本地进行处理

假设组件 1 需要对采集到的数据进行求和计算,并写入数据库,但是,消息到达的速度很快,组件 1 没有办法及时地既做采集,又做计算,并且写入数据库。所以,我们可以使用基于消息队列的通信,让组件 1 把数据 x 和 y 保存为 JSON 格式的消息,再发到消息队列,这样它就可以继续接收新的数据了。组件 2 则异步地从消息队列中把数据读取出来,在服务器 2 上进行求和计算后,再写入数据库。这个过程如下图所示:

img

我们一般把消息队列中发送消息的组件称为生产者(例子中的组件 1),把接收消息的组件称为消费者

在使用消息队列时,消费者可以异步读取生产者消息,然后再进行处理。这样一来,即使生产者发送消息的速度远远超过了消费者处理消息的速度,生产者已经发送的消息也可以缓存在消息队列中,避免阻塞生产者,这是消息队列作为分布式组件通信的一大优势。

消息保序

虽然消费者的信息是异步处理的,但是消息仍然需药按照生产者发送消息的顺序来处理消息,避免后发送的信息被先处理了

重复消息处理

消费者从消息队列读取信息时,有时会因为网络堵塞导致消息重传,此时如果消费者重复执行了相同的消息,如果消息是修改数据,就会导致数据出错。

消息可靠性保证

消费者在处理消息的时候,可能会出现故障或者宕机导致消息没处理的情况。也就是说,当消费者重启时,需要保证重新从消息队列里面读取信息再次处理。

基于List的消息队列解决方案

List本身是先进先出的顺序对数据进行存取,所以满足消息保序的需求。

不过,在生产者在写入数据时,list不会主动通知消费者有新消息写入了,如果消费者要处理消息,只能一直不停调用RPOP命令,带来了性能损失,为了解决这个问题,redis提供了阻塞形式的BRPOP,客户端在没有读到队列数据时,自动阻塞,知道队列有新数据写入队列,再开始读取新数据。

为了解决重复消息处理的问题,消息队列给每个消息提供全局ID,并且把处理过的ID记录下来

为了解决消息处理可靠性的问题,redis在消费者读取了消息后,会把这个消息存入另一个list里面去,这样如果在读取时候消费者挂了,重启后可以去备份里面读取消息处理。

问题出现了:生产者发送数据的数据太快了,但是消费者处理数据的速度太慢,会导致大量数据堆积在list中,给redis的内存带来很大的压力。

这个时候,我们希望启动多个消费者程序组成一个消费组,一起分担处理 List 中的消息。

因此我们引入了Stream

基于Streams的消息队列的解决方案

Streams是redis专门为消息队列设计的数据类型

XADD

XADD 命令可以往消息队列中插入新消息,消息的格式是键 - 值对形式。对于插入的每一条消息,Streams 可以自动为其生成一个全局唯一的 ID。

XREAD

XREAD 在读取消息时,可以指定一个消息 ID,并从这个消息 ID 的下一条消息开始进行读取。另外,消费者也可以在调用 XRAED 时设定 block 配置项,实现类似于 BRPOP 的阻塞读取操作。当消息队列中没有消息时,一旦设置了 block 配置项,XREAD 就会阻塞,阻塞的时长可以在 block 配置项进行设置。

XGROUP

Streams 本身可以使用 XGROUP 创建消费组,创建消费组之后,Streams 可以使用 XREADGROUP 命令让消费组内的消费者读取消息。

使用消费组的目的是让组内的多个消费者共同分担读取消息,所以,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的。

为了保障消费者宕机后,仍然可以处理读取为处理的数据。

Streams 会自动使用内部队列(也称为 PENDING List)留存消费组里每个消费者读取的消息,直到消费者使用 XACK 命令通知 Streams“消息已经处理完成”。如果消费者没有成功处理消息,它就不会给 Streams 发送 XACK 命令,消息仍然会留存。此时,消费者可以在重启后,用 XPENDING 命令查看已读取、但尚未确认处理完成的消息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值