2011-08-22 4 views
20

J'utilise Céleri avec RabbitMQ. Dernièrement, j'ai remarqué qu'un grand nombre de files d'attente temporaires sont faites. J'ai donc expérimenté et constaté que lorsqu'une tâche échoue (c'est-à-dire qu'une tâche déclenche une exception), une file d'attente temporaire avec un nom aléatoire (comme c76861943b0a4f3aaa6a99a6db06952c) est formée et la file d'attente reste.File d'attente temporaire en Céleri

Certaines propriétés de la file d'attente temporaire que l'on trouve dans rabbitmqadmin sont les suivantes -

auto_delete: True consommateurs: 0 durable: Faux messages: 1 messages_ready: 1

Et une telle file d'attente temporaire est fait à chaque fois qu'une tâche échoue (c'est-à-dire, déclenche une exception). Comment éviter cette situation? Parce que dans mon environnement de production, un grand nombre de files d'attente se forment.

+0

C'est une observation intéressante! Moi aussi je voudrais savoir. –

+1

Salut Elver. J'étais capable de résoudre le problème. S'il vous plaît jeter un oeil à la réponse (un par moi aussi bien). J'espère que cela aide. – Siddharth

Répondre

11

Eh bien, Philippe est là. Ce qui suit est une description de la façon dont je l'ai résolu. C'est une configuration dans celeryconfig.py. J'utilise toujours CELERY_BACKEND = "amqp" comme l'avait dit Philip. Mais en plus de cela, j'utilise maintenant CELERY_IGNORE_RESULT = True. Cette configuration assurera que les files d'attente supplémentaires ne sont pas formées pour chaque tâche.

J'utilisais déjà cette configuration mais quand une tâche échoue, la file d'attente supplémentaire s'est formée. Puis j'ai remarqué que j'utilisais une autre configuration qui devait être supprimée: CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True. Ce que cela a fait c'est qu'il n'a pas stocké les résultats pour toutes les tâches mais seulement pour les erreurs (tâches qui ont échoué) et donc une file d'attente supplémentaire pour une tâche qui a échoué.

+0

Wow! Cela a résolu pour moi. Je n'ai même pas réalisé que c'était un problème puisque je mettais ignore_result = True dans chaque descripteur de tâche. Mais j'ai ajouté CELERY_IGNORE_RESULT = True et CELERY_STORE_ERRORS_EVEN_IF_IGNORED = Faux et alto - plus de files d'attente supplémentaires après le traitement! Je pourrais toujours considérer redis comme un backend alternatif, mais c'est vraiment bien d'avoir trouvé cette solution. Je vous remercie! – chaimp

+0

@jeffp - Content d'entendre ça. J'ai aussi récemment utilisé Redis avec Celery - je ne pense pas que ce soit un problème avec ça. Le céleri lui-même forme et maintient la file d'attente. Donc cette configuration est importante. – Siddharth

+1

En fait, j'ai découvert une autre chose au cours de la journée qui, je pense, sera très utile pour quiconque lit ceci: Il est nécessaire d'avoir plus d'un travailleur et d'acheminer différentes tâches à chaque travailleur. Il est conseillé d'en apprendre davantage sur celeryd-multi et de l'utiliser. La documentation ne le rend pas évident, mais c'est la clé pour utiliser efficacement les ressources système disponibles et ne pas laisser la file d'attente être sauvegardée. – chaimp

16

Il semble que vous utilisiez l'amqp comme backend de résultats. De l'docs ici sont les pièges de cette configuration particulière:

  • Chaque nouvelle tâche crée une nouvelle file d'attente sur le serveur, avec des milliers de tâches que le courtier peut être surchargée avec les files d'attente et cela affectera
    performance de manière négative. Si vous utilisez RabbitMQ alors chaque file d'attente
    sera un processus Erlang séparé, donc si vous avez l'intention de
    garder de nombreux résultats en même temps que vous pourriez avoir à augmenter la limite de processus Erlang
    , et le nombre maximal de descripteurs de fichiers votre système d'exploitation
    permet
  • résultats anciens ne seront pas nettoyés automatiquement, vous devez donc vous assurer de consommer les résultats ou bien le nombre de files d'attente finalement hors de contrôle. Si vous exécutez RabbitMQ 2.1.1 ou plus haut, vous pouvez tirer parti de l'argument x-expires aux files d'attente, qui expirera les files d'attente après un certain délai après qu'elles soient inutilisées. L'expiration de la file d'attente peut être définie (en secondes) par le paramètre CELERY_AMQP_TASK_RESULT_EXPIRES (non activé par défaut).

D'après ce que je l'ai lu dans le changelog, ce n'est plus le back-end par défaut dans les versions> = 2.3.0 parce que les utilisateurs recevaient peu à l'arrière par ce comportement. Je suggérerais de changer les résultats si ce n'est pas la fonctionnalité dont vous avez besoin.

+0

CELERY_AMQP_TASK_RESULT_EXPIRES a été abandonné, CELERY_TASK_RESULT_EXPIRES est le nouveau nom du paramètre de configuration. La valeur par défaut est maintenant de l'enregistrer pendant 1 jour, le mettre à 0 signifie garder pour toujours. – cbron

3

CELERY_TASK_RESULT_EXPIRES détermine l'heure de vie des files d'attente temporaires. La valeur par défaut est 1 jour. Vous pouvez modifier cette valeur.

0

La raison pour laquelle cela se produit est parce que celery workers remote control est activé (il est activé par défaut).

Vous pouvez le désactiver en définissant le paramètre CELERY_ENABLE_REMOTE_CONTROL False Cependant, notez que vous perdrez la possibilité de faire des choses comme add_consumer, cancel_consumer etc en utilisant le backend celery command

0

amqp crée une nouvelle file d'attente pour chaque tâche. Si vous voulez l'éviter, vous pouvez utiliser le backend rpc qui conserve les résultats dans une seule file d'attente.

Dans votre configuration, définissez

CELERY_RESULT_BACKEND = 'rpc' 
CELERY_RESULT_PERSISTENT = True 

Vous pouvez en savoir plus sur this on celery docs.

Questions connexes