为什么我们需要像RabbitMQ这样的消息代理而不是像PostgreSQL这样的数据库?

我对像RabbitMQ这样的消息代理不熟悉,我们可以使用它为像芹菜这样的调度系统创建任务/消息队列。

现在问题来了:

  • 我可以在PostgreSQL中创建一个表,它可以附加新的任务,并被像芹菜这样的消费者程序消费。

  • 为什么我要为RabbitMQ这样一个全新的技术呢?

现在,我认为伸缩性不是答案,因为我们的数据库(如PostgreSQL)可以在分布式环境中工作。

我在谷歌上搜索了数据库对特定问题造成的问题,我发现:

  • 轮询使数据库繁忙且性能低下
  • 锁定表->再次低性能
  • 数百万行任务—又是>,轮询的性能很低

现在,RabbitMQ或其他类似的消息代理是如何解决这些问题的呢?

此外,我发现AMQP协议是它遵循的。这有什么好呢?

复述,也可以用作消息代理吗?我发现它更类似于Memcached而不是RabbitMQ。

请解释一下!

52701 次浏览

PostgreSQL 9.5

PostgreSQL 9.5合并了SELECT ... FOR UPDATE ... SKIP LOCKED。这使得实现工作队列系统很多更加简单和容易。您可能不再需要外部队列系统,因为现在很容易获取没有其他会话锁定的“n”行,并保持它们锁定,直到您提交确认工作完成为止。当需要外部协调时,它甚至可以处理两阶段事务。

外部队列系统仍然很有用,它提供了固定的功能、经过验证的性能、与其他系统的集成、水平扩展和联合的选项等等。然而,对于简单的情况,你不再需要它们了。

旧版本

你不需要这样的工具,但使用一个可能会使生活更容易。在数据库中进行排队看起来很简单,但是在实践中你会发现,在关系数据库中执行高性能、可靠的并发排队是真的很难的正确方法。

这就是像PGQ这样的工具存在的原因。

你可以在PostgreSQL中通过使用LISTENNOTIFY来摆脱轮询,但这并不能解决在保持高并发操作和不阻塞插入的同时,将队列顶部的条目可靠地分发给一个消费者的问题。所有您认为可以解决该问题的简单而明显的解决方案实际上在现实世界中都无法实现,而且往往会退化为效率较低的单工作者队列获取版本。

如果你不需要高并发的多工作者队列获取,那么在PostgreSQL中使用单个队列表是完全合理的。

Rabbit的队列驻留在内存中,因此比在数据库中实现要快得多。一个(好的)专用消息队列还应该提供与队列相关的基本特性,比如节流/流控制,以及选择不同路由算法的能力(rabbit提供了这些功能)。根据项目的大小,您可能还希望消息传递组件与数据库分离,这样如果一个组件负载过重,它就不必妨碍另一个组件的操作。

关于你提到的问题:

  • 轮询使数据库处于繁忙和低性能状态:使用Rabbitmq,生产者可以更新给消费者,这比轮询的性能要好得多。数据只在需要时发送给消费者,消除了不必要的检查。

  • 表的锁定->还是表现不佳:没有表要锁

  • 如上所述,Rabbitmq将运行得更快,因为它驻留在RAM中,并提供流控制。如果需要,它还可以在RAM耗尽时使用磁盘临时存储消息。在2.0之后,Rabbit在RAM使用方面有了显著的改善。集群选项也是可用的。

关于AMQP,我想说一个非常酷的功能是“交换”,以及路由到其他交易所的能力。这为您提供了更大的灵活性,并使您能够创建广泛的精心设计的路由类型,这在扩展时非常方便。关于一个好的例子,请参见:

< p > < img src = " https://i.stack.imgur.com/LIt6H.png " alt = " / >
(来源:springsource.com) < /订阅>

和:http://blog.springsource.org/2011/04/01/routing-topologies-for-performance-and-scalability-with-rabbitmq/

最后,关于Redis,是的,它可以用作消息代理,而且做得很好。然而,Rabbitmq拥有比Redis更多的消息队列特性,因为Rabbitmq是从头开始构建的,是一个全功能的企业级专用消息队列。另一方面,Redis主要被创建为内存中的键值存储(尽管现在它的功能远远不止于此;它甚至被称为瑞士军刀)。尽管如此,我已经读到/听说很多人在小型项目中使用Redis取得了很好的效果,但在大型应用中却没有听说太多。

下面是一个在长轮询聊天实现中使用Redis的例子:http://eflorenzano.com/blog/2011/02/16/technology-behind-convore/