Quelles sont les solutions au problème de file d'attente distribuée?

23

J'essaie d'en savoir plus sur les différentes manières de résoudre le problème d'une file d'attente distribuée. Je voudrais donc savoir quels produits, services, implémentations et documents de recherche sont déjà disponibles.

Une mise en œuvre sera confrontée à de nombreux défis et sera obligée de faire des compromis:

  • At-il une commande forte ou lâche?
  • At-il mis idempotent?
  • Pouvons-nous avoir plus de files d'attente que ce qui peut tenir sur une seule machine?
  • Pouvons-nous avoir plus de données dans une file d'attente que ce qui peut tenir sur une seule machine?
  • Combien de machines peuvent planter avant de perdre potentiellement des données?
  • Peut-il tolérer des fractionnements nets?
  • Peut-il réconcilier automatiquement les données lorsqu'un partage net est résolu?
  • Peut-il garantir la livraison lorsque les clients peuvent tomber en panne?
  • Peut-il garantir que le même message n'est pas transmis plus d'une fois?
  • Un nœud peut-il tomber en panne à un moment donné, remonter et ne pas envoyer de courrier indésirable?
  • Pouvez-vous ajouter ou supprimer des nœuds dans un cluster en cours d'exécution sans interruption?
  • Pouvez-vous mettre à niveau des nœuds dans un cluster en cours d'exécution sans temps d'arrêt?
  • Peut-il fonctionner sans problème sur des serveurs hétérogènes?
  • Pouvez-vous «coller» des files d'attente à un groupe de serveurs? (exemple: "ces files d'attente ne sont autorisées que dans le centre de données européen")
  • Peut-il s'assurer de placer des répliques de données dans au moins deux centres de données, le cas échéant?

Je ne me fais aucune illusion que toute mise en œuvre pourra dire «oui» à tout cela. Je suis simplement intéressé à entendre parler des différentes implémentations; comment ils fonctionnent, quels compromis ils ont faits et peut-être pourquoi ils ont décidé de leur ensemble particulier de compromis.

Aussi, s'il y a des défis que j'ai pu manquer dans la liste ci-dessus.

Chris Vest
la source

Réponses:

13

Écrire un système de mise en file d'attente de base est assez simple, mais comme vous l'avez noté ci-dessus avec tous les défis, le faire correctement est une autre question. J'ai utilisé des systèmes maison pour lesquels j'ai écrit le code source, des systèmes tiers et divers fournisseurs JMS. JMS (Java Messaging Service) est de loin la solution la plus complète que j'ai rencontrée jusqu'à présent. Une grande partie de ce que vous demandez est disponible dans JMS. Mon fournisseur JMS préféré est ActiveMQ. Gratuit, performant, facile à installer et, surtout, facile à intégrer dans mon application avec Spring. Les fournisseurs JMS ne fournissent pas tout ce que vous avez demandé, mais ils fournissent un ensemble d'outils pour gérer une grande partie de ce que vous avez demandé si votre application en avait besoin. Je n'ai pas trouvé que beaucoup d'applications ont besoin de tout ce que vous avez listé. La commande peut ne pas être importante (il vaut mieux que ce ne soit pas le cas),

http://activemq.apache.org/what-open-source-integration-solution-works-best-with-activemq-.html

At-il une commande forte ou perdue? Oui. Il a les deux en fonction des besoins de vos programmes. Voici les détails: http://activemq.apache.org/total-ordering.html .

At-il mis idempotent? Non, mais cela est trivial à implémenter dans votre couche application si vous en avez besoin.

Pouvons-nous avoir plus de files d'attente que ce qui peut tenir sur une seule machine? Oui. Vous pouvez avoir des serveurs en cluster, et si vous souhaitez configurer plusieurs machines avec différentes files d'attente, vous pouvez, et tirer de l'une ou l'autre.

Pouvons-nous avoir plus de données dans une file d'attente que ce qui peut tenir sur une seule machine? Oui, la plupart des fournisseurs JMS doivent utiliser une sorte de stockage DB / persistant pour garantir que les messages ne sont pas perdus ou perdus si le fournisseur JMS tombe en panne.

Combien de machines peuvent planter avant de perdre potentiellement des données? C'est un peu plus difficile à répondre car c'est lié au timing. Cependant, vous pouvez planter un fournisseur JMS et à condition que le disque ne soit pas corrompu, il reviendra et commencera là où il a reçu le dernier commit. Cela signifie que les messages peuvent être remis deux fois, mais si vous codez votre application pour gérer cela, ce n'est pas un problème. Tant que vous en avez au moins un de chaque type (producteurs, consommateurs ou serveurs JMS), il se terminera. Vous pouvez également avoir la charge / l'équilibre / le basculement pour la redondance si un disque sort sur vous.

Peut-elle tollérer les fractionnements nets? Je pense que je comprends ce que vous entendez par "net-split", mais je ne suis pas tout à fait sûr. Je suppose que vous voulez dire que si les serveurs JMS sont en cluster, et que nous perdons la connexion avec l'un des serveurs, il sautera vers un autre serveur et reprendra là où il s'était arrêté. Oui, mais là encore, ces types de situations peuvent conduire à des messages en double selon le moment où le client a perdu la connexion.

