Celery: ¿La misma tarea se ejecuta varias veces a la vez?

Creado en 20 nov. 2017  ·  43Comentarios  ·  Fuente: celery/celery

El problema es un reenvío de una publicación desatendida de grupos de Google _¿La misma tarea se ejecuta varias veces?_

> ./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'}}

Mi aplicación programa un solo grupo de dos, a veces tres tareas, cada una de las cuales tiene su propio ETA dentro de una hora. Cuando llega la ETA, veo lo siguiente en mi registro de apio:

[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
…

Esto puede repetirse docenas de veces. Tenga en cuenta el tiempo de ejecución de 33 segundos de la primera tarea y el uso de diferentes trabajadores.

No tengo una explicación para este comportamiento, y me gustaría entender qué está pasando aquí.

Redis Broker Redis Results Backend Feedback Needed ✘ Needs Testcase ✘

Comentario más útil

@georgepsarakis Entonces, si la tarea está programada con mucha anticipación en el futuro, ¿entonces podría ver lo anterior? ¿El "tiempo de espera de visibilidad" aborda eso? De la documentación que vinculó:

El tiempo de espera de visibilidad predeterminado para Redis es de 1 hora.

Lo que significa que si dentro de la hora el trabajador no acusa la tarea (es decir, ¿la ejecuta?), esa tarea se envía a otro trabajador que no acusará, y así sucesivamente... De hecho, este parece ser el caso mirando la sección de advertencias de la documentación; este problema relacionado https://github.com/celery/kombu/issues/337; o citando de este blog :

Pero cuando los desarrolladores comienzan a usarlo, se enfrentan regularmente a un comportamiento anormal de los trabajadores, específicamente a la ejecución múltiple de la misma tarea por parte de varios trabajadores. La razón que lo causa es una configuración de tiempo de espera de visibilidad.

Parece que establecer visibility_timeout en 31 540 000 segundos (un año) podría ser una solución rápida.

Todos 43 comentarios

¿Quizás esto esté relacionado con el tiempo de espera de visibilidad ?

@georgepsarakis ¿Podría dar más detalles sobre su sospecha?

Hasta donde yo sé, este es un problema conocido para los transportes de intermediarios que no tienen las características de reconocimiento integradas de AMQP. La tarea se asignará a un nuevo trabajador si el tiempo de finalización de la tarea supera el tiempo de espera de visibilidad, por lo que es posible que vea que las tareas se ejecutan en paralelo.

@georgepsarakis Entonces, si la tarea está programada con mucha anticipación en el futuro, ¿entonces podría ver lo anterior? ¿El "tiempo de espera de visibilidad" aborda eso? De la documentación que vinculó:

El tiempo de espera de visibilidad predeterminado para Redis es de 1 hora.

Lo que significa que si dentro de la hora el trabajador no acusa la tarea (es decir, ¿la ejecuta?), esa tarea se envía a otro trabajador que no acusará, y así sucesivamente... De hecho, este parece ser el caso mirando la sección de advertencias de la documentación; este problema relacionado https://github.com/celery/kombu/issues/337; o citando de este blog :

Pero cuando los desarrolladores comienzan a usarlo, se enfrentan regularmente a un comportamiento anormal de los trabajadores, específicamente a la ejecución múltiple de la misma tarea por parte de varios trabajadores. La razón que lo causa es una configuración de tiempo de espera de visibilidad.

Parece que establecer visibility_timeout en 31 540 000 segundos (un año) podría ser una solución rápida.

Diría que si aumenta el tiempo de espera de visibilidad a 2 horas, sus tareas se ejecutarán solo una vez.

Así que si combinas:

  • corredor de redis
  • Acuse de recibo tardío
  • ETA igual/superior al tiempo de espera de visibilidad
    obtienes múltiples ejecuciones en la tarea.

Creo que lo que pasa es:

  • Después de que pasa una hora, un proceso de trabajo comienza a procesar la tarea.
  • Un segundo trabajador verá que este mensaje ha estado en la cola durante más tiempo que el tiempo de espera de visibilidad y lo está procesando otro trabajador.
  • El mensaje se restaura en la cola.
  • Otro trabajador comienza a procesar el mismo mensaje.
  • Lo anterior sucede para todos los procesos de trabajo.

Al observar la implementación del transporte de Redis, notará que usa conjuntos ordenados, pasando el tiempo en cola como una puntuación a zadd . El mensaje se restaura en función de esa marca de tiempo y se compara con un intervalo igual al tiempo de espera de visibilidad .

Espero que esto explique un poco el funcionamiento interno del transporte Redis.

@georgepsarakis , ahora estoy completamente confundido. Si la hora estimada de llegada de una tarea se establece para dentro de dos meses, ¿por qué un trabajador la recogería una hora después de que se hayan programado las tareas? ¿Me estoy perdiendo de algo?

Mi suposición (¿incorrecta?) es que:

  • Programo una tarea con una ETA en cualquier momento en el futuro; luego
  • la tarea (es decir, sus argumentos ordenados) y ETA se sentarán en la cola hasta que llegue ETA; luego
  • un trabajador comienza a procesar la tarea en ETA.

Su "_Creo que lo que sucede es:_" anterior es bastante diferente de mi suposición.

También encontré el mismo problema, ¿lo resolviste? @jenstroeger

¡Gracias!

@jenstroeger eso no suena como un flujo factible, creo que el trabajador simplemente vuelve a poner en cola el mensaje para posponer la ejecución hasta que finalmente se cumpla la condición de ETA. El concepto de la cola es distribuir mensajes tan pronto como lleguen, de modo que el trabajador examine el mensaje y simplemente vuelva a ponerlos en cola.

Tenga en cuenta que esta es mi suposición, no estoy realmente al tanto de los aspectos internos de la implementación de ETA.

@zivsu , como se mencionó anteriormente , configuré visibility_timeout en un número _muy_ grande y eso parece haber resuelto los síntomas. Sin embargo, como señala @georgepsarakis , ese parece ser un enfoque deficiente.

No sé la causa del problema original ni cómo abordarlo correctamente.

@jenstroeger Leí un blog, cambio visibility_timeout no puedo resolver el problema por completo, así que cambio mi borker a rabbitmq .

@zivsu , ¿puede compartir el enlace al blog? ¿Usaste Redis antes?

@jenstroeger No puedo encontrar el blog, usé Redis como corredor antes. Para la tarea programada, elijo rebbitmq para evitar que el error vuelva a ocurrir.

Tengo exactamente el mismo problema, mi configuración es:
django==1.11.6
apio==4.2rc2
django-apio-beat==1.0.1

ajustes:

CELERY_ENABLE_UTC = True
# CELERY_TIMEZONE = 'America/Los_Angeles'

Y esa es la única combinación que funciona de esta configuración. También tengo que programar mis tareas periódicas en la zona horaria UTC.
Si habilita CELERY_TIMEZONE o deshabilita CELERY_ENABLE_UTC , comienza a ejecutar tareas periódicas varias veces.

Tengo el problema de guardar. la tarea eta se ejecuta multiplicando veces cuando se usa redis como intermediario.
Alguna forma de resolver esto..
parece que el corredor de cambios de redis a rabbitmq resuelve este problema ...

Al usar redis, hay un problema bien conocido cuando especifica una zona horaria que no sea UTC. Para solucionar el problema, crea una subclase de la aplicación predeterminada y agrega tu propia función de manejo de zona horaria:

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)

Espero que ayude a cualquier otra persona que se encuentre con este problema.

A veces tengo este problema cuando reinicio con frecuencia trabajos de apio con ritmo en máquinas multinúcleo. Me he acostumbrado a ejecutar ps aux | grep celery y luego kill <each_pid> para resolverlo.

El mejor consejo que tengo es que siempre se asegure de ver el mensaje "reiniciar HECHO" antes de desconectarse de la máquina.

{"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 marcamos las marcas de tiempo de la tarea recibida, cada hora obtendrá una nueva tarea con la misma identificación. El resultado es que todos los mensajes de ETA se envían más de 10 veces. Parece que rabbitmq es la única opción si queremos usar ETA

Recientemente encontré un error similar. También ps aux | grep celery mostró más procesos que los que iniciaron los trabajadores, dos veces más. Agregar el parámetro --pool gevent al comando de lanzamiento de trabajadores de apio redujo el número de procesos al número exacto de trabajadores iniciados y ritmo de apio. Y ahora estoy viendo la ejecución de mis tareas.

¿Podría otra solución deshabilitar por completo la emulación ack? es decir "broker_transport_options": {"ack_emulation": False} . ¿Algún inconveniente para tareas de ejecución corta/cuenta atrás?

¿Alguien consiguió la solución?

He estado enfrentando el mismo problema, ¿alguna solución?

Chocando, el mismo problema.

Mismo problema aquí, usando Redis como intermediario.

$ 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

El mismo problema aqui. Apio versión 4.3.0
apio = Apio('tareas', broker='pyamqp://nosd:sdsd@rabbit//', config_from_object={"broker_transport_options":{'visibility_timeout': 18000}})

El comando que uso para ejecutar mi trabajador
apio -Un trabajador de tareas --pidfile=/tmp/celery_worker.pid -f=/tmp/celery_worker.log -Q celery_queue --loglevel=info --pool=solo --concurrency=1 -n worker_celery --detach -- sin-chismes --sin-mezclar --sin-latido

¿Puedes probar celery==4.4.0rc4?

El apio está recibiendo la misma tarea dos veces, con la misma identificación de tarea al mismo tiempo.
Aquí están los registros

[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

ambos se están ejecutando simultáneamente,

usando celery==4.4.0rc4 , boto3==1.9.232, kombu==4.6.6 con SQS en matraz pyhton.
en SQS, el tiempo de espera de visibilidad predeterminado es de 30 minutos, y mi tarea es no tener ETA y no confirmar.

trabajador corriendo como,
trabajador de apio -A app.jobs.run -l info --pidfile=/var/run/celery/celery.pid --logfile=/var/log/celery/celery.log --time-limit=7200 --concurrencia =8

@auvipy , cualquier ayuda sería genial.

¿Qué corredor y back-end de resultados está utilizando? ¿Puedes intentar cambiar a otro back-end?

¿Qué corredor y back-end de resultados está utilizando? ¿Puedes intentar cambiar a otro back-end?

usando SQS, el backend de resultados es MYSQL, con sqlalchemy.
los detalles están aquí en SO, https://stackoverflow.com/questions/59123536/celery-is-receiving-same-task-twice-with-same-task-id-at-same-time
@auvipy , ¿puedes echar un vistazo?

@thedrow , ¿te enfrentas a este problema en Bloomberg?

@nitish-itilite: ¿qué zona horaria estás usando para el apio?

@nitish-itilite: ¿qué zona horaria estás usando para el apio?

es UTC predeterminado. en metros cuadrados, la región es este EE. UU. Este (Norte de Virginia).

Tuve un caso similar ejecutando apio con SQS. Ejecuté una tarea ficticia con countdown=60 , mientras que el tiempo de espera de visibilidad en SQS es de 30 segundos. Esto es lo que obtengo:

NOTA: comencé con el apio con --concurrency=1 , por lo que hay dos subprocesos, ¿verdad?

[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

Lo que sucedió en orden cronológico:

  1. 14:46:32 se recibió la tarea y SQS la puso en modo inflight durante 30 segundos
  2. 14:47:02 se recibió la misma tarea porque expiró el tiempo de visibilidad
  3. 14:47:32 ambas tareas se ejecutan al mismo tiempo

Supongo que se trata de un error en Celery (?), Creo que debería haber verificado si ese trabajador ya tomó la identificación del mensaje ( b483a22f-31cc-4335-9709-86041baa8f05 ).

Tal vez podría haber una lista hash con todos los ID de mensajes, de modo que el apio pueda decidir si una tarea recibida es válida para su procesamiento. ¿Puede el apio hacer eso?

NOTA 2:
No podemos establecer un tiempo de espera de visibilidad demasiado largo, porque si el trabajador realmente muere, el mensaje tardaría demasiado en ser recogido por otro trabajador. Establecerlo demasiado bajo expondría esta condición.

Esto parece estar pasando a mí también.

[2020-05-11 15:31:23,673: INFO/MainProcess] Tarea recibida: ee_external_attributes.tasks. recrear_valores_específicos[53046bd7-2a19-4f72-808f-d712eaecb0e8]
[2020-05-11 15:31:28,673: INFO/MainProcess] Tarea recibida: ee_external_attributes.tasks.recreate_specific_values[53046bd7-2a19-4f72-808f-d712eaecb0e8]

(Ajusté el nombre de la tarea en los registros para la publicación pública).

Debido a las restricciones de unicidad, uno de mis trabajadores arroja un error a la mitad de la tarea y el otro tiene éxito.

intenté configurar
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
Eso resultó no ayudar.

Estoy usando
apio==4.4.1
django-apio-resultados==1.2.1

Y estoy usando AWS SQS para la cola.

yo tengo una teoria Aparentemente, mi configuración de "Tiempo de espera de visibilidad predeterminado" en mi cola solo se configuró en 5 segundos. Puede ser que el segundo trabajador haya retirado el trabajo mientras el primero estaba trabajando en él, porque asumió que el primer trabajador había muerto. Aumenté el tiempo de espera de visibilidad a 2 minutos y parece estar mejorando. Tenía muchas tareas que tomaban entre 8 y 12 segundos, por lo que 2 minutos pueden ser excesivos. Pero esperemos que eso lo solucione.

Puede ser que el segundo trabajador haya retirado el trabajo mientras el primero estaba trabajando en él, porque asumió que el primer trabajador había muerto.

@JulieGoldberg , esa sería una forma horrible de que Celery manejara los trabajos. Un trabajador de Celery nunca debe comenzar un trabajo que otro trabajador haya sacado de la cola y esté procesando activamente; Creo que eso estaría seriamente roto. (Pero es Celery, ya nada me sorprende 😒)

Tengo un problema similar con una aplicación que se ejecuta en Kubernetes. En la instancia de Kubernetes, tenemos 10 trabajadores (instancia de la aplicación de apio) que consumen las tareas de Redis.

Síntomas:
El trabajador de apio programa una tarea de ETA que se planificará después de 30 minutos. Si se rota el pod de Kubernetes (Kubernetes mata al trabajador) o se implementa una versión más nueva de la aplicación (se matan todos los trabajadores y se crean nuevos trabajadores), todos los trabajadores tomarán la tarea programada y comenzarán a ejecutarse en el tiempo definido.
Para el trabajador, traté de establecer diferentes valores de visibility_timeout durante varias horas hasta un año, pero el resultado seguía siendo el mismo. El mismo comportamiento se alcanzó con la configuración enable_utc = True , o una reducción de worker_prefetch_multiplier = 1 .

No sé si esto ayudará a alguien, pero este era mi problema:

Tenía tareas (generación de informes) que se ejecutaban cuando se cargaba una página a través de GET. Por alguna razón (algo relacionado con los favicons), Chrome enviaba 2 solicitudes GET en cada carga de página, activando la tarea dos veces.
Se supone que las solicitudes GET no tienen efectos secundarios, por lo que las convertí todas en formularios que usted envía y el problema se resolvió.

Puede ser que el segundo trabajador haya retirado el trabajo mientras el primero estaba trabajando en él, porque asumió que el primer trabajador había muerto.

@JulieGoldberg , esa sería una forma horrible de que Celery manejara los trabajos. Un trabajador de Celery nunca debe comenzar un trabajo que otro trabajador haya sacado de la cola y esté procesando activamente; Creo que eso estaría seriamente roto. (Pero es Celery, ya nada me sorprende 😒)

En lugar de quejarse, puede ayudarnos a solucionar el problema al encontrar una solución y un PR.

Tengo un problema similar con una aplicación que se ejecuta en Kubernetes. En la instancia de Kubernetes, tenemos 10 trabajadores (instancia de la aplicación de apio) que consumen las tareas de Redis.

Síntomas:
El trabajador de apio programa una tarea de ETA que se planificará después de 30 minutos. Si se rota el pod de Kubernetes (Kubernetes mata al trabajador) o se implementa una versión más nueva de la aplicación (se matan todos los trabajadores y se crean nuevos trabajadores), todos los trabajadores tomarán la tarea programada y comenzarán a ejecutarse en el tiempo definido.

@elMateso Enfrenté problemas similares con la implementación de Airflow en k8s (consumidores en pods y redis como cola). Pero pude hacer que la implementación fuera estable y funcionara como se esperaba, tal vez estos consejos te ayuden:
https://www.polidea.com/blog/application-scalability-kubernetes/#tips-for-hpa

Frente a lo mismo aquí.

No parece ser un problema con ninguna configuración de tiempo (tiempo de espera de visibilidad, ETA, etc.), al menos para mí. En el caso mío sucede microsegundos entre ejecuciones. No encontré cómo el apio, de hecho, ACK un mensaje, pero, si en rabbitMQ funciona perfectamente, parece ser un problema con la concurrencia y ACK en Redis.

Estoy viendo el mismo problema y también estamos usando Redis como intermediario. Cambiar a rabbitMQ no es una opción para nosotros.

¿Alguien ha intentado usar un bloqueo para asegurarse de que la tarea solo se ejecute una vez? ¿Podría eso funcionar?

por ejemplo, https://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring-a-task-is-only-ejecuted-one-to-a-time

@ErikKalkoken terminamos haciendo exactamente eso.

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

El código anterior no se usa para el apio, pero la ejecución múltiple del apio es la misma lógica, solo necesita obtener el task_id y configurar el caché. Hasta ahora está funcionando bien.

¿Fue útil esta página
0 / 5 - 0 calificaciones