245

我是RabbitMQ等消息代理的新手,我们可以使用它为Celery等调度系统创建任务/消息队列。

现在,这是一个问题:

  • 我可以在PostgreSQL中创建一个表,该表可以附加新任务并由 Celery 等消费者程序使用。

  • 为什么我要为此设置一个全新的技术,比如 RabbitMQ?

现在,我认为扩展无法解决问题,因为我们的数据库(如 PostgreSQL)可以在分布式环境中工作。

我用谷歌搜索数据库对特定问题有什么问题,我发现:

  • 轮询使数据库保持忙碌且性能低下
  • 锁定表 -> 再次表现不佳
  • 数百万行任务->再次,轮询性能低下

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

另外,我发现AMQP协议是它遵循的。这有什么了不起的?

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

请对此有所了解!

4

2 回答 2

131

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

至于你提到的问题:

  • 轮询保持数据库繁忙和低性能:使用 Rabbitmq,生产者可以更新推送给消费者,这比轮询性能要好得多。只需在需要时将数据发送给消费者,无需进行无用的检查。

  • 锁定表->再次低性能:没有要锁定的表:P

  • 数百万行任务 -> 再次轮询性能低下:如上所述,Rabbitmq 将运行得更快,因为它驻留在 RAM 中,并提供流控制。如果需要,它还可以在 RAM 用完时使用磁盘临时存储消息。在 2.0 之后,Rabbit 的 RAM 使用率有了显着改善。集群选项也可用。

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


(来源: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/

于 2012-10-22T06:33:53.230 回答
77

PostgreSQL 9.5

PostgreSQL 9.5 包含SELECT ... FOR UPDATE ... SKIP LOCKED. 这使得实现工作排队系统变得更加简单和容易。您可能不再需要外部排队系统,因为现在可以轻松获取没有其他会话锁定的“n”行,并保持它们锁定,直到您确认工作已完成。当需要外部协调时,它甚至可以与两阶段事务一起使用。

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

旧版本

不需要这样的工具,但使用一个可能会让生活更轻松。在数据库中进行排队看起来很容易,但在实践中您会发现高性能、可靠的并发排队在关系数据库中确实很难做到。

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

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

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

于 2012-10-22T05:42:35.060 回答