MQ高级-惰性队列

发布于:2023-09-22 ⋅ 阅读:(89) ⋅ 点赞:(0)

请添加图片描述
个人名片:

博主酒徒ᝰ.
个人简介沉醉在酒中,借着一股酒劲,去拼搏一个未来。
本篇励志三人行,必有我师焉。

请添加图片描述
本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 点击观看

四、惰性队列

2. 惰性队列

惰性队列是一种数据结构,它可以在不需要立即处理的情况下,将数据元素暂存到队列中,留待后续处理。

惰性队列是一种特殊的队列,它遵循先进先出(FIFO)的原则。与普通队列不同的是,惰性队列中的元素只有在需要时才会被处理,而不是立即处理。这使得惰性队列可以有效地应对处理时间不确定或处理过程耗时的情况。

惰性队列的应用场景非常广泛。

  • 在任务调度系统中,我们可能需要对大量任务进行排序和调度。如果每个任务的处理时间都很短,但是数量非常庞大,那么我们可以使用惰性队列来暂存这些任务,并在需要时再进行处理。这样可以避免大量计算和内存开销。

  • 在机器学习中,我们可能需要处理大量的数据来进行模型训练。由于模型训练过程通常需要较长时间,因此我们可以使用惰性队列来暂存这些数据,并在空闲时间或需要时进行批量处理。这样可以有效地利用系统资源,提高处理效率。

惰性队列的优点主要体现:

  • 减少计算和内存开销:由于惰性队列中的元素只有在需要时才会被处理,因此可以避免大量不必要的计算和内存开销。
  • 提高系统资源利用率:惰性队列可以有效地利用系统资源,例如CPU和内存,从而提高系统资源利用率。
  • 灵活性和可扩展性:惰性队列可以灵活地应对各种应用场景,并且可以轻松地扩展到大规模数据处理中。

惰性队列的不足:

  • 数据一致性问题:由于惰性队列中的元素在需要时才会被处理,因此可能会导致数据一致性问题。例如,在多线程环境下,如果一个线程在读取队列中的元素时,另一个线程修改了该元素,那么可能会导致数据不一致的情况。
  • 数据丢失风险:如果惰性队列中的元素在需要时未被正确处理,那么可能会导致数据丢失的风险。

改进建议:

  • 使用锁或其他同步机制:在多线程环境下,我们可以使用锁或其他同步机制来确保线程安全,从而避免数据一致性问题。
  • 设计合理的调度策略:为了降低数据丢失风险,我们可以设计合理的调度策略,确保每个元素在需要时都能被正确处理。

惰性队列的实现可以基于现有的队列数据结构,通过添加一些额外的标志位或条件来判断是否需要处理队列中的元素。例如,我们可以在每个队列元素中添加一个标记位,表示该元素是否已被处理。当需要处理队列中的元素时,我们只需要检查标记位即可。

总结来说,惰性队列是一种非常有用的数据结构,它可以有效地应对处理时间不确定或处理过程耗时的情况。通过暂存待处理的元素并在需要时再进行处理,惰性队列可以减少计算和内存开销,提高系统资源利用率,并具有灵活性和可扩展性。然而,需要注意解决数据一致性和数据丢失问题。在实践中,我们应该根据具体的应用场景来选择是否使用惰性队列,并根据实际情况进行相应的改进或扩展。

从RabbitMQ的3.6.0版本开始,就增加了Lazy Queues的概念,也就是惰性队列。惰性队列的特征如下:

  • 接收到消息后直接存入磁盘而非内存
  • 消费者要消费消息时才会从磁盘中读取并加载到内存
  • 支持数百万条的消息存储
  1. 基于命令行设置lazy-queue

而要设置一个队列为惰性队列,只需要在声明队列时,指定x-queue-mode属性为lazy即可。可以通过命令行将一个运行中的队列修改为惰性队列:

rabbitmqctl set_policy Lazy "^lazy-queue$" '{"queue-mode":"lazy"}' --apply-to queues  

命令解读:

  • rabbitmqctl :RabbitMQ的命令行工具
  • set_policy :添加一个策略
  • Lazy :策略名称,可以自定义
  • "^lazy-queue$" :用正则表达式匹配队列的名字
  • '{"queue-mode":"lazy"}' :设置队列模式为lazy模式
  • --apply-to queues :策略的作用对象,是所有的队列
  1. 基于@RabbitListener声明LazyQueue
@RabbitListener(queuesToDeclare = @Queue(
        name = "lazy.queue",
        durable = "true",
        arguments = @Argument(name = "x-queue-mode", value = "lazy")
))
public void listenLazyQueue(String msg) {
    log.info("接收到lazy.queue的消息:{}", msg);
}

总结

消息堆积问题的解决方案?

  • 队列上绑定多个消费者,提高消费速度
  • 使用惰性队列,可以再mq中保存更多消息

惰性队列的优点有哪些?

  • 基于磁盘存储,消息上限高
  • 没有间歇性的page-out,性能比较稳定

惰性队列的缺点有哪些?

  • 基于磁盘存储,消息时效性会降低
  • 性能受限于磁盘的IO

网站公告

今日签到

点亮在社区的每一天
去签到