Me acabo de enterar de la opción de configuración CELERYD_PREFETCH_MULTIPLIER
( documentos ). El valor predeterminado es 4, pero (creo) quiero que la captación previa esté desactivada o lo más baja posible. Lo configuré en 1 ahora, que está lo suficientemente cerca de lo que estoy buscando, pero todavía hay algunas cosas que no entiendo:
¿Por qué esta búsqueda previa es una buena idea? Realmente no veo una razón para ello, a menos que haya mucha latencia entre la cola de mensajes y los trabajadores (en mi caso, actualmente se están ejecutando en el mismo host y, en el peor de los casos, podrían eventualmente ejecutarse en diferentes hosts en los mismos datos centrar). La documentación solo menciona las desventajas, pero no explica cuáles son las ventajas.
Mucha gente parece establecer esto en 0, esperando poder desactivar la captación previa de esa manera (una suposición razonable en mi opinión). Sin embargo, 0 significa captura previa ilimitada. ¿Por qué alguien querría una búsqueda previa ilimitada? ¿No elimina eso por completo la concurrencia / asincronicidad para la que introdujo una cola de tareas en primer lugar?
¿Por qué no se puede desactivar la captación previa? Puede que no sea una buena idea que el rendimiento lo desactive en la mayoría de los casos, pero ¿hay alguna razón técnica para que esto no sea posible? ¿O simplemente no está implementado?
A veces, esta opción está conectada a
CELERY_ACKS_LATE
. Por ejemplo. Roger Hu escribe «[…] a menudo lo que [los usuarios] realmente quieren es que un trabajador solo reserve tantas tareas como procesos secundarios haya. Pero esto no es posible sin habilitar los reconocimientos tardíos […] »No entiendo cómo están conectadas estas dos opciones y por qué una no es posible sin la otra. Aquí se puede encontrar otra mención de la conexión . ¿Alguien puede explicar por qué las dos opciones están conectadas?
CELERYD_PREFETCH_MULTIPLIER = 1
hace no la obtención previa de bloqueo. Simplemente, como su nombre indica, solo precarga una tarea a la vez.Pregunta anterior, pero aún agrego mi respuesta en caso de que ayude a alguien. Mi comprensión de algunas pruebas iniciales fue la misma que la de la respuesta de David Wolever. Acabo de probar esto más en apio 3.1.19 y
-Ofair
funciona. Solo que no está destinado a deshabilitar la captación previa en el nivel del nodo de trabajo. Eso seguirá sucediendo. El uso-Ofair
tiene un efecto diferente que se encuentra en el nivel del trabajador de la piscina. En resumen, para deshabilitar la captación previa por completo, haga lo siguiente:CELERYD_PREFETCH_MULTIPLIER = 1
CELERY_ACKS_LATE = True
a nivel global o nivel de tarea-Ofair
al iniciar los trabajadoresAñadiendo algunos detalles más:
Descubrí que el nodo trabajador siempre se buscará previamente de forma predeterminada. Solo puede controlar la cantidad de tareas que solicita previamente mediante
CELERYD_PREFETCH_MULTIPLIER
. Si se establece en 1, solo precargará tantas tareas como el número de trabajadores del grupo (simultaneidad) en el nodo. Entonces, si tenía concurrencia = n, el número máximo de tareas precargadas por el nodo será n.Sin la
-Ofair
opción, lo que me sucedió fue que si uno de los procesos de trabajo del grupo estaba ejecutando una tarea de ejecución prolongada, los otros trabajadores del nodo también dejarían de procesar las tareas que ya había obtenido previamente. Al usar-Ofair
, eso cambió. Aunque uno de los trabajadores en el nodo estaba ejecutando tareas de larga ejecución, otros no dejarían de procesar y continuarían procesando las tareas precargadas por el nodo. Veo dos niveles de obtención previa. Uno en el nivel del nodo trabajador. El otro a nivel de trabajador individual. Usar-Ofair
para mí parecía deshabilitarlo a nivel de trabajador.¿Cómo se
ACKS_LATE
relaciona?. Me acabo de dar cuenta de que los mensajes precargados aparecen en "mensajes no reconocidos" en rabbitmq. Así que no estoy seguro de siACKS_LATE = True
significa que la tarea se reconocerá solo cuando la tarea se realice correctamente. De lo contrario, supongo que pasaría cuando lo reciba un trabajador. En el caso de la captación previa, el trabajador primero recibe la tarea (confirmada a partir de los registros) pero se ejecutará más tardeTrue
es absolutamente necesario configurarlo . De todos modos, teníamos nuestras tareas configuradas de esa manera (ack tardío) por otras razones.fuente
-Ofair
tiene un "efecto diferente", pero no en qué se diferencia el efecto. Además, estás mencionandoCELERY_ACKS_LATE
, como otros lo han hecho antes, pero hasta ahora nadie ha logrado explicarme qué tiene que ver ese atributo con la desactivación de la captación previa.prefetch=1, celery_acks=True
y cuando lo agregué-Ofair
solucionó el problema en el que estaban esperando al trabajador colgado. Desafortunadamente, el problema del trabajador colgado todavía no se solucionó para mí y, por lo tanto, todos los trabajadores eventualmente se cuelgan, pero al menos ya no lo hacen exactamente al mismo tiempo.Solo una advertencia: a partir de mis pruebas con el corredor de redis + Celery 3.1.15, todos los consejos que he leído relacionados con la
CELERYD_PREFETCH_MULTIPLIER = 1
desactivación de la captación previa son demostrablemente falsos.Para demostrar esto:
CELERYD_PREFETCH_MULTIPLIER = 1
time.sleep(5)
)Comience a ver la longitud de la cola de tareas en Redis:
watch redis-cli -c llen default
comienzo
celery worker -c 1
5
a3
CELERYD_PREFETCH_MULTIPLIER = 1
no evita la captación previa , simplemente limita la captación previa a 1 tarea por cola.-Ofair
, a pesar de lo que dice la documentación , tampoco impide la captación previa .Aparte de modificar el código fuente, no he encontrado ningún método para deshabilitar por completo la captación previa.
fuente
CELERY_ACKS_LATE = 1
, deshabilitará efectivamente la captación previa.No puedo comentar sobre las respuestas de David Wolever, ya que mi stackcred no es lo suficientemente alto. Entonces, he enmarcado mi comentario como una respuesta ya que me gustaría compartir mi experiencia con Celery 3.1.18 y un corredor de Mongodb. Me las arreglé para dejar de buscar previamente con lo siguiente:
CELERYD_PREFETCH_MULTIPLIER = 1
a la configuración de apioCELERY_ACKS_LATE = True
a la configuración de apio--concurrency=1 -Ofair
Dejando CELERY_ACKS_LATE en el valor predeterminado, el trabajador aún realiza búsquedas anticipadas. Al igual que el OP, no entiendo completamente el vínculo entre la captación previa y los acks tardíos. Entiendo lo que dice David "CELERY_ACKS_LATE = True impide reconocer mensajes cuando llegan a un trabajador", pero no entiendo por qué los acks tardíos serían incompatibles con la captación previa. En teoría, una captación previa aún permitiría ack tardío, ¿incluso si no se codifica como tal en el apio?
fuente
Experimenté algo un poco diferente con SQS como corredor.
La configuración fue:
CELERYD_PREFETCH_MULTIPLIER = 1 ACKS_ON_FAILURE_OR_TIMEOUT=False CELERY_ACKS_LATE = True CONCURRENCY=1
Después de que la tarea fallara (se generó una excepción), el trabajador dejó de estar disponible porque el mensaje no fue recibido, tanto en la cola local como en la remota.
La solución que hizo que los trabajadores siguieran consumiendo trabajo fue establecer
CELERYD_PREFETCH_MULTIPLIER = 0
Solo puedo especular que acks_late no se tuvo en cuenta al escribir el transporte SQS
fuente