为什么我们需要像PostgreSQL这样的像RabbitMQ这样的消息代理?
我对像RabbitMQ这样的消息代理是新来的,我们可以使用它来为像Celery这样的调度系统创build任务/消息队列。
现在,这是一个问题:
-
我可以在PostgreSQL中创build一个表格,这个表格可以被附加新的任务,并被像Celery这样的消费者程序所使用。
-
为什么我要为RabbitMQ设置一个全新的技术?
现在,我相信扩展不能成为答案,因为像PostgreSQL这样的数据库可以在分布式环境中工作。
我search了数据库为特定问题提出的问题,并发现:
- 保持数据库繁忙和低性能的轮询
- 表的locking – >再次performance不佳
- 数百万行的任务 – >再次轮询performance不佳
现在,RabbitMQ或者其他类似的消息代理如何解决这些问题呢?
另外,我发现AMQP
协议是遵循的。 那有什么好处?
Redis也可以用作消息代理吗? 我发现它更类似于memcache然后RabbitMQ。
请点亮这个!
兔子的队列驻留在内存中,因此比在数据库中实现更快。 一个(好的)专用的消息队列还应该提供基本的排队相关的function,例如节stream/stream量控制,以及select不同路由algorithm的能力,命名一对(rabbit提供这些和更多)。 根据您的项目大小,您可能还希望将消息传递组件与数据库分开,以便在一个组件经历沉重负载的情况下,不必妨碍对方的操作。
至于你提到的问题:
-
保持数据库缓慢且性能低下的轮询 :使用Rabbitmq,生产者可以将更新推送给消费者,这比查询的性能高得多。 数据只需发送给消费者,无需进行浪费检查。
-
locking表 – >再次performance不佳:没有表要locking:P
-
数百万行的任务 – >再次轮询performance不佳:如上所述,Rabbitmq将以更快的速度驻留RAM,并提供stream量控制。 如果需要的话,它也可以使用磁盘临时存储消息,如果它的内存不足。 在2.0之后,Rabbit在内存使用上有了明显的提升。 集群选项也是可用的。
关于AMQP,我想说一个非常酷的function是“交换”,以及它能够路由到其他交易所的能力。 这为您提供了更大的灵活性,使您能够创build大量精细的路由types,这些types在缩放时非常方便。 举一个很好的例子,见:
wp-content/uploads/2011/04/routing-topology.png
和: http : //blog.springsource.org/2011/04/01/routing-topologies-for-performance-and-scalability-with-rabbitmq/
最后,关于redis,是的,它可以作为一个消息中介,可以做得很好。 不过,Rabbitmq比Redis具有更多的消息队列function,因为rabbitmq是从头开始构build的,是一个全function的企业级专用消息队列。 另一方面,Redis主要是为了成为一个内存中的键值存储(尽pipe现在的performance还不止这些,甚至被称为瑞士军刀)。 不过,我已经读过/听过很多人用Redis为小型项目取得好成绩,但在大型应用程序中却没有听说过。
以下是在长轮询聊天实施中使用的redis示例: http : //eflorenzano.com/blog/2011/02/16/technology-behind-convore/
PostgreSQL 9.5
PostgreSQL 9.5集成了SELECT ... FOR UPDATE ... SKIP LOCKED
。 这使得实施工作排队系统变得更加简单和容易。 您可能不再需要外部排队系统,因为现在很容易获取没有其他会话locking的“n”行,并保持locking状态,直到您确认工作完成。 甚至在需要外部协调的情况下,它甚至可以用于两阶段交易。
外部排队系统仍然是有用的,提供了jar头function,性能validation,与其他系统集成,水平扩展和联合选项等。但是,对于简单的情况,你不再需要它们。
较旧的版本
你不需要这样的工具,但使用它可能会使生活更轻松。 在数据库中排队看起来很容易,但是在实践中你会发现高性能,可靠的并发排队在关系数据库中确实很难做到。
这就是为什么像PGQ这样的工具存在。
您可以使用LISTEN
和NOTIFY
来消除PostgreSQL中的轮询,但是这并不能解决将队列顶部的条目可靠地分发给一个使用者的问题,同时保持高度并发的操作并且不会阻塞插入。 所有你认为简单而明显的解决scheme将解决这个问题,但实际上并不存在于现实世界中,并倾向于退化为效率较低的单个工作者队列获取版本。
如果您不需要高度并发的多工作器队列提取,那么在PostgreSQL中使用单个队列表是完全合理的。
正如你所说,我的一个简短的视图,postgresql当然可以做芹菜所需要的东西。 但是考虑到我们使用芹菜的操作情况,postgresql并不是最好的select。
而且我认为在工程方面没有最好的解决scheme[消息代理],但是在特定的时间内,对于特定的业务应用程序总是有一个最匹配的解决scheme。