消息队列可以支持组件通信消息的快速读取和写作,而Redis作为常用的缓存组件,支持高速访问数据,只能满足消息队列的读取和写入性能要求。除了性能外,消息队列还有其他要求,很多人关心一个问题:“ redis适合消息队列吗?”
实际上,在这个问题的背后,有两个方面有两个核心问题:
在系统设计中,通常会考虑系统的高可用性,高性能和易于扩展功能,并且消息队列还用作工具手段,通常用于解决:
消息队列的常用场景:
市场上的专业MQ包括RocketMQ,Kafka等。Redis为什么会导出实现消息队列?
一般设计信息队列需要考虑三个需求,
当然,可以根据场景选择性实现以上三个条件
需求1:消息序言
尽管消费者是异步处理消息,但消费者仍然需要按照生产者发送消息的顺序处理该消息,并避免通过帖子延期发送的消息。对于需要消息准备的场景,一旦处理消息,就可以处理消息。命令,它可能导致业务逻辑被错误地执行并造成业务方损失。
需求2:重复消息处理
当消费者从消息队列中阅读消息时,由于网络的障碍,新闻有时会复发新闻。在这一点上,消费者可能会收到多个重复的消息。对于重复的新闻,如果处理消费者多次处理,他们会收到多次。可能导致业务逻辑多次执行。如果业务逻辑只是为了修改数据,则将多次修改数据。
需求3:消息可靠性保证
当消费者处理该消息时,他们也可能会有这样的情况:由于失败或停机时间,该消息没有处理。这次,消息队列需要提供可靠性的保证,也就是说,当消费者重新启动时,您可以再次阅读消息并再次处理,否则将发生消息的消息。
列表本身将首先以高级访问顺序访问数据,因此,如果您将列表用作消息队列来保存消息,则可以满足消息准备的需求。
具体而言,生产者可以使用lpush命令依次编写要发送的消息,而消费者可以使用RPOP命令。从列表的另一端,依次阅读消息并处理。
应该注意的是,当同一队列的多重消耗率消耗时,此时并不有序。
当消费者阅读数据时,会有潜在的性能风险点。
当生产者在列表中写入数据时,列表不会主动通知消费者写新闻。如果消费者想及时处理消息,他们需要在程序中不断调用RPOP命令。如果写了新消息,则RPOP命令将返回结果,否则,RPOP命令返回空白值,然后继续继续环形。
因此,即使没有列表的新消息,消费者也必须不断调用RPOP命令,这会导致消费者程序的CPU消耗RPOP命令,从而导致CPU为空。
当然,也有解决方案;当没有拉消息时,睡眠可能是:
但是,在这种情况下,可能会有新闻延迟时间处理,然后看不起:
REDIS提供了BRPOP命令。BRPOP命令也称为阻止阅读。当客户端不读取队列数据时,它会自动阻碍,直到将新数据写入队列中,并且启动了新数据,而消费者程序则不断地调用RPOP命令,此方法可以节省CPU开销。
消息准备的问题解决了。接下来,您需要考虑解决重复消息处理的问题;让我们看看消费者如何对消息进行重复判断。
收到消息后,消费者程序可以比较接收到的消息ID和处理信息ID,以确定当前接收的消息是否已处理。称为功率,例如电源,电源和其他性质意味着,对于同一消息,消费者收到了一个时间处理结果,并收到了多个处理结果。
但是,列表本身不会为每个消息生成ID号。因此,消息的唯一ID号要求生产者程序在发送消息之前生成自身。生成后,当我们使用LPUSH命令将消息插入列表中时,我们需要在消息中包含全局唯一ID。
最后,让我们看一下列表类型如何保证新闻的可靠性。
当消费者程序从列表中读取消息时,列表将不再保留此消息。因此,如果消费者程序在处理消息的过程中失败或下降,则会导致消息未经处理。然后,在消费者程序再次启动之后,它将无法再次从列表中读取消息。
我们可以添加备份队列。当该消息来自队列中的RPOP时,及时放入备份队列,并在消费者提交ACK时将其从备份队列中删除;
当然,列表类型提供了BRPOPLPUSH命令。该命令的作用是允许消费者程序从一个列表中读取消息。同时,REDIS会将此消息插入另一个列表(可以称为备份列表)。如果使用消费者程序读取消息但未能正常处理,则可以重新启动,您可以重新阅读。消息并从备份列表中处理。
当然,备份队列不必使用列表的brpoplpush命令,您也可以使用像哈希这样的结构来存储它。简而言之,选择多样性
消息可靠性与伪代码相关的代码如下:
在日常开发中,您可能还经常遇到需要以延迟队列对待的场景,例如15分钟的有效时间支付订单,最新的物流订单状态30分钟等等。,您可以考虑使用Redis的ZSET实现
ZSET结构具有可用于控制延迟的参数分数。例如
然后采取这个:
ZSET是有序结构。每次采用第一个元素以确定是否可以处理。如果无法处理第一个元素,则说明后的元素未达到执行时间。
这与列表类似,您需要备份队列以确保消息的可靠性;也就是说,步骤3和4,首先将消息存储到备份队列中,然后从原始队列中删除消息。在ACK之后,该消息从备份队列中删除,在这里,该消息已完全处理。
让我们看一下ZSET实现队列的特征:
到目前为止,列表和ZSET实施的队列还不能很好地支持多消费者组的场景;当然,您可能会认为,根据Multi -Cosmumer Group的场景,您也可以写下来。但是,复杂性已经飙升,错误很容易。
REDIS从5.0版中提供的流数据类型是为Redis设计的消息队列,可以支持多个消费者组的场景。
流提供丰富的消息队列操作命令。
常见命令:
1. XADD:
2. XLEN
指示查询流队列的长度
3. Xrange
其中 - +表示最小ID和最大ID,也就是说,返回整个队列数据
返回队列前两个数据
4. xrevrange
Xrange的对立面只是返回队列的最后一个数据
5,xread
6. XGroup用于创建,销毁和管理消费者组;这里的消费者组类似于Kafka消费者组的概念。组中消费者之间的消费数据是相互排斥的,可以在组之间处理相同的数据。redis流的概念没有。
当指定流不存在时,您可以指定子选项MkStream以自动创建流
7. XreadGroup
一旦消费者组的消费者阅读了消息队列中的消息队列,消费者组中的其他消费者将不再阅读它。
值得注意的是,使用消费者组的目的是允许该组中的多个消费者共享消息以收集消息。因此,每个消费者通常都会读取消息的一部分,因此读取负载在多个消费者中的多个消费者中。平衡分布之间。这与Kafka不同。卡夫卡(Kafka)具有分区的概念。消费者群体中的消费者负责消耗不同的分区数据,并且没有消费者消耗同一分区的情况。
8. xpending查询消费者绘制但不使用ACK的消息可用于恢复诸如崩溃和其他前所未有的执行等数据,这等同于列表队列的“备份队列”。用途如下:
命令行,例如:
返回待定队列中的十大数据。
为了确保消费者在失败或停机时间失败后仍然可以阅读未准备好的新闻,流将自动使用待处理的列表队列来备份消费者组中每个消费者的新闻,直到消费者使用Xack来使用Xack来使用Xack The Stream的订单通知“已处理消息”。如果消费者无法成功处理该消息,则不会将XACK命令发送到流,并且该消息仍将保留。这次,消费者可以使用Xpending命令重新启动以查看已阅读但尚未确认处理的新闻。
流是由REDIS 5.0设计的数据类型,专门用于消息队列场景。如果您的Redis是5.0和5.0之后的版本,则可以考虑使用流作为消息队列。
可以看出,Redis队列对开发人员很友好,但是您可能会考虑其新闻积压和Redis本身。
总而言之,REDIS队列可以考虑在非核心业务中使用,例如E -Commerce会员点,文本消息,付款倒计时,甚至是一些常规处理的订单状态。在Shortuse!
相关参考: