Je viens de découvrir l'option de configuration CELERYD_PREFETCH_MULTIPLIER
( documents ). La valeur par défaut est 4, mais (je crois) je veux que la prélecture soit la plus faible possible. Je l'ai mis à 1 maintenant, ce qui est assez proche de ce que je recherche, mais il y a encore des choses que je ne comprends pas:
Pourquoi cette prélecture est-elle une bonne idée? Je ne vois pas vraiment de raison à cela, sauf s'il y a beaucoup de latence entre la file d'attente de messages et les travailleurs (dans mon cas, ils s'exécutent actuellement sur le même hôte et, au pire, pourraient éventuellement s'exécuter sur différents hôtes dans les mêmes données centre). La documentation ne mentionne que les inconvénients, mais ne parvient pas à expliquer quels sont les avantages.
Beaucoup de gens semblent mettre ce paramètre à 0, s'attendant à pouvoir désactiver la prélecture de cette façon (une hypothèse raisonnable à mon avis). Cependant, 0 signifie une prélecture illimitée. Pourquoi quelqu'un voudrait-il un prélecture illimité, cela n'élimine-t-il pas entièrement la simultanéité/asynchronicité pour laquelle vous avez introduit une file d'attente de tâches en premier lieu?
Pourquoi la prélecture ne peut-elle pas être désactivée? Ce n'est peut-être pas une bonne idée de désactiver les performances dans la plupart des cas, mais y a-t-il une raison technique pour que cela ne soit pas possible? Ou n'est-il simplement pas mis en œuvre?
Parfois, cette option est connectée à CELERY_ACKS_LATE
. Par exemple. Roger Hu écrit "[…] souvent ce que [les utilisateurs] veulent vraiment, c'est qu'un travailleur réserve uniquement autant de tâches qu'il y a de processus enfants. Mais cela n'est pas possible sans activer les accusés de réception tardifs […] "Je ne comprends pas comment ces deux options sont connectées et pourquoi l'une n'est pas possible sans l'autre. Une autre mention de la connexion peut être trouvée ici . Quelqu'un peut-il expliquer pourquoi les deux options sont liées?
La prélecture peut améliorer les performances. Les travailleurs n'ont pas besoin d'attendre le prochain message d'un courtier pour être traités. Communiquer avec un courtier une fois et traiter un grand nombre de messages améliore les performances. Obtenir un message d'un courtier (même local) coûte cher par rapport à l'accès à la mémoire locale. Les travailleurs sont également autorisés à accuser réception des messages par lots
La prérécupération définie sur zéro signifie "pas de limite spécifique" plutôt qu'illimité
La définition de la prélecture à 1 est documentée comme équivalant à la désactiver, mais ce n'est pas toujours le cas (voir https://stackoverflow.com/a/33357180/71522 )
La prélecture permet d'accepter les messages par lots. CELERY_ACKS_LATE = True empêche la reconnaissance des messages lorsqu'ils atteignent un travailleur
Vieille question, mais toujours en ajoutant ma réponse au cas où cela aiderait quelqu'un. Ma compréhension de certains tests initiaux était la même que celle de la réponse de David Wolever. Je viens de tester cela plus dans le céleri 3.1.19 et -Ofair
fonctionne. Juste qu'il n'est pas destiné à désactiver la prélecture au niveau du nœud de travail. Cela continuera de se produire. En utilisant -Ofair
a un effet différent qui est au niveau du travailleur de la piscine. En résumé, pour désactiver complètement la prélecture, procédez comme suit:
CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_ACKS_LATE = True
au niveau global ou au niveau de la tâche-Ofair
lors du démarrage des travailleursAjout de plus de détails:
J'ai constaté que le nœud de travail sera toujours prérécupéré par défaut. Vous pouvez uniquement contrôler le nombre de tâches qu'il prélève en utilisant CELERYD_PREFETCH_MULTIPLIER
. S'il est défini sur 1, il prélèvera uniquement autant de tâches que le nombre de travailleurs de pool (simultanéité) dans le nœud. Donc, si vous aviez concurrency = n, le nombre maximal de tâches prélues par le nœud sera n.
Sans le -Ofair
option, ce qui m'est arrivé, c'est que si l'un des processus de travail du pool exécutait une tâche de longue durée, les autres travailleurs du nœud arrêteraient également de traiter les tâches déjà prélues par le nœud. En utilisant -Ofair
, cela a changé. Même si l'un des travailleurs du nœud exécutait des tâches de longue durée, d'autres n'arrêtaient pas le traitement et continuaient à traiter les tâches prélues par le nœud. Je vois donc deux niveaux de prélecture. Un au niveau du nœud de travail. L'autre au niveau du travailleur individuel. En utilisant -Ofair
pour moi semblait le désactiver au niveau des travailleurs.
Comment est ACKS_LATE
en relation? . Je viens de réaliser que les messages prélus apparaissent sous "messages non reconnus" dans rabbitmq. Je ne suis donc pas sûr que le paramétrer sur ACKS_LATE = True
signifie que la tâche ne sera reconnue que lorsque la tâche réussira. Sinon, je suppose que cela arriverait quand il serait reçu par un travailleur. En cas de prélecture, la tâche est d'abord reçue par le travailleur (confirmée à partir des journaux) mais sera exécutée plus tardTrue
soit absolument nécessaire. De toute façon, nos tâches avaient été définies de cette façon (accusé de réception tardif) pour d'autres raisons.
Juste un avertissement: à partir de mes tests avec le courtier redis + Celery 3.1.15, tous les conseils que j'ai lus concernant la désactivation de la prélecture CELERYD_PREFETCH_MULTIPLIER = 1
Sont manifestement faux.
Pour le démontrer:
CELERYD_PREFETCH_MULTIPLIER = 1
time.sleep(5)
)Commencez à regarder la longueur de la file d'attente des tâches dans Redis: watch redis-cli -c llen default
Démarrer celery worker -c 1
5
À 3
CELERYD_PREFETCH_MULTIPLIER = 1
n'empêche pas la prélecture , il limite simplement la prélecture à 1 tâche par file d'attente.
-Ofair
, malgré ce que dit la documentation , également n'empêche pas la prélecture .
À moins de modifier le code source, je n'ai trouvé aucune méthode pour désactiver entièrement la prélecture.
Je ne peux pas commenter les réponses de David Wolever, car mon stackcred n'est pas assez élevé. J'ai donc encadré mon commentaire comme une réponse car j'aimerais partager mon expérience avec Celery 3.1.18 et un courtier Mongodb. J'ai réussi à arrêter la prélecture avec les éléments suivants:
CELERYD_PREFETCH_MULTIPLIER = 1
à la config céleriCELERY_ACKS_LATE = True
à la config céleri--concurrency=1 -Ofair
En laissant CELERY_ACKS_LATE à la valeur par défaut, le travailleur effectue toujours une prélecture. Tout comme l'OP, je ne saisis pas complètement le lien entre la prélecture et les accusés de réception tardifs. Je comprends ce que David dit "CELERY_ACKS_LATE = True empêche de reconnaître les messages lorsqu'ils atteignent un travailleur", mais je n'arrive pas à comprendre pourquoi les accusés de réception tardifs seraient incompatibles avec la prélecture. En théorie, une prélecture permettrait toujours d'acquitter tard à droite - même si elle n'est pas codée comme telle dans le céleri?