Pourquoi avons-nous besoin de courtiers de messages comme RabbitMQ sur une base de données comme PostgreSQL?

215

Je suis nouveau dans les courtiers de messages comme RabbitMQ que nous pouvons utiliser pour créer des tâches / files d'attente de messages pour un système de planification comme Celery .

Maintenant, voici la question:

  • Je peux créer une table dans PostgreSQL qui peut être ajoutée à de nouvelles tâches et consommée par le programme consommateur comme Celery.

  • Pourquoi diable voudrais-je installer une toute nouvelle technologie pour cela comme RabbitMQ?

Maintenant, je crois que la mise à l'échelle ne peut pas être la réponse puisque notre base de données comme PostgreSQL peut fonctionner dans un environnement distribué.

J'ai recherché sur Google quels problèmes la base de données pose pour le problème particulier, et j'ai trouvé:

  • l'interrogation maintient la base de données occupée et peu performante
  • verrouillage de la table -> encore peu performant
  • des millions de lignes de tâches -> encore une fois, le sondage est peu performant

Maintenant, comment RabbitMQ ou tout autre courtier de messages comme celui-ci résout-il ces problèmes?

De plus, j'ai découvert que le AMQPprotocole est ce qu'il suit. Qu'est-ce qui est génial là-dedans?

Redis peut-il également être utilisé comme courtier de messages? Je le trouve plus analogue à Memcached qu'à RabbitMQ.

Veuillez éclairer ce sujet!

Yugal Jindle
la source
9
L'impact du verrouillage devrait être beaucoup moins important avec PostgreSQL car il implémente MVCC où les lecteurs ne sont pas bloqués par les écrivains et vice versa. La plupart des articles que j'ai trouvés critiquant l'utilisation des bases de données comme files d'attente de messages ont en tête MySQL.
CadentOrange
Un courtier de messages déplace les données entre les nœuds, tandis qu'une base de données conserve les données au même endroit. Le fait que vous puissiez accéder aux données d'une base de données à partir de plusieurs nœuds ne fait pas, à première vue, un bon outil pour transférer rapidement des données entre nœuds.
theMayer
2
"système de planification comme celery" - je viens d'apprendre quelque chose qui sera utile dans ma conception, de la question . Maintenant pour lire les réponses ...
Mark K Cowan
l'utilisation du courtier de messages producteur et consommateur est découplée.
giorgi dvalishvili
Vous pouvez voir le lien ci-dessous. Il a une description large: stackoverflow.com/a/51377756/3073945
Md. Sajedul Karim

Réponses:

110

Les files d'attente de Rabbit résident en mémoire et seront donc beaucoup plus rapides que leur implémentation dans une base de données. Une (bonne) file d'attente de messages dédiée devrait également fournir des fonctionnalités essentielles liées à la mise en file d'attente telles que la limitation / le contrôle du flux et la possibilité de choisir différents algorithmes de routage, pour en nommer un couple (Rabbit en fournit et bien plus). Selon la taille de votre projet, vous pouvez également souhaiter que le composant de transmission de messages soit distinct de votre base de données, de sorte que si un composant subit une charge importante, il n'a pas besoin d'entraver le fonctionnement de l'autre.

Quant aux problèmes que vous avez mentionnés:

  • sondage gardant la base de données à jour et peu performante : à l'aide de Rabbitmq, les producteurs peuvent envoyer des mises à jour aux consommateurs, ce qui est beaucoup plus performant que le sondage. Les données sont simplement envoyées au consommateur quand elles en ont besoin, ce qui élimine le besoin de contrôles inutiles.

  • verrouillage de la table -> encore peu performant: Il n'y a pas de table à verrouiller: P

  • des millions de lignes de tâche -> encore une fois, l'interrogation est peu performante: Comme mentionné ci-dessus, Rabbitmq fonctionnera plus rapidement car il réside dans la RAM et fournit un contrôle de flux. Si nécessaire, il peut également utiliser le disque pour stocker temporairement des messages s'il manque de RAM. Après 2.0, Rabbit a considérablement amélioré son utilisation de la RAM. Des options de clustering sont également disponibles.

En ce qui concerne AMQP, je dirais qu'une fonctionnalité vraiment sympa est "l'échange" et la possibilité pour lui de se diriger vers d'autres échanges. Cela vous donne plus de flexibilité et vous permet de créer un large éventail de typologies de routage élaborées qui peuvent être très utiles lors de la mise à l'échelle. Pour un bon exemple, voir:


(source: springsource.com )

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