Peut-il réconcilier automatiquement les données lorsqu'un partage net est résolu? Si vous utilisez des sessions traitées, il ne redistribuera tout message ayant fait l'objet d'une validation aux clients existants qui sont actifs.

Peut-il garantir la livraison lorsque les clients peuvent tomber en panne? Oui, c'est l'un des principaux objectifs de JMS. La livraison garantie signifie que si un message est mis en file d'attente, il est garanti d'être traité par un client.

Peut-il garantir que le même message n'est pas transmis plus d'une fois? Oui si les sessions traitées sont utilisées. Cela signifie qu'un client a accepté le message et appelé commit / rollback. Une fois le commit appelé, il ne remettra pas le message.

Un nœud peut-il tomber en panne à un moment donné, remonter et ne pas envoyer de courrier indésirable? Dans le cas où vous disposez de files d'attente en cluster durables. Oui, il ne crachera pas de «courrier indésirable» si l'autre nœud du cluster a remis le message. Il peut toujours livrer tout ce qui n'a pas été reconnu.

Pouvez-vous ajouter ou supprimer des nœuds dans un cluster en cours d'exécution sans interruption? Oui.

Pouvez-vous mettre à niveau des nœuds dans un cluster en cours d'exécution sans temps d'arrêt? C'est un peu plus compliqué pour moi de répondre, mais je crois que oui, vous pouvez le faire.

Peut-il fonctionner sans problème sur des serveurs hétérogènes? Qu'est-ce que cela signifie exactement? J'ai trouvé que la plupart des fournisseurs JMS sont très faciles à exécuter dans des environnements utilisant différents matériels, systèmes d'exploitation, etc. Bien que, si vous parlez de performances, c'est une tout autre chose. Tout système de traitement distribué peut être affecté négativement par un nœud lent. J'avais 2 serveurs Intel 8 Core exécutant la file d'attente et les consommateurs. C'est 16 cœurs ensemble, et j'ai obtenu de meilleures performances en utilisant uniquement ces deux boîtiers, que lorsque j'ai ajouté une machine monocœur en tant que consommateur. Cette machine monocœur était tellement plus lente qu'elle a ralenti l'ensemble de la grille d'un facteur 2x. Cela n'avait rien à voir avec JMS en soi.

Pouvez-vous «coller» des files d'attente à un groupe de serveurs? Réponse courte oui. Je peux penser à un moyen où vous pouvez exécuter un cluster qui ne se trouve que dans le centre de données européen et y configurer la file d'attente. Ensuite, dans votre configuration de printemps, configurez vos consommateurs pour consommer cette file d'attente ainsi que d'autres files d'attente sur d'autres clusters. Vous voudrez peut-être consulter les documents:

http://activemq.apache.org/clustering.html

Peut-il s'assurer de placer des répliques de données dans au moins deux centres de données, si c'est le cas? Encore une fois, je le crois, mais il est préférable de consulter les documents de clustering.

Encore une fois, JMS propose de nombreuses options que vous pouvez modifier selon vos besoins. L'utilisation de sessions traitées et de files d'attente durables a un coût de performance. J'ai vu allumer toutes les cloches et les sifflets impactaient les performances jusqu'à 10 fois. Lorsque j'ai utilisé JBossMQ si nous désactivions certaines de ces fonctionnalités, nous pouvions obtenir environ 10 000 messages / s, mais les activer nous a ramenés à 1 000 messages / s. Grosse chute.

chubbsondubs
la source
Merci d'avoir pris le temps avec cette réponse. Un net-split se produit lorsque certains nœuds d'un cluster ne peuvent plus communiquer avec les autres. Par serveurs hétérogènes, j'entends principalement différentes quantités de RAM - certains systèmes distribués le préfèrent lorsque les serveurs se ressemblent.
Chris Vest
Alors c'est sûr oui sur netsplits. Si un consommateur tombe en panne ou ne peut pas communiquer, il continuera d'essayer de se connecter. Les emplois qui lui ont été attribués et qui n'ont pas été validés seront ensuite redistribués à d'autres consommateurs. Si un fournisseur JMS tombe en panne et que vous avez d'autres membres du cluster, les messages peuvent être dupliqués sur le cluster pour éviter de perdre des messages.
chubbsondubs
Il n'y a aucune exigence pour que les machines soient identiques, qu'elles soient RAM, matérielles ou OS. Vous pouvez exécuter un sac mixte de machines si vous en avez besoin. La seule préoccupation est celle que j'ai notée, qui est liée aux performances dans la mesure où les machines qui ne sont pas les mêmes traiteront les messages à des taux différents, ce qui peut entraîner une baisse du débit. Cependant, le modèle JMS atténue quelque peu cela par le fait qu'il s'agit d'un modèle pull au lieu d'un modèle push. Les modèles push sont beaucoup plus sensibles à ces types de problèmes.
chubbsondubs