9
votes

Contrôler les rôles de travailleur Azure Concurrence en plusieurs instances

J'ai un simple rôle de travail dans Azure qui effectue un traitement de données sur une base de données SQL Azure. Le travailleur ajoute essentiellement des données d'une source de données tierce à ma base de données toutes les 2 minutes. Lorsque j'ai deux cas de rôle, cela double évidemment inutilement. J'aimerais avoir 2 cas pour redondance et la chaîne de disponibilité 99.95, mais ne veulent pas qu'ils traitent à la fois de la dupliquer le même emploi. Y a-t-il un modèle standard pour cela que je manque? Je sais que je pourrais mettre des drapeaux dans la base de données, mais j'espère qu'il existe un autre moyen plus facile ou meilleur de gérer cela. Merci


1 commentaires

Eh bien, vous pouvez mettre un message de déclenchement sur une file d'attente Azure, car un seul client peut lire un message à la fois. Cependant, cela soulève simplement la question de la manière de créer ces messages en premier lieu. Si vous faites cela des rôles de travailleur à intervalles réguliers, vous avez le même problème à une fois de plus que chaque rôle de travailleur simultané va envoyer le même message à peu près au même moment. Je ne peux pas penser à une solution à cela qui n'implique pas un sémaphore d'une sorte.


4 Réponses :


7
votes

Comme Mark suggéré, vous pouvez utiliser une file d'attente Azure pour poster un message. Vous pouvez avoir l'instance de rôle travailleur poster un message suivant à la file d'attente comme la dernière chose qu'elle effectue lors du traitement du message actuel. Cela devrait traiter de la marque de problème élevé concernant la nécessité d'un sémaphore. Dans votre message de file d'attente, vous pouvez intégrer un marquage horodatage lorsque le message peut être traité. Lors de la création d'un nouveau message, ajoutez simplement deux minutes à l'heure actuelle.

et ... au cas où ce n'est pas évident: dans l'éventualité, l'instance de rôle de travailleur se bloque avant de terminer le traitement et ne survient pas à republier un nouveau message de la file d'attente, c'est bien. Dans ce cas, le message de la file d'attente actuel réapparaîtra simplement sur la file d'attente et une autre instance est alors libre de le traiter.


3 commentaires

Assurez-vous de mettre en œuvre un filtre de message empoisonné, cependant: si un rôle de travailleur se bloque à cause de ce message particulier, vous ne voulez pas le faire republier à la file d'attente de plus et encore. Un nombre de repose-repos (ou le nombre de lecture) peut vous aider là-bas.


Comment démarrez-vous cette machine perpétuelle? Si vous avez deux cas d'un rôle commençant en même temps que l'on devrait poster le 1er message?


J'utilise des files d'attente avec une détection en double via le bus de service pour vous assurer qu'une seule instance effectue une action. Tous les rôles de travailleurs envoient un message au démarrage avec le même messageid. Le ServiceBus supprime ensuite tous les messages sauf un qui est livré à l'une des instances. cloudcasts.net/devguide/default.aspx?id=13026



0
votes

Il n'y a pas de moyen super facile de le faire, je ne pense pas.

Vous pouvez utiliser un sémaphore que Mark a mentionné, pour enregistrer essentiellement le début et l'arrêt du traitement. Ensuite, vous pouvez avoir n'importe quelle quantité d'instances en cours d'exécution, chacun inspecter l'enregistrement du sémaphore et n'agissant que si le sémaphore le permet.

Cependant, la mise en garde ici est que ce qui se passe si l'une des instances se bloque au milieu de la transformation et ne libère jamais le sémaphore? Vous pouvez implémenter une valeur "timeout" après laquelle d'autres instances tenteront de commencer le traitement s'il n'ya pas eu un déverrouillage pour la quantité de temps x.

Alternativement, vous pouvez utiliser un service de surveillance tiers comme azurwatch pour surveiller les instances insensibles dans Azure et lancer un nouvelle instance si la quantité d'instances "prêtes" est inférieure à 1. Cela vous permettra d'enregistrer peut économiser de l'argent en ne faisant pas avoir à disposer de 2 instances et d'exécuter tout le temps, mais il y a un léger retard entre quand une instance échoue et quand un Un nouveau est commencé.


0 commentaires

0
votes

Une sémaphore comme suggéré serait la voie à suivre, bien que j'irais probablement avec un simple temps de coeur d'horodatage dans Blob Store.

L'autre pensée est, quelle est la nécessité? Si vos charges peuvent supporter d'être en panne pendant quelques minutes, laissez peut-être simplement le rôle de recycler?


0 commentaires

0
votes

Petite capture sur la solution de David. Re-poster le message à la file d'attente se produirait comme la dernière chose sur l'exécution actuelle de sorte que si la machine se bloque le long de la façon dont le message actuel expirerait et reformerait la file d'attente. Cela suppose que le message a été lancé à l'origine et nécessite une opération de file d'attente de la file d'attente. La désignation doit se produire avant d'insérer le nouveau message à la file d'attente. Si le rôle se bloque entre ces 2 opérations, il ne restera plus de jetons dans le système et sera arrêté. La vérification du dup ESB sonne comme une approche réalisable, mais elle ne semble pas que ce serait déterministe que le bus ne puisse rechercher que des messages identiques actuellement existants dans une file d'attente. Mais si l'un des messages vient juste après la mise en attente de la précédente, il est possible de retrouver 2 processus en parallèle.

Une solution alternative, si vous pouvez vous le permettre, ne serait jamais de désigner et de simplement louer le message via les opérations de peink. Vous devriez vous assurer que le délai d'invisibilité ne dépasse jamais le temps de traitement de votre rôle de travailleur. En ce qui concerne la création du jeton en premier lieu, la même stratégie de démarrage du rôle de travail décrit avant la combinaison avec la vérification DUP ASB devrait fonctionner (car les messages ne passeraient jamais de la file d'attente).


0 commentaires