web-dev-qa-db-fra.com

Conception d'une architecture de file d'attente de messages évolutive

J'ai récemment commencé à apprendre les nuances de l'architecture informatique évolutive et d'entreprise, et l'un des composants centraux est une file d'attente de messagerie. Afin d'apprendre le plus possible de tout paradigme de programmation, j'essaie d'implémenter ma propre version d'un service de file d'attente de messagerie.

Jusqu'à présent, ma conception initiale s'exécute sur un écouteur de socket fileté, mais afin d'empêcher le même message d'être téléchargé deux fois par deux nœuds de traitement distincts, le registre d'index de file d'attente de messages est verrouillé lorsqu'une lecture est lancée, et déverrouillé après que le registre a été mise à jour. En tant que tel, cela supprime la nécessité de le threader et signifie qu'il existe un plafond pour la taille d'un système évolutif en fonction de la vitesse de traitement du serveur sur lequel le service de file d'attente de messagerie s'exécute.

Pour contourner ce problème, exécutez le service de file d'attente de messages sur plusieurs serveurs, mais cela augmentera la probabilité que le même message soit téléchargé deux fois. Le seul moyen d'éviter de tels problèmes serait d'inclure un rappel de révocation qui (après que les serveurs, ou même les threads sur un seul serveur, ont synchronisé leurs informations et détecté une telle réémission) commanderait au nœud de traitement d'arrêter son travail en cours et interroger à nouveau la file d'attente de messages pour le message suivant, mais là encore, il y aurait un plafond où la plupart du trafic envoyé serait des synchronisations et des rappels de révocation, provoquant un goulot d'étranglement et ralentissant le traitement des informations de sorte qu'un beaucoup de nœuds de traitement effectueraient des opérations nulles et perdraient du temps.

La dernière façon dont je peux penser pour contourner ce problème est d'avoir chaque serveur de file d'attente de messages (et chaque thread sur chaque serveur) aurait un décalage spécifique quant à l'endroit dans la file d'attente qu'il recherche, mais cela pourrait avoir des problèmes basés sur le type d'application, en particulier si le traitement doit être effectué dans un ordre spécifique.

Donc, tout cela étant dit, existe-t-il des conceptions d'architecture de file d'attente de messages qui pourraient me montrer comment les services de file d'attente de messages de qualité entreprise évitent ces problèmes?

24
topherg

En bref:

C'est un problème difficile. Ne réinventez pas la roue.

De nombreuses technologies résolvent la couche de file d'attente de messages. Ils comprennent

Je pense qu'il est hors de portée pour moi de discuter des inconvénients de chacun, notamment parce que je ne revendique pas l'expertise pour bien le faire tousse ne pas utiliser Rabbit toux .

Même si vous ne souhaitez utiliser aucune de ces technologies, lisez leur documentation.

Cela vous renseignera sur les modèles de conception qui sont possibles sur un seul système. La lecture la documentation de ZeroMQ vous renseignera sur de nombreuses architectures de file d'attente de messages classiques qu'elles ont gracieusement mises en œuvre. Même si vous n'utilisez pas ZeroMQ, la connaissance de ces modèles vous aidera à évaluer d'autres technologies de mise en file d'attente en vous demandant si vous pouvez y implémenter ce modèle.

Découvrez le modèle de file d'attente d'échange de RabbitMQ/AMQP. Le routage peut arriver pour vous - cela est pris en charge par Redis PUBSUB mais je ne me souviens pas avoir été pris en charge par ZeroMQ - et les fanouts sont quelque chose que ma boutique utilise, bien que mal mis en œuvre via un sondage Memcached (beurk!), Depuis un certain temps .

Comment en choisir un?

Je travaille dans une startup dont SLA est typique d'une application web - certaines pannes sont correctes, tant que nous pouvons rapidement restaurer le service avec peu de perte de données. Nous n'avons pas eu à penser à des problèmes de mise à l'échelle comme Twitter ou Tumblr, nous n'avons donc pas eu à penser au volume de débit. Cela étant dit, si vous implémentez un SLA similaire au mien, ces considérations viendront à l'esprit:

  • les bibliothèques clientes fonctionnent? Est-il facile de maintenir une connexion en eux? (ZeroMQ, Redis: oui. RabbitMQ: non).
  • la surveillance et la gestion sont-elles faciles à partir d'une console de serveur? (Redis: oui, RabbitMQ: oui, ZeroMQ: pas que je me souvienne mais nous ne l'avons pas utilisé aussi longtemps)
  • les clients prennent-ils en charge les files d'attente internes si peu de pertes de données se produisent lors de courtes pannes? (ZeroMQ, Redis: oui. RabbitMQ: non.)

Bien sûr, si vous travaillez pour, disons, un magasin de trading haute fréquence, ce seront vos préoccupations les moins importantes. Vous serez plus disposé à consacrer du temps de développement à une bibliothèque côté client en échange d'un débit plus élevé à la fin. Mais je vous écris davantage pour vous avertir que ces technologies ont tendance à être commercialisées en fonction de leurs performances, et non de leurs fonctionnalités prédéfinies. Si vous êtes une startup du Web, vous êtes loin plus intéressé par ce dernier que par le premier, et par conséquent, quelque chose comme Redis, qui est plus optimisé pour une facilité d'utilisation à de bonnes performances que le difficulté d'utilisation à grande performance, est probablement un meilleur choix que RabbitMQ. (Je n'aime pas RabbitMQ).

15
djechlin