Celery: La même tâche s'exécute plusieurs fois à la fois ?

Créé le 20 nov. 2017  ·  43Commentaires  ·  Source: celery/celery

Le problème est une republication d'une publication de groupes Google sans surveillance _La même tâche s'exécute plusieurs fois ?_

> ./bin/celery -A celery_app report

software -> celery:4.1.0 (latentcall) kombu:4.1.0 py:3.6.1
            billiard:3.5.0.3 redis:2.10.6
platform -> system:Linux arch:64bit, ELF imp:CPython
loader   -> celery.loaders.app.AppLoader
settings -> transport:redis results:redis://localhost:6379/2

broker_url: 'redis://localhost:6379/2'
result_backend: 'redis://localhost:6379/2'
task_serializer: 'json'
result_serializer: 'json'
accept_content: ['json']
timezone: 'Europe/Berlin'
enable_utc: True
imports: 'tasks'
task_routes: {
 'tasks': {'queue': 'celery-test-queue'}}

Mon application planifie un seul groupe de deux, parfois trois tâches, chacune avec sa propre ETA dans l'heure. Lorsque l'ETA arrive, je vois ce qui suit dans mon journal de céleri :

[2017-11-20 09:55:34,470: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 33.81780316866934s: None
[2017-11-20 09:55:34,481: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.009824380278587341s: None
[2017-11-20 09:55:34,622: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.14010038413107395s: None
…
[2017-11-20 09:55:37,890: INFO/ForkPoolWorker-8] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.012678759172558784s: None
[2017-11-20 09:55:37,891: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.01177949644625187s: None
[2017-11-20 09:55:37,899: INFO/ForkPoolWorker-8] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.008250340819358826s: None
…

Cela peut se répéter des dizaines de fois. Notez le temps d'exécution de 33 secondes de la première tâche et l'utilisation de différents ouvriers !

Je n'ai aucune explication à ce comportement et j'aimerais comprendre ce qui se passe ici.

Redis Broker Redis Results Backend Feedback Needed ✘ Needs Testcase ✘

Commentaire le plus utile

@georgepsarakis Donc, si la tâche est planifiée loin dans le futur, alors je pourrais voir ce qui précède ? Le "délai de visibilité" résout cela ? À partir de la documentation que vous avez liée :

Le délai de visibilité par défaut pour Redis est de 1 heure.

Cela signifie que si dans l'heure le travailleur n'acquitte pas la tâche (c'est-à-dire l'exécute ?), cette tâche est envoyée à un autre travailleur qui ne répondra pas, et ainsi de suite… En effet, cela semble être le cas en regardant la section des mises en garde de La documentation; ce problème connexe https://github.com/celery/kombu/issues/337 ; ou en citant ce blog :

Mais lorsque les développeurs commencent à peine à l'utiliser, ils sont régulièrement confrontés à des comportements anormaux des travailleurs, en particulier l'exécution multiple de la même tâche par plusieurs travailleurs. La raison qui en est la cause est un paramètre de délai de visibilité.

On dirait que régler le visibility_timeout sur 31 540 000 secondes (un an) pourrait être une solution rapide.

Tous les 43 commentaires

Peut-être est-ce lié au délai de visibilité ?

@georgepsarakis Pourriez-vous, s'il vous plaît, préciser vos soupçons ?

Autant que je sache, il s'agit d'un problème connu pour les transports de courtiers qui n'ont pas de caractéristiques d'accusé de réception intégrées d'AMQP. La tâche sera affectée à un nouveau travailleur si le temps d'achèvement de la tâche dépasse le délai de visibilité, vous pouvez donc voir des tâches exécutées en parallèle.

@georgepsarakis Donc, si la tâche est planifiée loin dans le futur, alors je pourrais voir ce qui précède ? Le "délai de visibilité" résout cela ? À partir de la documentation que vous avez liée :

Le délai de visibilité par défaut pour Redis est de 1 heure.

Cela signifie que si dans l'heure le travailleur n'acquitte pas la tâche (c'est-à-dire l'exécute ?), cette tâche est envoyée à un autre travailleur qui ne répondra pas, et ainsi de suite… En effet, cela semble être le cas en regardant la section des mises en garde de La documentation; ce problème connexe https://github.com/celery/kombu/issues/337 ; ou en citant ce blog :

Mais lorsque les développeurs commencent à peine à l'utiliser, ils sont régulièrement confrontés à des comportements anormaux des travailleurs, en particulier l'exécution multiple de la même tâche par plusieurs travailleurs. La raison qui en est la cause est un paramètre de délai de visibilité.

On dirait que régler le visibility_timeout sur 31 540 000 secondes (un an) pourrait être une solution rapide.

Je dirais que si vous augmentez le délai de visibilité à 2 heures, vos tâches ne seront exécutées qu'une seule fois.

Donc si vous combinez :

  • Courtier Redis
  • Accusé de réception tardif
  • ETA égal/supérieur au délai de visibilité
    vous obtenez plusieurs exécutions sur la tâche.

Je pense que ce qui se passe est:

  • Au bout d'une heure, un processus de travail commence à traiter la tâche.
  • Un deuxième travailleur verra que ce message est dans la file d'attente depuis plus longtemps que le délai de visibilité et est en cours de traitement par un autre travailleur.
  • Le message est restauré dans la file d'attente.
  • Un autre travailleur commence à traiter le même message.
  • Ce qui précède se produit pour tous les processus de travail.

En regardant dans l'implémentation du transport Redis, vous remarquerez qu'il utilise des ensembles triés, en passant le temps de la file d'attente comme un score à zadd . Le message est restauré en fonction de cet horodatage et en le comparant à un intervalle égal au délai de visibilité .

J'espère que cela explique un peu les rouages ​​du transport Redis.

@georgepsarakis , je suis maintenant complètement confus. Si l'ETA d'une tâche est définie pour deux mois à partir de maintenant, pourquoi un travailleur la récupérerait-il une heure après la planification des tâches ? Est-ce que je manque quelque chose?

Mon hypothèse (incorrecte ?) est que :

  • Je planifie une tâche avec une ETA à tout moment dans le futur ; ensuite
  • la tâche (c'est-à-dire ses arguments rassemblés) et ETA resteront dans la file d'attente jusqu'à ce qu'ETA arrive ; ensuite
  • un travailleur commence à traiter la tâche à ETA.

Votre "_Je pense que ce qui se passe est :_" ci-dessus est assez différent de mon hypothèse.

J'ai également rencontré le même problème, l'avez-vous résolu ? @jenstroeger

Merci!

@jenstroeger cela ne ressemble pas à un flux réalisable, je pense que le travailleur remet continuellement le message en file d'attente afin de reporter l'exécution jusqu'à ce que la condition ETA soit enfin remplie. Le concept de la file d'attente consiste à distribuer les messages dès qu'ils arrivent, de sorte que le travailleur examine le message et se contente de le remettre en file d'attente.

Veuillez noter que c'est ma supposition, je ne suis pas vraiment au courant des éléments internes de la mise en œuvre de l'ETA.

@zivsu , comme mentionné ci-dessus , j'ai défini le visibility_timeout sur un très grand nombre et cela semble avoir résolu les symptômes. Cependant, comme le souligne @georgepsarakis , cela semble être une mauvaise approche.

Je ne connais pas la cause du problème d'origine ni comment le résoudre correctement.

@jenstroeger J'ai lu un blog, changer visibility_timeout ne peut pas résoudre complètement le problème, alors je change mon borker en rabbitmq .

@zivsu , pouvez-vous s'il vous plaît partager le lien vers le blog ? Avez-vous déjà utilisé Redis ?

@jenstroeger Je ne trouve pas le blog, j'ai déjà utilisé Redis comme courtier. Pour la tâche planifiée, je choisis rebbitmq pour éviter que l'erreur ne se reproduise.

J'ai exactement le même problème, ma config est la suivante :
Django==1.11.6
céleri==4.2rc2
django-celeri-beat==1.0.1

réglages:

CELERY_ENABLE_UTC = True
# CELERY_TIMEZONE = 'America/Los_Angeles'

Et c'est la seule combinaison de travail de ces paramètres. Je dois également programmer mes tâches périodiques dans le fuseau horaire UTC.
Si vous activez CELERY_TIMEZONE ou désactivez CELERY_ENABLE_UTC , il commence à exécuter des tâches périodiques plusieurs fois.

J'ai le problème de sauvegarde. la tâche eta s'exécute plusieurs fois lors de l'utilisation de redis en tant que courtier.
aucun moyen de résoudre ce problème ..
ressembler à changer de courtier de redis à rabbitmq résoudre ce problème ..

En utilisant redis, il existe un problème bien connu lorsque vous spécifiez un fuseau horaire autre que UTC. Pour contourner le problème, sous-classez l'application par défaut et ajoutez votre propre fonction de gestion du fuseau horaire :

from celery import Celery


class MyAppCelery(Celery):
    def now(self):
        """Return the current time and date as a datetime."""
        from datetime import datetime
        return datetime.now(self.timezone)

J'espère que cela aide quelqu'un d'autre qui rencontre ce problème.

J'ai parfois ce problème lorsque je redémarre fréquemment des travaux de céleri avec battement sur des machines multicœurs. J'ai pris l'habitude d'exécuter ps aux | grep celery puis kill <each_pid> pour le résoudre.

Le meilleur conseil que j'ai est de toujours vous assurer que vous voyez le message "restart DONE" avant de vous déconnecter de la machine.

{"log":"INFO 2018-10-09 17:41:08,468 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T17:41:08.468912644Z"}
{"log":"INFO 2018-10-09 17:41:08,468 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T17:41:08.468955918Z"}
{"log":"INFO 2018-10-09 19:46:04,293 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T19:46:04.293780045Z"}
{"log":"INFO 2018-10-09 19:46:04,293 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T19:46:04.293953621Z"}
{"log":"INFO 2018-10-09 20:46:04,802 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T20:46:04.802819711Z"}
{"log":"INFO 2018-10-09 20:46:04,802 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T20:46:04.802974829Z"}
{"log":"INFO 2018-10-09 21:46:05,335 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T21:46:05.336081133Z"}
{"log":"INFO 2018-10-09 21:46:05,335 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T21:46:05.336107517Z"}
{"log":"INFO 2018-10-09 22:46:05,900 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T22:46:05.901078395Z"}
{"log":"INFO 2018-10-09 22:46:05,900 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T22:46:05.901173663Z"}
{"log":"INFO 2018-10-09 23:46:06,484 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T23:46:06.485276904Z"}
{"log":"INFO 2018-10-09 23:46:06,484 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T23:46:06.485415253Z"}
{"log":"INFO 2018-10-10 00:46:07,072 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T00:46:07.072529828Z"}
{"log":"INFO 2018-10-10 00:46:07,072 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T00:46:07.072587887Z"}
{"log":"INFO 2018-10-10 01:46:07,602 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T01:46:07.60325321Z"}
{"log":"INFO 2018-10-10 01:46:07,602 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T01:46:07.603327426Z"}
{"log":"INFO 2018-10-10 02:46:08,155 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T02:46:08.155868992Z"}
{"log":"INFO 2018-10-10 02:46:08,155 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T02:46:08.155921893Z"}
{"log":"INFO 2018-10-10 03:46:08,753 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T03:46:08.75401387Z"}
{"log":"INFO 2018-10-10 03:46:08,753 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T03:46:08.754056891Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.013548928Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.013592318Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:71\n","stream":"stderr","time":"2018-10-10T04:00:00.014000106Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:71\n","stream":"stderr","time":"2018-10-10T04:00:00.014167558Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:64\n","stream":"stderr","time":"2018-10-10T04:00:00.014661348Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:64\n","stream":"stderr","time":"2018-10-10T04:00:00.014684354Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.01514884Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.015249646Z"}
{"log":"DEBUG 2018-10-10 04:00:00,015 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:66\n","stream":"stderr","time":"2018-10-10T04:00:00.01571124Z"}
{"log":"DEBUG 2018-10-10 04:00:00,015 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:66\n","stream":"stderr","time":"2018-10-10T04:00:00.01580249Z"}
{"log":"DEBUG 2018-10-10 04:00:00,019 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:68\n","stream":"stderr","time":"2018-10-10T04:00:00.019260948Z"}
{"log":"DEBUG 2018-10-10 04:00:00,019 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:68\n","stream":"stderr","time":"2018-10-10T04:00:00.019322151Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.245159563Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.245177267Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:67\n","stream":"stderr","time":"2018-10-10T04:00:00.245338722Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:67\n","stream":"stderr","time":"2018-10-10T04:00:00.245351289Z"}
{"log":"DEBUG 2018-10-10 04:00:00,256 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.256770035Z"}
{"log":"DEBUG 2018-10-10 04:00:00,256 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.256788689Z"}
{"log":"INFO 2018-10-10 04:00:00,371 trace celery.app.trace 68 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.35710329699213617s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.371967002Z"}
{"log":"INFO 2018-10-10 04:00:00,371 trace celery.app.trace 68 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.35710329699213617s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.371983293Z"}
{"log":"INFO 2018-10-10 04:00:00,387 trace celery.app.trace 69 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.10637873200175818s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.388119538Z"}
{"log":"INFO 2018-10-10 04:00:00,387 trace celery.app.trace 69 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.10637873200175818s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.388166317Z"}
{"log":"INFO 2018-10-10 04:00:00,404 trace celery.app.trace 70 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.16254851799749304s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.404834545Z"}
{"log":"INFO 2018-10-10 04:00:00,404 trace celery.app.trace 70 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.16254851799749304s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.404862208Z"}
{"log":"INFO 2018-10-10 04:00:00,421 trace celery.app.trace 65 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.1654666289978195s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.421607856Z"}
{"log":"INFO 2018-10-10 04:00:00,421 trace celery.app.trace 65 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.1654666289978195s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.421674687Z"}
{"log":"INFO 2018-10-10 04:00:00,438 trace celery.app.trace 67 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.19588526099687442s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.438295459Z"}
{"log":"INFO 2018-10-10 04:00:00,438 trace celery.app.trace 67 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.19588526099687442s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.438311386Z"}
...

si nous vérifions les horodatages des tâches reçues, toutes les heures, une nouvelle tâche avec le même identifiant sera obtenue. Le résultat est que tous les messages ETA sont envoyés plus de 10 fois. On dirait que rabbitmq n'est qu'une option si nous voulons utiliser ETA

Rencontrer récemment un bogue similaire. De plus, ps aux | grep celery a montré plus de processus que de travailleurs démarrés, soit deux fois plus. L'ajout du paramètre --pool gevent à la commande de lancement des travailleurs de céleri a réduit le nombre de processus au nombre exact de travailleurs démarrés et de battement de céleri. Et maintenant, je regarde l'exécution de mes tâches.

Une autre solution pourrait-elle désactiver complètement l'émulation ack? c'est-à-dire "broker_transport_options": {"ack_emulation": False} . Des inconvénients pour les tâches/comptes à rebours courts ?

Quelqu'un a-t-il trouvé la solution ?

Avez-vous été confronté au même problème, avez-vous une solution?

Bouger, même problème.

Même problème ici, en utilisant Redis comme courtier.

$ pipenv graph --bare | grep -i "redis\|celery"                                                                                                                                                                                                                              
---
channels-redis==2.4.0
  - aioredis [required: ~=1.0, installed: 1.3.0]
    - hiredis [required: Any, installed: 1.0.0]
django-celery-beat==1.5.0
django-celery-results==1.1.2
  - celery [required: >=4.3,<5.0, installed: 4.3.0]
  - celery [required: >=3.1.0, installed: 4.3.0]
  - pylint-celery [required: ==0.3, installed: 0.3]
redis==3.2.1

Même problème ici. Céleri version 4.3.0
céleri = Céleri('tâches', broker='pyamqp://nosd:sdsd@rabbit//', config_from_object={"broker_transport_options":{'visibility_timeout' : 18000}})

La commande que j'utilise pour exécuter mon worker
celery -A tâches worker --pidfile=/tmp/celery_worker.pid -f=/tmp/celery_worker.log -Q celery_queue --loglevel=info --pool=solo --concurrency=1 -n worker_celery --detach -- sans-commérage --sans-mélange --sans-battement de coeur

pouvez-vous essayer le céleri==4.4.0rc4 ?

Le céleri reçoit la même tâche deux fois, avec le même identifiant de tâche en même temps.
Voici les journaux

[2019-11-29 08:07:35,464: INFO/MainProcess] Received task: app.jobs.booking.bookFlightTask[657985d5-c3a3-438d-a524-dbb129529443]  
[2019-11-29 08:07:35,465: INFO/MainProcess] Received task: app.jobs.booking.bookFlightTask[657985d5-c3a3-438d-a524-dbb129529443]  
[2019-11-29 08:07:35,471: WARNING/ForkPoolWorker-4] in booking funtion1
[2019-11-29 08:07:35,473: WARNING/ForkPoolWorker-3] in booking funtion1
[2019-11-29 08:07:35,537: WARNING/ForkPoolWorker-3] book_request_pp
[2019-11-29 08:07:35,543: WARNING/ForkPoolWorker-4] book_request_pp

les deux fonctionnent simultanément,

en utilisant céleri==4.4.0rc4 , boto3==1.9.232, kombu==4.6.6 avec SQS dans un flacon pyhton.
dans SQS, le délai d'attente de visibilité par défaut est de 30 minutes, et ma tâche n'a pas d'ETA ni d'accusé de réception.

courir travailleur comme,
celery worker -A app.jobs.run -l info --pidfile=/var/run/celery/celery.pid --logfile=/var/log/celery/celery.log --time-limit=7200 --concurrency =8

@auvipy , toute aide serait formidable.

quel courtier et back-end de résultats utilisez-vous ? pouvez-vous essayer de passer à un autre backend ?

quel courtier et back-end de résultats utilisez-vous ? pouvez-vous essayer de passer à un autre backend ?

en utilisant SQS, le backend de résultat est MYSQL, avec sqlalchemy.
les détails sont ici sur SO, https://stackoverflow.com/questions/59123536/celery-is-receiving-same-task-twice-with-same-task-id-at-same-time
@auvipy pouvez-vous s'il vous plaît jeter un oeil.

@thedrow êtes-vous confronté à ce problème à Bloomberg ?

@nitish-itilite : quel fuseau horaire utilisez-vous pour le céleri ?

@nitish-itilite : quel fuseau horaire utilisez-vous pour le céleri ?

c'est l'UTC par défaut. en sqs , la région est cette USA Est (Virginie du Nord).

J'ai eu un cas similaire avec du céleri avec SQS. J'ai exécuté une tâche factice avec countdown=60 , tandis que le délai de visibilité dans SQS est de 30 secondes. Voici ce que j'obtiens :

REMARQUE : j'ai commencé le céleri avec --concurrency=1 , il y a donc deux fils, n'est-ce pas ?

[2020-02-18 14:46:32 +0000] [INFO] Received task: notification[b483a22f-31cc-4335-9709-86041baa8f05]  ETA:[2020-02-18 14:47:31.898563+00:00] 
[2020-02-18 14:47:02 +0000] [INFO] Received task: notification[b483a22f-31cc-4335-9709-86041baa8f05]  ETA:[2020-02-18 14:47:31.898563+00:00] 
[2020-02-18 14:47:32 +0000] [INFO] Task notification[b483a22f-31cc-4335-9709-86041baa8f05] succeeded in 0.012232275999849662s: None
[2020-02-18 14:47:32 +0000] [INFO] Task notification[b483a22f-31cc-4335-9709-86041baa8f05] succeeded in 0.012890915997559205s: None

Ce qui s'est passé dans l'ordre chronologique :

  1. 14:46:32 la tâche a été reçue et SQS l'a mise en mode inflight pendant 30 secondes
  2. 14:47:02 la même tâche a été reçue, car le délai de visibilité a expiré
  3. 14:47:32 les deux tâches sont exécutées en même temps

Je suppose qu'il s'agit d'un bogue dans Celery (?), Je pense qu'il aurait dû vérifier si l'identifiant du message ( b483a22f-31cc-4335-9709-86041baa8f05 ) a déjà été pris par ce travailleur.

Peut-être qu'il pourrait y avoir une liste de hachage avec tous les identifiants de message, afin que le céleri puisse décider si une tâche reçue est valide pour le traitement. Le céleri peut-il faire ça ?

NOTE 2:
Nous ne pouvons pas définir un délai de visibilité trop long, car si le travailleur meurt réellement, le message mettrait trop de temps à être capté par un autre travailleur. Un réglage trop bas exposerait cette condition.

Cela semble m'arriver aussi.

[2020-05-11 15:31:23,673 : INFO/MainProcess] Tâche reçue : ee_external_attributes.tasks. recréer_des_valeurs_spécifiques[53046bd7-2a19-4f72-808f-d712eaecb0e8]
[2020-05-11 15:31:28,673 : INFO/MainProcess] Tâche reçue : ee_external_attributes.tasks.recreate_specific_values[53046bd7-2a19-4f72-808f-d712eaecb0e8]

(J'ai modifié le nom de la tâche dans les journaux pour la publication publique.)

En raison de contraintes d'unicité, l'un de mes travailleurs génère une erreur au cours de la tâche et l'autre réussit.

j'ai essayé de régler
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
Cela s'est avéré ne pas aider.

j'utilise
céleri==4.4.1
django-celeri-results==1.2.1

Et j'utilise AWS SQS pour la file d'attente.

J'ai une théorie. Apparemment, mon paramètre "Délai de visibilité par défaut" sur ma file d'attente n'était défini que sur 5 secondes. Il se peut que le deuxième travailleur ait retiré le travail pendant que le premier y travaillait, car il supposait que le premier travailleur était décédé. J'ai augmenté le délai de visibilité à 2 minutes et cela semble aller mieux. J'avais beaucoup de tâches qui prenaient 8 à 12 secondes, donc 2 minutes peuvent être exagérées. Mais j'espère que cela résout le problème.

Il se peut que le deuxième travailleur ait retiré le travail pendant que le premier y travaillait, car il supposait que le premier travailleur était décédé.

@JulieGoldberg , ce serait une mauvaise façon pour Celery de gérer les travaux. Un travailleur Celery ne doit jamais commencer un travail qu'un autre travailleur a retiré de la file d'attente et est en train de traiter activement ; pense que ce serait sérieusement cassé. (Mais c'est Céleri, je ne m'étonne plus de rien 😒)

J'ai un problème similaire avec une application qui s'exécute dans Kubernetes. Dans l'instance Kubernetes, nous avons 10 travailleurs (instance d'application de céleri) qui consomment les tâches de Redis.

Symptômes:
Le travailleur du céleri planifie une tâche ETA qui sera planifiée après 30 minutes. Si le pod Kubernetes est tourné (le travailleur est tué par Kubernetes) ou si une version plus récente de l'application est déployée (tous les travailleurs sont tués et de nouveaux travailleurs sont créés), tous les travailleurs prendront la tâche planifiée et commenceront à s'exécuter dans le délai défini.
Pour le travailleur, j'ai essayé de définir différentes valeurs de visibility_timeout pendant plusieurs heures jusqu'à un an, mais le résultat était toujours le même. Le même comportement a été atteint avec le paramètre enable_utc = True , soit une réduction de worker_prefetch_multiplier = 1 .

Je ne sais pas si cela aidera quelqu'un mais c'était mon problème:

J'avais des tâches (génération de rapports) qui étaient exécutées lorsqu'une page était chargée via GET. Pour une raison quelconque (quelque chose à voir avec les favicons), Chrome enverrait 2 requêtes GET à chaque chargement de page, déclenchant la tâche deux fois.
Les requêtes GET sont censées être sans effet secondaire, donc je les ai toutes transformées en formulaires que vous soumettez et le problème a été résolu.

Il se peut que le deuxième travailleur ait retiré le travail pendant que le premier y travaillait, car il supposait que le premier travailleur était décédé.

@JulieGoldberg , ce serait une mauvaise façon pour Celery de gérer les travaux. Un travailleur Celery ne doit jamais commencer un travail qu'un autre travailleur a retiré de la file d'attente et est en train de traiter activement ; pense que ce serait sérieusement cassé. (Mais c'est Céleri, je ne m'étonne plus de rien 😒)

Au lieu de vous plaindre, vous pouvez nous aider à résoudre le problème en proposant une solution et un PR.

J'ai un problème similaire avec une application qui s'exécute dans Kubernetes. Dans l'instance Kubernetes, nous avons 10 travailleurs (instance d'application de céleri) qui consomment les tâches de Redis.

Symptômes:
Le travailleur du céleri planifie une tâche ETA qui sera planifiée après 30 minutes. Si le pod Kubernetes est tourné (le travailleur est tué par Kubernetes) ou si une version plus récente de l'application est déployée (tous les travailleurs sont tués et de nouveaux travailleurs sont créés), tous les travailleurs prendront la tâche planifiée et commenceront à s'exécuter dans le délai défini.

@elMateso J'ai rencontré des problèmes similaires avec le déploiement d'Airflow sur k8 (consommateurs sur pods et redis en file d'attente). Mais j'ai pu rendre le déploiement stable et fonctionner comme prévu, peut-être que ces conseils vous aideront :
https://www.polidea.com/blog/application-scalability-kubernetes/#tips-for-hpa

Face au même ici.

Cela ne semble pas être un problème avec n'importe quelle configuration de synchronisation (délai de visibilité, ETA, etc.), pour moi du moins. Dans mon cas, il se passe des microsecondes entre les exécutions. Je n'ai pas trouvé comment le céleri acquitte en fait un message, mais si, dans rabbitMQ, cela fonctionne parfaitement, il semble y avoir un problème de concurrence et ACK dans Redis.

Je vois le même problème et nous utilisons également Redis comme courtier. Passer à rabbitMQ n'est pas une option pour nous.

Est-ce que quelqu'un a essayé d'utiliser un verrou pour s'assurer que la tâche n'est exécutée qu'une seule fois. Cela pourrait-il fonctionner ?

par exemple https://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring -a-task-is-only-executed-one-at-a-time

@ErikKalkoken, nous finissons par faire exactement cela.

def semaphore(fn):
    @wraps(fn)
    def wrapper(self_origin, *args, **kwargs):
        cache_name = f"{UID}-{args[0].request.id}-semaphore"
        agreement_redis = AgreementsRedis()
        if not agreement_redis.redis.set(cache_name, "", ex=30, nx=True):
          Raise Exception("...")
        try:
            return fn(self_origin, *args, **kwargs)
        finally:
            agreement_redis.redis.delete(cache_name)

    return wrapper

Le code ci-dessus n'est pas utilisé pour le céleri, mais l'exécution multiple du céleri est la même logique, il vous suffit d'obtenir le task_id et de définir le cache. Jusqu'à présent fonctionne bien.

Cette page vous a été utile?
0 / 5 - 0 notes