Enfin, en ce qui concerne redis, oui, il peut être utilisé comme courtier de messages et peut bien faire. Cependant, Rabbitmq a plus de fonctionnalités de file d'attente de messages que redis, car rabbitmq a été conçu à partir de zéro pour être une file d'attente de messages dédiée au niveau de l'entreprise. Redis, d'autre part, a été principalement créé pour être un magasin de valeurs-clés en mémoire (bien qu'il fasse beaucoup plus que cela maintenant; il est même appelé couteau suisse). Pourtant, j'ai lu / entendu de nombreuses personnes obtenir de bons résultats avec Redis pour des projets de plus petite taille, mais je n'en ai pas beaucoup entendu parler dans les applications plus grandes.

Voici un exemple de redis utilisé dans une implémentation de chat à longue interrogation: http://eflorenzano.com/blog/2011/02/16/technology-behind-convore/

Jaigus
la source
2
J'ai implémenté une implémentation JMS (c'est-à-dire un système de transmission de messages) au-dessus d'une base de données. Je peux vous dire qu'il est possible, mais ce n'est pas amusant et il ne paie généralement pas de le faire. Certains des problèmes que vous mentionnez peuvent être contournés, mais cela augmente considérablement la complexité. Dans l'ensemble, je suis d'accord: utilisez un système MQ dédié, si vous en avez besoin. Pour les charges de travail faibles, vous pouvez cependant vous en passer avec la base de données.
Joachim Sauer
1
Vous avez simplement couvert toutes vos préoccupations / doutes. Réponse géniale!
Yugal Jindle
C'est intéressant. Et la cohérence d'ailleurs? Que se passe-t-il s'il y a des centaines de tâches dans une file d'attente et que le nœud qui les contient dans le RAM se bloque?
Mahn
22
En fait, avec PostgreSQL il n'y a pas d'interrogation (voir NOTIFY) ni de verrous de table (voir MVCC). Bien que PostgreSQL ne soit toujours pas conçu pour la mise en file d'attente des messages, il n'est pas complètement inapproprié.
jkj
3
Comme ce qu'a dit @jkj, il y a NOTIFY et aucun verrou de table. Le seul problème semble être la bande passante élevée des messages. Ne pourriez-vous pas avoir une instance PostgreSQL dédiée au lieu de maintenir un système entièrement nouveau comme Rabbit? Vous pouvez 1) utiliser une seule instance PostgreSQL jusqu'à ce que vous atteigniez un goulot d'étranglement, puis 2) utiliser un Postgres dédié, puis enfin 3) passer facilement à Rabbit en tant que votre courtier. On dirait que commencer avec Rabbit est une pré-optimisation.
Joe
72

PostgreSQL 9.5

PostgreSQL 9.5 intègre SELECT ... FOR UPDATE ... SKIP LOCKED. Cela rend la mise en œuvre de systèmes de mise en file d'attente de travail beaucoup plus simple et plus facile. Vous n'avez peut-être plus besoin d'un système de mise en file d'attente externe, car il est désormais simple de récupérer des 'n' lignes qu'aucune autre session n'a verrouillées et de les garder verrouillées jusqu'à ce que vous validiez la confirmation que le travail est terminé. Il fonctionne même avec des transactions en deux phases lorsque la coordination externe est requise.

Les systèmes de files d'attente externes restent utiles, offrant des fonctionnalités prédéfinies, des performances éprouvées, l'intégration avec d'autres systèmes, des options de mise à l'échelle horizontale et de fédération, etc. Néanmoins, pour les cas simples, vous n'en avez plus vraiment besoin.

Versions plus anciennes

Vous n'avez pas besoin de tels outils, mais en utiliser un peut vous faciliter la vie. La mise en file d'attente dans la base de données semble facile, mais vous découvrirez dans la pratique que la mise en file d'attente simultanée fiable et hautes performances est vraiment difficile à faire correctement dans une base de données relationnelle.

C'est pourquoi des outils comme PGQ existent.

Vous pouvez vous débarrasser de l'interrogation dans PostgreSQL en utilisant LISTENet NOTIFY, mais cela ne résoudra pas le problème de la distribution fiable des entrées du haut de la file d'attente à exactement un consommateur tout en préservant le fonctionnement hautement simultané et en ne bloquant pas les insertions. Toutes les solutions simples et évidentes qui, selon vous, permettront de résoudre ce problème ne le sont pas dans le monde réel et ont tendance à dégénérer en versions moins efficaces de la récupération de file d'attente par un seul travailleur.

Si vous n'avez pas besoin de récupérations de files d'attente multi-travailleurs hautement simultanées, l'utilisation d'une seule table de files d'attente dans PostgreSQL est tout à fait raisonnable.

Craig Ringer
la source
11
la ligne le reliably handing out entries off the top of the queue to exactly one consumer while preserving highly concurrent operation and not blocking inserts. résume - non?
Yugal Jindle