Celery: Pérdida de memoria continua

Creado en 23 jun. 2018  ·  129Comentarios  ·  Fuente: celery/celery

Hay una pérdida de memoria en el proceso principal del trabajador de Celery.
No es un proceso hijo que ejecuta una tarea.
Ocurre de repente cada pocos días.
A menos que detenga Celery, consume memoria del servidor en decenas de horas.

Este problema ocurre al menos en Celery 4.1 y también ocurre en Celery 4.2.
El apio se ejecuta en Ubuntu 16 y los corredores usan RabbitMQ.

memory

Prefork Workers Pool RabbitMQ Broker Bug Report Critical Needs Testcase ✘ Needs Verification ✘ memory leak

Comentario más útil

¿Por qué se cerró este problema?

Todos 129 comentarios

¿Está utilizando flujos de trabajo de Canvas? Quizás el # 4839 esté relacionado.

También supongo que está utilizando el grupo de prefork para la concurrencia de trabajadores.

Gracias georgepsarakis.

No estoy usando el flujo de trabajo.
Utilizo prefork concurrencia 1 en un solo servidor.

La tasa de aumento parece bastante lineal, bastante extraña. ¿El trabajador está procesando tareas durante este período de tiempo? Además, ¿puede agregar una nota con el comando completo que está utilizando para iniciar el trabajador?

Si. El trabajador continúa procesando la tarea con normalidad.

El trabajador se inicia con el siguiente comando.

/xxxxxxxx/bin/celery worker --app=xxxxxxxx --loglevel=INFO --pidfile=/var/run/xxxxxxxx.pid

Este problema ocurre tanto en el entorno de producción como en el entorno de prueba.
Puedo agregar un perfil de memoria y una salida de prueba al entorno de prueba.
Si hay algo que pueda hacer, por favor diga algo.

Necesitamos entender qué está ejecutando el trabajador durante el tiempo en que se observa el aumento de memoria. Definitivamente cualquier información y detalles que pueda proporcionar. También es bueno que puedas reproducir esto.

Aunque fue un caso que ocurrió en un momento diferente al del gráfico, el siguiente registro se emitió en el momento en que comenzó la pérdida de memoria.

[2018-02-24 07:50:52,953: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection...
Traceback (most recent call last):
File "/xxxxxxxx/lib/python3.5/site-packages/celery/worker/consumer/consumer.py", line 320, in start
blueprint.start(self)
File "/xxxxxxxx/lib/python3.5/site-packages/celery/bootsteps.py", line 119, in start
step.start(parent)
File "/xxxxxxxx/lib/python3.5/site-packages/celery/worker/consumer/consumer.py", line 596, in start
c.loop(*c.loop_args())
File "/xxxxxxxx/lib/python3.5/site-packages/celery/worker/loops.py", line 88, in asynloop
next(loop)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/hub.py", line 293, in create_loop
poll_timeout = fire_timers(propagate=propagate) if scheduled else 1
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/hub.py", line 136, in fire_timers
entry()
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/timer.py", line 68, in __call__
return self.fun(*self.args, **self.kwargs)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/async/timer.py", line 127, in _reschedules
return fun(*args, **kwargs)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/connection.py", line 290, in heartbeat_check
return self.transport.heartbeat_check(self.connection, rate=rate)
File "/xxxxxxxx/lib/python3.5/site-packages/kombu/transport/pyamqp.py", line 149, in heartbeat_check
return connection.heartbeat_tick(rate=rate)
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/connection.py", line 696, in heartbeat_tick
self.send_heartbeat()
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/connection.py", line 647, in send_heartbeat
self.frame_writer(8, 0, None, None, None)
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/method_framing.py", line 166, in write_frame
write(view[:offset])
File "/xxxxxxxx/lib/python3.5/site-packages/amqp/transport.py", line 258, in write
self._write(s)
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-02-24 08:49:12,016: INFO/MainProcess] Connected to amqp://xxxxxxxx:**@xxx.xxx.xxx.xxx:5672/xxxxxxxx

Parece que ocurrió cuando la conexión con RabbitMQ se cortó temporalmente.

@marvelph , ¿ocurre durante las reconexiones de RabbitMQ? Quizás estos problemas estén relacionados:

Si.
Parece que la reconexión lo desencadena.

Parece que estoy teniendo el mismo problema ... Es muy difícil para mí averiguar qué lo desencadena y por qué hay una fuga de memorias. Me molesta durante al menos un mes. Recurro al apio 3 usado y todo está bien.

Para el problema de la pérdida de memoria, estoy usando ubuntu 16, celery 4.1.0 con rabbitmq. Lo implementé a través de Docker.

La pérdida de memoria es con MainProcess, no con ForkPoolWorker. El uso de memoria de ForkPoolWorker es normal, pero el uso de memoria de MainProcess siempre está aumentando. Durante cinco segundos, se filtran alrededor de 0,1 MB de memoria. La pérdida de memoria no comienza inmediatamente después de que el trabajo comienza, sino quizás después de uno o dos días.

Usé gdb y pyrasite para inyectar el proceso en ejecución e intentar gc.collect() , pero no se recopila nada.

Revisé el registro, sucedió el consumer: Connection to broker lost. Trying to re-establish the connection... , pero por ahora no estoy seguro de que este sea el momento en que ocurre la pérdida de memoria.

¿Alguna sugerencia para depurar este problema y descubrir qué sucede realmente? Gracias.

Como @marvelph mencionó que puede estar relacionado con la reconexión de rabbitmq, trato de detener mi servidor de rabbitmq. El uso de memoria aumentó después de cada reconexión, a continuación se muestra el registro. Entonces puedo confirmar este https://github.com/celery/kombu/issues/843 problema.

Pero una vez que se vuelve a conectar la conexión, el uso de la memoria se detiene para aumentar gradualmente. Así que no estoy seguro de que esta sea la razón de la pérdida de memoria.

Intentaré usar redis para averiguar si este problema de pérdida de memoria se relaciona con rabbitmq o no.

[2018-06-25 02:43:33,456: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection...
Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 316, in start
    blueprint.start(self)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 592, in start
    c.loop(*c.loop_args())
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/loops.py", line 91, in asynloop
    next(loop)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/asynchronous/hub.py", line 354, in create_loop
    cb(*cbargs)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/transport/base.py", line 236, in on_readable
    reader(loop)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/transport/base.py", line 218, in _read
    drain_events(timeout=0)
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/connection.py", line 491, in drain_events
    while not self.blocking_read(timeout):
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/connection.py", line 496, in blocking_read
    frame = self.transport.read_frame()
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/transport.py", line 243, in read_frame
    frame_header = read(7, True)
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/transport.py", line 418, in _read
    s = recv(n - len(rbuf))
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-25 02:43:33,497: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 2.00 seconds...

[2018-06-25 02:43:35,526: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 4.00 seconds...

[2018-06-25 02:43:39,560: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 6.00 seconds...

[2018-06-25 02:43:45,599: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 8.00 seconds...

[2018-06-25 02:43:53,639: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 10.00 seconds...

[2018-06-25 02:44:03,680: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 12.00 seconds...

[2018-06-25 02:44:15,743: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 14.00 seconds...

[2018-06-25 02:44:29,790: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 16.00 seconds...

[2018-06-25 02:44:45,839: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 18.00 seconds...

[2018-06-25 02:45:03,890: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 20.00 seconds...

[2018-06-25 02:45:23,943: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 22.00 seconds...

[2018-06-25 02:45:46,002: ERROR/MainProcess] consumer: Cannot connect to amqp://***:**@***:***/***: [Errno 111] Connection refused.
Trying again in 24.00 seconds...

[2018-06-25 02:46:10,109: INFO/MainProcess] Connected to amqp://***:**@***:***/***
[2018-06-25 02:46:10,212: INFO/MainProcess] mingle: searching for neighbors
[2018-06-25 02:46:10,291: WARNING/MainProcess] consumer: Connection to broker lost. Trying to re-establish the connection...
Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/consumer.py", line 316, in start
    blueprint.start(self)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/bootsteps.py", line 119, in start
    step.start(parent)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 40, in start
    self.sync(c)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 44, in sync
    replies = self.send_hello(c)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/worker/consumer/mingle.py", line 57, in send_hello
    replies = inspect.hello(c.hostname, our_revoked._data) or {}
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/app/control.py", line 132, in hello
    return self._request('hello', from_node=from_node, revoked=revoked)
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/app/control.py", line 84, in _request
    timeout=self.timeout, reply=True,
  File "/app/.heroku/python/lib/python3.6/site-packages/celery/app/control.py", line 439, in broadcast
    limit, callback, channel=channel,
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/pidbox.py", line 315, in _broadcast
    serializer=serializer)
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/pidbox.py", line 290, in _publish
    serializer=serializer,
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py", line 181, in publish
    exchange_name, declare,
  File "/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py", line 203, in _publish
    mandatory=mandatory, immediate=immediate,
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py", line 1732, in _basic_publish
    (0, exchange, routing_key, mandatory, immediate), msg
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py", line 50, in send_method
    conn.frame_writer(1, self.channel_id, sig, args, content)
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py", line 166, in write_frame
    write(view[:offset])
  File "/app/.heroku/python/lib/python3.6/site-packages/amqp/transport.py", line 275, in write
    self._write(s)
ConnectionResetError: [Errno 104] Connection reset by peer
[2018-06-25 02:46:10,375: INFO/MainProcess] Connected to amqp://***:**@***:***/***
[2018-06-25 02:46:10,526: INFO/MainProcess] mingle: searching for neighbors
[2018-06-25 02:46:11,764: INFO/MainProcess] mingle: all alone

Aunque revisé los registros, encontré un registro de reconexión en el momento de la pérdida de memoria, pero también hubo un caso en el que comenzó una pérdida de memoria en el momento en que no se produjo la reconexión.
Estoy de acuerdo con la idea de jxlton.

Además, cuando estaba usando Celery 3.x, no encontré tal problema.

el mismo problema aqui
screenshot 2018-06-25 11 09 22
Cada pocos días tengo que reiniciar a los trabajadores debido a este problema
no hay pistas significativas en los registros, pero tengo la sospecha de que las reconexiones pueden afectar; ya que volví a conectar las entradas del registro en algún momento cuando la memoria comienza a crecer constantemente
Mi conf es ubuntu 17, 1 servidor - 1 trabajador con 3 concurrencia; conejo y redis en el backend; todos los paquetes son las últimas versiones

@marvelph @ dmitry-kostin, ¿podría proporcionar su configuración exacta (omitiendo información confidencial, por supuesto) y posiblemente una tarea, o muestra, que reproduzca el problema? Además, ¿tiene alguna estimación del intervalo de tiempo de actividad promedio en el que comienza a aparecer el aumento de la memoria del trabajador?

la configuración está cerca de la predeterminada

importaciones = ('app.tasks',)
result_persistent = Verdadero
task_ignore_result = Falso
task_acks_late = Verdadero
trabajador_concurrencia = 3
worker_prefetch_multiplier = 4
enable_utc = Verdadero
timezone = 'Europa / Moscú'
broker_transport_options = {'visibilidad_tiempo de espera': 3600, 'confirm_publish': True, 'fanout_prefix': True, 'fanout_patterns': True}

screenshot 2018-06-25 11 35 17
Básicamente, se trata de un nuevo nodo implementado; fue desplegado el 21/06 18-50; comenzó a crecer 23/6 alrededor de 05-00 y finalmente se estrelló 23/6 alrededor de 23-00

la tarea es bastante simple y no hay superlógica allí, creo que puedo reproducir toda la situación en un proyecto temporal claro pero no tengo tiempo libre por ahora, si tengo suerte intentaré hacer un ejemplo completo el fin de semana

UPD
como puede ver, la tarea en sí consume algo de memoria, puede verlo por picos en el gráfico, pero el momento en que la memoria comenzó a filtrarse no se produjeron tareas ni ninguna otra actividad.

@marvelph @ dmitry-kostin @jxltom Noté que usas Python3. ¿Le importaría habilitar tracemalloc para el proceso? Sin embargo, es posible que deba parchear el proceso de trabajo para registrar los rastreos de asignación de memoria, avíseme si necesita ayuda con eso.

@georgepsarakis ¿ Te refieres a habilitar tracemalloc en las estadísticas de trabajo y de registro, como los 10 archivos de uso de memoria principales, en un intervalo específico, como 5 minutos?

@jxltom Creo que algo así ayudaría a localizar la parte del código responsable. ¿Qué piensas?

@georgepsarakis Intenté usar gdb y https://github.com/lmacken/pyrasite para inyectar el proceso de fuga de memoria y comenzar a depurar a través de tracemalloc. Aquí está el archivo top 10 con mayor uso de mem.

Utilizo resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 y el uso de la memoria está aumentando gradualmente.

>>> import tracemalloc
>>> 
>>> tracemalloc.start()
>>> snapshot = tracemalloc.take_snapshot()
>>> top_stats = snapshot.statistics('lineno')
>>> for stat in top_stats[:10]:
...     print(stat)
... 
/app/.heroku/python/lib/python3.6/site-packages/kombu/utils/eventio.py:84: size=12.0 KiB, count=1, average=12.0 KiB
/app/.heroku/python/lib/python3.6/site-packages/celery/worker/heartbeat.py:47: size=3520 B, count=8, average=440 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py:166: size=3264 B, count=12, average=272 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:142: size=3060 B, count=10, average=306 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:157: size=2912 B, count=8, average=364 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py:50: size=2912 B, count=8, average=364 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:181: size=2816 B, count=12, average=235 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:203: size=2816 B, count=8, average=352 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:199: size=2672 B, count=6, average=445 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py:1734: size=2592 B, count=8, average=324 B

Aquí está la diferencia entre dos instantáneas después de unos 5 minutos.

>>> snapshot2 = tracemalloc.take_snapshot()
>>> top_stats = snapshot2.compare_to(snapshot, 'lineno')
>>> print("[ Top 10 differences ]")
[ Top 10 differences ]

>>> for stat in top_stats[:10]:
...     print(stat)
... 
/app/.heroku/python/lib/python3.6/site-packages/celery/worker/heartbeat.py:47: size=220 KiB (+216 KiB), count=513 (+505), average=439 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:142: size=211 KiB (+208 KiB), count=758 (+748), average=285 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py:166: size=210 KiB (+206 KiB), count=789 (+777), average=272 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:157: size=190 KiB (+187 KiB), count=530 (+522), average=366 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py:50: size=186 KiB (+183 KiB), count=524 (+516), average=363 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:199: size=185 KiB (+182 KiB), count=490 (+484), average=386 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:203: size=182 KiB (+179 KiB), count=528 (+520), average=353 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:181: size=179 KiB (+176 KiB), count=786 (+774), average=233 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py:1734: size=165 KiB (+163 KiB), count=525 (+517), average=323 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/async/hub.py:293: size=157 KiB (+155 KiB), count=255 (+251), average=632 B

¿Alguna sugerencia sobre cómo continuar depurando esto? No tengo ni idea de cómo proceder. Gracias.

@georgepsarakis

Quiero un poco de tiempo para cortar el proyecto y reproducirlo.

Es escenario de apio.

BROKER_URL = [
    'amqp://xxxxxxxx:[email protected]:5672/zzzzzzzz'
]
BROKER_TRANSPORT_OPTIONS = {}

El planificador tiene la siguiente configuración.

CELERYBEAT_SCHEDULE = {
    'aaaaaaaa_bbbbbbbb': {
        'task': 'aaaa.bbbbbbbb_cccccccc',
        'schedule': celery.schedules.crontab(minute=0),
    },
    'dddddddd_eeeeeeee': {
        'task': 'dddd.eeeeeeee_ffffffff',
        'schedule': celery.schedules.crontab(minute=0),
    },
}

En EC 2, estoy usando supervisord para operarlo.

@georgepsarakis
Dado que mi entorno de prueba puede tolerar la degradación del rendimiento, puede utilizar tracemalloc.
¿Puedes hacer un apio parcheado para volcar el uso de memoria?

@jxltom Apuesto a que tracemalloc con 5 minutos no ayudará a localizar el problema
Por ejemplo, tengo 5 nodos y solo 3 de ellos tuvieron este problema durante los últimos 4 días, y 2 funcionaron bien todo este tiempo, por lo que será muy complicado localizar el problema.
Siento que hay un interruptor que se enciende y luego la memoria comienza a crecer, hasta que el consumo de memoria de este interruptor se ve muy bien

Intenté averiguar si se producían problemas similares en otros sistemas en ejecución.
La frecuencia de ocurrencia varía, pero se ha producido una pérdida de memoria en tres sistemas que utilizan Celery 4.xy no ha ocurrido en un sistema.
El sistema que tiene una pérdida de memoria es Python 3.5.x, y el sistema sin pérdida de memoria es Python 2.7.x.

@ dmitry-kostin ¿Cuál es la diferencia con los otros dos nodos normales? ¿Ambos usan el mismo rabbitmq como intermediario?

Dado que nuestra discusión mencionó que puede estar relacionado con rabbitmq, comencé otro nodo nuevo con la misma configuración, excepto por usar redis en su lugar. Hasta ahora, este nodo no tiene pérdida de memoria después de 24 horas de funcionamiento. Lo publicaré aquí si tiene una fuga de memoria más tarde

@marvelph Entonces, ¿quiere decir que los tres sistemas con pérdida de memoria están usando python3 mientras que el que está bien está usando python2?

@jxltom no hay diferencia en absoluto, y sí, están en python 3 y rabit como corredor y redis en el backend
Hice un ejemplo de prueba para reproducir esto, si tiene éxito en un par de días, le daré las credenciales a estos servidores para alguien que sepa cómo localizar este error.

@jxltom
Si.
En lo que respecta a mi entorno, los problemas no ocurren en Python 2.

Seguí la pérdida de memoria a través de tracemalloc en un período más largo.

El uso de la memoria inicial informado por el módulo resource es 146.58MB , después de las 3,5 horas, informa que el uso de la memoria es 224.21MB .

A continuación se muestra la diferencia de instantánea informada por tracemalloc

>>> snapshot2 = tracemalloc.take_snapshot(); top_stats = snapshot2.compare_to(snapshot, 'lineno')
>>> for stat in top_stats[:10]:
...     print(stat)
... 
/app/.heroku/python/lib/python3.6/site-packages/celery/worker/heartbeat.py:47: size=3619 KiB (+3614 KiB), count=8436 (+8426), average=439 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:142: size=3470 KiB (+3466 KiB), count=12529 (+12514), average=284 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/method_framing.py:166: size=3418 KiB (+3414 KiB), count=12920 (+12905), average=271 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:157: size=3149 KiB (+3145 KiB), count=8762 (+8752), average=368 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/abstract_channel.py:50: size=3099 KiB (+3096 KiB), count=8685 (+8676), average=365 B
/app/.heroku/python/lib/python3.6/site-packages/celery/events/dispatcher.py:199: size=3077 KiB (+3074 KiB), count=8354 (+8345), average=377 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:203: size=3020 KiB (+3017 KiB), count=8723 (+8713), average=355 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/messaging.py:181: size=2962 KiB (+2959 KiB), count=12952 (+12937), average=234 B
/app/.heroku/python/lib/python3.6/site-packages/amqp/channel.py:1734: size=2722 KiB (+2718 KiB), count=8623 (+8613), average=323 B
/app/.heroku/python/lib/python3.6/site-packages/kombu/async/hub.py:293: size=2588 KiB (+2585 KiB), count=4193 (+4188), average=632 B

¿Algunas ideas? ¿Parece que no hay un solo archivo con fugas?

También importé gc , y gc.collect() devuelve 0 ...

@georgepsarakis Pude reproducir esto, ping para acceder a los créditos

Actualización: He actualizado el corredor de rabbitmq a redis actualizando la URL del corredor como variable de entorno y mantengo el docker / código completamente igual. Y está funcionando durante 4 días y no hay pérdida de memoria .

Así que creo que este problema está relacionado con el corredor de rabbitmq.

Si es posible, intente ejecutar el comando de referencia, mencionado aquí: https://github.com/celery/celery/issues/2927#issuecomment -171455414

Este sistema está ejecutando trabajadores con 20 servidores.
Ayer se produjo una pérdida de memoria, pero está ocurriendo en casi todos los servidores al mismo tiempo.
memoryleak

No sé si está relacionado, déjelo aquí en caso de que sirva de ayuda.

Tengo un problema diferente con el apio y el conejomq (el apio pierde la conexión y comienza a reconectarse un montón de veces por segundo, la CPU funciona al 100% en 1 núcleo, el ritmo no puede enviar nuevas tareas, es necesario reiniciar el apio).

La razón por la que estoy informando esto aquí es el desencadenante: después de días de monitoreo, creo que localicé el inicio del problema y parece ser rabbitmq moviendo algunos mensajes de la memoria al disco. En ese momento, el apio comienza a intentar reconectarse lo más rápido que puede y los registros de rabbitmq muestran decenas de operaciones de conexión / desconexión por segundo, en lotes de ~ 10 aproximadamente a la vez. Reiniciar rabbitmq no soluciona el problema, reiniciar el apio lo soluciona de inmediato. No tengo una solución adecuada, pero como ejemplo, establecer una política de expiración que permita que los mensajes permanezcan siempre en la memoria soluciona el problema y no lo he visto desde entonces.

Dado que algunos detalles de este problema coinciden con lo que vi (intercambiar rabbitmq con redis lo soluciona, no hay un punto de partida claro, sucede en más de un trabajador / servidor al mismo tiempo) Supongo que podría haber un desencadenante común y podría sea ​​el mismo que vi.

El conjunto de pruebas se cambia de https://github.com/celery/celery/tree/master/funtests/stress a https://github.com/celery/cyanide , y solo es compatible con Python2.

Así que lo ejecuto en Python2 con rabbitmq como intermediario. Recaudó !join: connection lost: error(104, 'Connection reset by peer') . ¿Está esto relacionado con el problema de la pérdida de memoria?

Aquí está el registro de la suite de pruebas.

➜  cyanide git:(master) pipenv run python -m cyanide.bin.cyanide
Loading .env environment variables…
Cyanide v1.3.0 [celery 4.2.0 (windowlicker)]

Linux-4.13.0-45-generic-x86_64-with-debian-stretch-sid

[config]
.> app:    cyanide:0x7fb097f31710
.> broker: amqp://**:**@**:**/cyanide
.> suite: cyanide.suites.default:Default

[toc: 12 tests total]
.> 1) manyshort,
.> 2) always_timeout,
.> 3) termbysig,
.> 4) timelimits,
.> 5) timelimits_soft,
.> 6) alwayskilled,
.> 7) alwaysexits,
.> 8) bigtasksbigvalue,
.> 9) bigtasks,
.> 10) smalltasks,
.> 11) revoketermfast,
.> 12) revoketermslow

+enable worker task events...
+suite start (repetition 1)
[[[manyshort(50)]]]
 1: manyshort                            OK (1/50) rep#1 runtime: 15.00 seconds/15.01 seconds
 1: manyshort                            OK (2/50) rep#1 runtime: 13.16 seconds/28.17 seconds
 1: manyshort                            OK (3/50) rep#1 runtime: 13.29 seconds/41.46 seconds
 1: manyshort                            OK (4/50) rep#1 runtime: 13.70 seconds/55.16 seconds
 1: manyshort                            OK (5/50) rep#1 runtime: 13.77 seconds/1.15 minutes
 1: manyshort                            OK (6/50) rep#1 runtime: 13.91 seconds/1.38 minutes
!join: connection lost: error(104, 'Connection reset by peer')
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',)
!join: connection lost: error(104, 'Connection reset by peer')
failed after 7 iterations in 3.12 minutes
Traceback (most recent call last):
  File "/home/***/.pyenv/versions/2.7.15/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/home/***/.pyenv/versions/2.7.15/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 62, in <module>
    main()
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 58, in main
    return cyanide().execute_from_commandline(argv=argv)
  File "/home/***/.local/share/virtualenvs/cyanide-Vy3PQPTU/lib/python2.7/site-packages/celery/bin/base.py", line 275, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "/home/***/.local/share/virtualenvs/cyanide-Vy3PQPTU/lib/python2.7/site-packages/celery/bin/base.py", line 363, in handle_argv
    return self(*args, **options)
  File "/home/***/.local/share/virtualenvs/cyanide-Vy3PQPTU/lib/python2.7/site-packages/celery/bin/base.py", line 238, in __call__
    ret = self.run(*args, **kwargs)
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 20, in run
    return self.run_suite(names, **options)
  File "/home/***/Documents/Python-Dev/cyanide/cyanide/bin/cyanide.py", line 30, in run_suite
    ).run(names, **options)
  File "cyanide/suite.py", line 366, in run
    self.runtest(test, iterations, j + 1, i + 1)
  File "cyanide/suite.py", line 426, in runtest
    self.execute_test(fun)
  File "cyanide/suite.py", line 447, in execute_test
    fun()
  File "cyanide/suites/default.py", line 22, in manyshort
    timeout=10, propagate=True)
  File "cyanide/suite.py", line 246, in join
    raise self.TaskPredicate('Test failed: Missing task results')
cyanide.suite.StopSuite: Test failed: Missing task results

Aquí está el registro para el trabajador.

➜  cyanide git:(master) pipenv run celery -A cyanide worker -c 1
Loading .env environment variables…

 -------------- celery@** v4.2.0 (windowlicker)
---- **** ----- 
--- * ***  * -- Linux-4.13.0-45-generic-x86_64-with-debian-stretch-sid 2018-07-03 12:59:28
-- * - **** --- 
- ** ---------- [config]
- ** ---------- .> app:         cyanide:0x7fdc988b4e90
- ** ---------- .> transport:   amqp://**:**@**:**/cyanide
- ** ---------- .> results:     rpc://
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- 
 -------------- [queues]
                .> c.stress         exchange=c.stress(direct) key=c.stress


[2018-07-03 12:59:29,883: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [e6e71bed-8e58-4e7e-96c5-f56b583a37af, 42fd4f97-4ff5-4e0e-b874-89e7b3f0ff22, 3de45eeb-9b89-41bc-8284-95a4c07aa34a,...]: TimeoutError('The operation timed out.',) !
[2018-07-03 12:59:29,886: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [e6e71bed-8e58-4e7e-96c5-f56b583a37af, 42fd4f97-4ff5-4e0e-b874-89e7b3f0ff22, 3de45eeb-9b89-41bc-8284-95a4c07aa34a,...]: TimeoutError('The operation timed out.',) !
[2018-07-03 12:59:30,964: WARNING/ForkPoolWorker-1] + suite start (repetition 1) +
[2018-07-03 12:59:30,975: WARNING/ForkPoolWorker-1] ---  1: manyshort                             (0/50) rep#1 runtime: 0.0000/0.0000 ---
[2018-07-03 13:01:07,835: WARNING/ForkPoolWorker-1] ! join: connection lost: error(104, 'Connection reset by peer') !
[2018-07-03 13:01:17,918: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:27,951: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:38,902: WARNING/ForkPoolWorker-1] ! Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:48,934: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:01:58,961: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:09,906: WARNING/ForkPoolWorker-1] ! Still waiting for 475/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:19,934: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:29,964: WARNING/ForkPoolWorker-1] ! Still waiting for 1000/1000: [1624cd7a-3cc0-474a-b957-b0484f6b4937, 2b436525-73de-4062-bd6b-924cbd11ba74, ce04cb5e-a99e-41e2-95dc-e9bc351e606d,...]: TimeoutError(u'The operation timed out.',) !
[2018-07-03 13:02:37,900: WARNING/ForkPoolWorker-1] ! join: connection lost: error(104, 'Connection reset by peer') !

He actualizado para usar apio 3.1.25 con el mismo conjunto de pruebas de estrés, todo está bien.

Por cierto, para todos los que buscan una solución rápida: reemplazar el conejo con redis resuelve el problema como sugirió @jxltom , tengo más de una semana de trabajo estable con redis solo ahora
Entonces, el problema definitivamente está en algún lugar cerca del borde del conejo <-> apio

@dieeasy hemos experimentado el mismo problema. Supongo que está utilizando el backend de resultados de RPC. Si es así, intente cambiar al backend de resultados de base de datos y vea si eso ayuda. El problema que causa esto es: https://github.com/celery/kombu/pull/779 y se explica aquí: https://github.com/celery/kombu/pull/779#discussion_r134961611

Tengo el mismo problema de pérdida de memoria
Memoria
image

Versión
pitón 3.6.5 apio 4.2.1 backend redis corredor rabbitmq

Config

[celery]
broker_url=amqp://taunt:[email protected]:5672/%2ftaunt
celery_result_backend=redis://xx.xx.xx.xx:6379
# 7days
celery_task_result_expires=604800
celery_task_serializer=msgpack
celery_result_serializer=json
celery_accept_content=json,msgpack
celery_timezone=Asia/Shanghai
celery_enable_utc=True

[cmd]
worker=True
proj=app.worker.celery
log_level=INFO
name=send_im%%h
queue=im
autoscale=10,3
concurrency=10

`` pitón

- - codificación: utf-8 - -

desde la cola de importación de kombu, Exchange
del registro de importación de oslo_log como registro

desde app.conf import CONF

LOG = logging.getLogger (__ nombre__)

colas_de_apio = (
Cola ('im', exchange = Exchange ('remitente'), routing_key = 'im'),
Cola ('sms', exchange = Exchange ('remitente'), routing_key = 'sms'),
Cola ('correo', intercambio = Exchange ('remitente'), routing_key = 'correo'),
Cola ('ivr', exchange = Exchange ('remitente'), routing_key = 'ivr')
)

celery_routes = {
'sender.im': {'cola': 'im', 'routing_key': 'im'},
'sender.sms': {'cola': 'sms', 'routing_key': 'sms'},
'sender.mail': {'queue': 'mail', 'routing_key': 'mail'},
'sender.ivr': {'cola': 'ivr', 'routing_key': 'ivr'}
}

config = {
'BROKER_URL': CONF.celery.broker_url,
'CELERY_RESULT_BACKEND': CONF.celery.celery_result_backend,
'CELERY_TASK_RESULT_EXPIRES': CONF.celery.celery_task_result_expires,
'CELERY_TASK_SERIALIZER': CONF.celery.celery_task_serializer,
'CELERY_RESULT_SERIALIZER': CONF.celery.celery_result_serializer,
'CELERY_ACCEPT_CONTENT': CONF.celery.celery_accept_content.split (','),
'CELERY_TIMEZONE': CONF.celery.celery_timezone,
'CELERY_ENABLE_UTC': CONF.celery.celery_enable_utc,
'CELERY_QUEUES': celery_queues,
'CELERY_ROUTES': celery_routes
}

**Startup**
```python

def make_command() -> list:
    log_path = f'{CONF.log_dir}{os.sep}{CONF.log_file}'
    command_name = f'{sys.path[0]}{os.sep}celery'
    command = [command_name, 'worker', '-A', CONF.cmd.proj, '-E']
    if CONF.cmd.log_level:
        command.extend(['-l', CONF.cmd.log_level])
    if CONF.cmd.queue:
        command.extend(['-Q', CONF.cmd.queue])
    if CONF.cmd.name:
        command.extend(['-n', CONF.cmd.name])
    # if CONF.cmd.autoscale:
    #     command.extend(['--autoscale', CONF.cmd.autoscale])
    if CONF.cmd.concurrency:
        command.extend(['--concurrency', CONF.cmd.concurrency])
    command.extend(['-f', log_path]) 
    return command


if CONF.cmd.worker:
    LOG.info(make_command())
    entrypoint = celery.start(argv=make_command())

Puedo proporcionar más información si es necesario.

Por lo que vale, estoy teniendo este problema y puedo reproducirlo de manera consistente abriendo la consola de administración de rabbitmq, yendo a las conexiones y cerrando las conexiones con el tráfico de celery a rabbitmq.

He probado con apio 4.1 y 4.2 y rabbitmq 3.7.7-1
EDITAR: también Python versión 3.6.5 y ubuntu 16.04 (imagen AWS EC2)

Tengo una pérdida de memoria con celery 4.2.1 y redis broker. La memoria crece de 100 MiB a 500 MiB (limitada) en 3 horas, y los trabajadores se marcan como desconectados en flor. Tanto prefork pool como gevent muestran el mismo problema.

@yifeikong, este puede no ser el mismo problema, pero para su caso, ¿podría probar la solución propuesta https://github.com/celery/celery/pull/4839#issuecomment -447739820?

@georgepsarakis Estoy usando Python 3.6.5, así que este error no me afecta. Usaré tracemalloc para investigar un poco. Si fue un error de apio, abriré una nueva edición. Gracias

Quizás la misma causa con # 5047 , parece que este error puede conducir a un fenómeno diferente.

Nos enfrentamos a la misma pérdida de memoria al ejecutar Celery 4.2.1, Kombu 4.2.2 y python3.6 con RabbitMQ como intermediario.

$ celery --app=eventr.celery_app report

software -> celery:4.2.1 (windowlicker) kombu:4.2.2-post1 py:3.6.8
            billiard:3.5.0.5 py-amqp:2.4.0
platform -> system:Linux arch:64bit imp:CPython

Puedo decir que hemos intentado muchas cosas que otras personas mencionaron como posibles soluciones (redis como corredor, usando jemalloc, libamqp, ruta de mono __del__ en AsyncResult ) pero siempre terminamos con una pérdida de memoria.

Al analizar nuestro registro, notamos que teníamos muchos mensajes relacionados con latidos del corazón perdidos por chismes.

{"asctime": "2019-01-25 13:40:06,486", "levelname": "INFO", "name": "celery.worker.consumer.gossip", "funcName": "on_node_lost", "lineno": 147, "message": "missed heartbeat from celery@******"}

Una última cosa que intentamos fue deshabilitar los chismes ejecutando a los trabajadores con --without-gossip , sorprendentemente, deshabilitar los chismes tuvo un efecto inmediato.

Puedes verlo aqui:
celery-memory-14d

Desde que desactivamos el chisme en dos proyectos que ejecutan apios, el consumo de memoria ha mejorado.

Si prestas atención, antes teníamos picos de memoria similares a los descritos aquí https://github.com/celery/celery/issues/4843#issuecomment -399833781

Una cosa que he estado tratando de entender por completo es cuáles son las implicaciones de deshabilitar por completo el chisme, ya que solo se describe como comunicación trabajador <-> trabajador, si alguien pudiera arrojar algo de luz sobre esto, estaría muy agradecido.

Espero que esto ayude y gracias por el arduo trabajo.

¿Por qué se cerró este problema?

Hay comentarios activos e interés en este tema, así que reabriré.

Bueno, @georgepsarakis, ya que diagnosticamos que mi fuga no era # 4839, y sospechabas que era # 4843, pasaré a este hilo de fuga al menos por ahora. Tampoco estoy seguro de que el número 4843 sea mi fuga. Según el problema inicial en este hilo:

Este problema ocurre al menos en Celery 4.1 y también ocurre en Celery 4.2.
El apio se ejecuta en Ubuntu 16 y los corredores usan RabbitMQ.

Actualmente estoy en:

python 2.7.12
Ubuntu 16.04.1 amd64
ConejoMQ 3.7.5

utilizando:

Apio 4.1.1
librabbitmq 2.0.0
amqp 2.4.0
vid 1.1.4
billar 3.5.0.5
kombu 4.2.2.post1
gevent 1.2.2

Sin embargo, Celery 4.1.1 + gevent 1.2.2 no se filtra por mí (ni Celery 3.1.25 + gevent 1.2.2 AFAICT); Apio 4.2.1 + gevent 1.3.7 sí. Desafortunadamente, gevent 1.3.7 y gevent 1.2.2 no son intercambiables para demostrar (o excluir) una biblioteca gevent como una posible fuente del problema.

EDITAR: Hmm ... parece haber un parche gevent (022f447dd) que parece que podría solucionar el error que encontré. Intentaré que eso funcione.

Apliqué 022f447 a Celery 4.1.1 e instalé gevent 1.3.7. Esa combinación de apio + gevent se ejecutó ... y produjo patrones de uso de memoria consistentes con la fuga que he estado experimentando. Instalaré Celery 4.2.1 + gevent 1.2.2 (con el parche inverso) y veré si obtengo el patrón de uso de memoria habitual.

Noto que Gevent 1.4.0 está fuera. Tal vez debería darle una vuelta a eso también para ver cómo se comporta.

Apio 4.2.1 + gevent 1.2.2 + parche inverso para gevent 1.2.2 no parece producir la fuga al igual que Apio 4.2.1 + gevent 1.3.7.

El apio 4.2.1 + gevent 1.4.0 parece tener fugas aproximadamente a la misma velocidad que gevent 1.3.7 AFAICT.

https://github.com/celery/celery/blob/9f0a554dc2d28c630caf9d192873d040043b7346/celery/events/dispatcher.py

    def _publish(self, event, producer, routing_key, retry=False,
                 retry_policy=None, utcoffset=utcoffset):
        exchange = self.exchange
        try:
            producer.publish(...)
        except Exception as exc:  # pylint: disable=broad-except
            if not self.buffer_while_offline:  # <-- False by default
                raise
            self._outbound_buffer.append((event, routing_key, exc))  # <---- Always buffered

    def send(self, type, blind=False, utcoffset=utcoffset, retry=False,
            ...
            if group in self.buffer_group:   # <--- Never true for eventlet & gevent
                ...
                if len(buf) >= self.buffer_limit:
                    self.flush()     #  <---- Never flushed even when grows above limit
                ...
            else:
                return self.publish(type, fields, self.producer, blind=blind,
                                    Event=Event, retry=retry,

https://github.com/celery/celery/blob/b2668607c909c61becd151905b4525190c19ff4a/celery/worker/consumer/events.py

    def start(self, c):
        # flush events sent while connection was down.
        prev = self._close(c)
        dis = c.event_dispatcher = c.app.events.Dispatcher(
            ...
            # we currently only buffer events when the event loop is enabled
            # XXX This excludes eventlet/gevent, which should actually buffer.
            buffer_group=['task'] if c.hub else None,
            on_send_buffered=c.on_send_event_buffered if c.hub else None,
        )
        if prev:
            dis.extend_buffer(prev)
            dis.flush()    # <---- The only (!) chance to flush on [g]event[let] is on reconnect.

Ahora, si entiendo correctamente lo que hace AMQP debajo del capó, entonces tiene su propio latido y cuando detecta una conexión rota, sigue adelante y se vuelve a conectar debajo del capó. Dependiendo de los tipos de eventos que estén habilitados (chismes, latidos del corazón), esto puede filtrarse bastante rápido.
Esto debería ser cierto para cualquier versión de eventlet y gevent, pero algunas podrían presentar problemas de conexión que empeoran o hacen más notorias las cosas.

Hola,

Sospecho que estamos teniendo el mismo problema.
Nuestra configuración está a continuación. ¿Puedo negar o confirmar que este es el mismo tema que se discutió aquí?

Python: 2.7
Apio: 4.2.1
SO: CentOS versión 6.10
Redis como corredor

En la imagen adjunta puedes ver:

  1. El consumo de memoria aumenta constantemente y disminuye al reiniciar.
  2. El 13 de enero, pasamos de apio 3.1.25 a 4.2.1. El consumo de memoria aumenta a un ritmo cada vez mayor.

image

ACTUALIZAR

Independientemente de este problema, actualizamos a Python 3.6 y, desde entonces, parece que la filtración ya no ocurre.

image
(la actualización fue el 19 de febrero)

@georgepsarakis

No estoy seguro de cuán relevante es esto, pero estoy agotando mis 2GB de espacio SWAP por el apio en producción. Detener a Flower no borró la memoria, pero detener a Celery lo hizo.

¿Alguien podría probar el apio 4.3rc1?

@auvipy Instalé Apio 4.3.0rc1 + gevent 1.4.0. pip actualizó billar a 3.6.0.0 y kombu 4.3.0.

Un poco desconcertado porque el paquete rc1 no requería vine 1.2.0, dado que # 4839 está corregido por esa actualización.

De todos modos, Celery 4.3.0 rc1 parece funcionar bien.

@ ldav1s muchas gracias por los comentarios. Entonces, vine se declara como una dependencia en py-amqp en realidad. En instalaciones nuevas, se instalará la última versión vine , pero es posible que esto no suceda en las existentes.

@thedrow ¿ quizás deberíamos declarar la dependencia en los requisitos de Apio también?

Abramos un tema al respecto y discutámoslo allí.

Apio 4.3.0rc1 + gevent 1.4.0 se ha estado ejecutando un par de días. Parece que tiene una fuga de la misma manera que Celery 4.2.1 + gevent 1.4.0.

image

Tener la misma fuga con apio 4.2.1, python 3.6

¿Alguna actualización sobre esto?

teniendo el mismo problema aquí

Saludos,

Estoy experimentando un problema similar, pero no estoy seguro de que sea el mismo.

Después de migrar nuestra aplicación de apio a un entorno / red diferente, los trabajadores de apio comenzaron a filtrarse. Anteriormente, la aplicación de apio y la instancia de rabbitmq estaban en el mismo entorno / red.

Mi configuración está en Python 3.6.5:

amqp (2.4.2)
billiard (3.5.0.5)
celery (4.1.1)
eventlet (0.22.0)
greenlet (0.4.15)
kombu (4.2.1)
vine (1.3.0)

apioconfig

broker_url = rabbitmq
result_backend = mongodb
task_acks_late = True
result_expires = 0
task_default_rate_limit = 2000
task_soft_time_limit = 120
task_reject_on_worker_lost = True
loglevel = 'INFO'
worker_pool_restarts = True
broker_heartbeat = 0
broker_pool_limit = None

La aplicación está compuesta por varios trabajadores con eventlet pool, iniciada vía comando en supervisord:

[program:worker1]
command={{ celery_path }} worker -A celery_app --workdir {{ env_path }} -l info -E -P eventlet -c 250 -n worker1@{{ hostname }} -Q queue1,queue2

El comportamiento de fuga de memoria se ve así, cada ~ 10 horas generalmente 1 trabajador, máximo 2 comienzan a filtrarse:
image

Entonces, he creado un mensaje de transmisión para que se ejecute en cada trabajador, para usar tracemalloc, este es el resultado del comando superior en la máquina, hay 1 trabajador que solo tiene una fuga con 1464m:

217m   1%   2   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   379
189m   1%   0   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   377     
1464m   9%   1   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   378
218m   1%   0   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   376 
217m   1%   2   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   375
217m   1%   3   0% /usr/bin/python3 -m celery worker -A celery_app --workdir   394
163m   1%   0   0% /usr/bin/python3 -m celery beat -A celery_app --workdir /app

Tracemalloc TOP 10 resultados en el trabajador con fugas

[2019-03-29 07:18:03,809: WARNING/MainProcess] [ Top 10: worker5<strong i="6">@hostname</strong> ]

[2019-03-29 07:18:03,809: WARNING/MainProcess] /usr/lib/python3.6/site-packages/eventlet/greenio/base.py:207: size=17.7 MiB, count=26389, average=702 B

[2019-03-29 07:18:03,810: WARNING/MainProcess] /usr/lib/python3.6/site-packages/kombu/messaging.py:203: size=16.3 MiB, count=44422, average=385 B

[2019-03-29 07:18:03,811: WARNING/MainProcess] /usr/lib/python3.6/site-packages/celery/worker/heartbeat.py:49: size=15.7 MiB, count=39431, average=418 B

[2019-03-29 07:18:03,812: WARNING/MainProcess] /usr/lib/python3.6/site-packages/celery/events/dispatcher.py:156: size=13.0 MiB, count=40760, average=334 B

[2019-03-29 07:18:03,812: WARNING/MainProcess] /usr/lib/python3.6/site-packages/eventlet/greenio/base.py:363: size=12.9 MiB, count=19507, average=695 B

[2019-03-29 07:18:03,813: WARNING/MainProcess] /usr/lib/python3.6/site-packages/amqp/transport.py:256: size=12.7 MiB, count=40443, average=328 B

[2019-03-29 07:18:03,814: WARNING/MainProcess] /usr/lib/python3.6/site-packages/celery/events/dispatcher.py:138: size=12.4 MiB, count=24189, average=539 B

[2019-03-29 07:18:03,814: WARNING/MainProcess] /usr/lib/python3.6/site-packages/amqp/transport.py:256: size=12.3 MiB, count=19771, average=655 B

[2019-03-29 07:18:03,815: WARNING/MainProcess] /usr/lib/python3.6/site-packages/amqp/connection.py:505: size=11.9 MiB, count=39514, average=317 B

[2019-03-29 07:18:03,816: WARNING/MainProcess] /usr/lib/python3.6/site-packages/kombu/messaging.py:181: size=11.8 MiB, count=61362, average=201 B

TOP 1 con 25 cuadros

TOP 1

[2019-03-29 07:33:05,787: WARNING/MainProcess] [ TOP 1: worker5<strong i="10">@hostname</strong> ]

[2019-03-29 07:33:05,787: WARNING/MainProcess] 26938 memory blocks: 18457.2 KiB

[2019-03-29 07:33:05,788: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 207

[2019-03-29 07:33:05,788: WARNING/MainProcess] mark_as_closed=self._mark_as_closed)

[2019-03-29 07:33:05,789: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 328

[2019-03-29 07:33:05,789: WARNING/MainProcess] timeout_exc=socket_timeout('timed out'))

[2019-03-29 07:33:05,790: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 357

[2019-03-29 07:33:05,790: WARNING/MainProcess] self._read_trampoline()

[2019-03-29 07:33:05,790: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/eventlet/greenio/base.py", line 363

[2019-03-29 07:33:05,791: WARNING/MainProcess] return self._recv_loop(self.fd.recv, b'', bufsize, flags)

[2019-03-29 07:33:05,791: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 440

[2019-03-29 07:33:05,791: WARNING/MainProcess] s = recv(n - len(rbuf))

[2019-03-29 07:33:05,792: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/transport.py", line 256

[2019-03-29 07:33:05,792: WARNING/MainProcess] frame_header = read(7, True)

[2019-03-29 07:33:05,792: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 505

[2019-03-29 07:33:05,793: WARNING/MainProcess] frame = self.transport.read_frame()

[2019-03-29 07:33:05,793: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/amqp/connection.py", line 500

[2019-03-29 07:33:05,793: WARNING/MainProcess] while not self.blocking_read(timeout):

[2019-03-29 07:33:05,793: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/transport/pyamqp.py", line 103

[2019-03-29 07:33:05,794: WARNING/MainProcess] return connection.drain_events(**kwargs)

[2019-03-29 07:33:05,794: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/kombu/connection.py", line 301

[2019-03-29 07:33:05,794: WARNING/MainProcess] return self.transport.drain_events(self.connection, **kwargs)

[2019-03-29 07:33:05,795: WARNING/MainProcess] File "/usr/lib/python3.6/site-packages/celery/worker/pidbox.py", line 120

[2019-03-29 07:33:05,795: WARNING/MainProcess] connection.drain_events(timeout=1.0)

Espero que pueda ayudar, no hay ningún error en los registros, aparte del latido perdido entre los trabajadores. Ahora estoy tratando de usar la versión exacta de las bibliotecas que estábamos usando el antiguo env.

ACTUALIZACIÓN: Usando las mismas versiones exactas de lib de dependencias y un latido del corredor cada 5 minutos, la aplicación parecía estable durante más tiempo: más de 2 días, luego se filtró nuevamente.

Hubo un pequeño pico que continuó durante ~ 1 hora por tiempo, pero fueron "absorbidos / recolectados" ... el último parece que comenzó el pico.

Después del primer pico, la primera rampa, reinicié el trabajador con fugas ... como puede ver, otro trabajador comenzó a gotear después o probablemente ya tenía fugas, segunda rampa.

image

Voy a hacer la prueba sin latido.

ACTUALIZACIÓN: sin latidos del corazón se filtró nuevamente después de 2 días, el mismo comportamiento

440m   3%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker1@ -Q p_1_queue,p_2_queue
176m   1%   0   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker2@ -Q p_1_queue,p_2_queue
176m   1%   2   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker5@ -Q p_1_queue,p_2_queue
176m   1%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker3@ -Q p_1_queue,p_2_queue
176m   1%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 250 -Ofair -n worker4@ -Q p_1_queue,p_2_queue
171m   1%   1   0% /usr/bin/python3 -m celery worker -A celery_app --without-heartbeat --workdir /app -l info -E -P eventlet -c 20 -n worker_p_root@ -Q p_root_queue
157m   1%   0   0% /usr/bin/python3 -m celery beat -A celery_app --workdir /app --schedule /app/beat.db -l info

image

ACTUALIZAR:
Usando apio 4.3.0 parece que el problema se resolvió y es estable desde hace una semana
image

amqp (2.4.2)
billiard (3.6.0.0)
celery (4.3.0)
eventlet (0.24.1)
greenlet (0.4.15)
kombu (4.5.0)
vine (1.3.0)

Por favor, avíseme si puedo ayudar de alguna manera, instrumentando el código. Si es necesario, proporcione enlaces y ejemplos.

Gracias

También tengo una pérdida de memoria. Parece que logré encontrar la causa.
https://github.com/celery/celery/blob/master/celery/events/dispatcher.py#L75
Puedo ver que este búfer comienza a crecer después de problemas de conexión con el conejo. No entiendo por qué no puede borrar los eventos eventualmente, continúa creciendo con el tiempo y consume cada vez más RAM. Pasar buffer_while_offline=False aquí https://github.com/celery/celery/blob/master/celery/worker/consumer/events.py#L43 parece arreglar la fuga por mí. ¿Alguien puede verificar si esto está relacionado?

@ yevhen-m ¡muchas gracias! ¡Eso nos ayudó a resolver la pérdida de memoria!

Es bueno que tengamos una solución, pero ¿podemos encontrar una solución adecuada?

Sigue este problema de pérdida de memoria continua

image

celery-pod-screencshot-lastweek

Estoy usando apio en un entorno de producción y lo estoy implementando a través de la ventana acoplable.
Como en la captura de pantalla, tenemos el mismo problema.
Nuestra configuración de producción se muestra a continuación.

Imagen principal de Docker: python 3.6.8-buster
Versión de apio: 4.2.0
Opciones de comando:

  • concurrencia 4
  • multiplicador de captación previa 8
  • Sin result_backend
  • acks_late y accept_on_worker_lost

Me pregunto si actualizar la versión de apio a 4.3.0 resuelve el problema de pérdida de memoria.

¡Gracias!

apio 4.4.0 es el último establo

Equipo, ¿hay alguna actualización sobre este problema? ¿Se abordó y solucionó esto en el apio 4.4.0?

Equipo, ¿hay alguna actualización sobre este problema? ¿Se abordó y solucionó esto en el apio 4.4.0?

Lamentablemente no. Ahora está abordado.

Equipo, ¿hay alguna actualización sobre este problema? ¿Se abordó y solucionó esto en el apio 4.4.0?

estará disponible en 4.4.1

estará disponible en 4.4.1

¿Está arreglado en la versión actual 4.4.1?

@auvipy El problema todavía está presente en Celery 4.4.2 y 4.4.6. Vemos las mismas fugas de memoria en todos los trabajadores.

BROKER_POOL_LIMIT = None
CELERY_ACKS_LATE = False
CELERY_TRACK_STARTED = True
CELERYD_MAX_TASKS_PER_CHILD = 1
CELERYD_PREFETCH_MULTIPLIER = 1
BROKER_TRANSPORT_OPTIONS = {
    'fanout_prefix': True,
    'fanout_patterns': True,
    'visibility_timeout': 43200,
    'health_check_interval': 180,
    'socket_keepalive': True,
    'retry_on_timeout': True,
}

El trabajador de apio comienza con las banderas -O fair --without-heartbeat --without-gossip -c 1 -l . También usamos las banderas -n y -Q para establecer el nombre del trabajador y las colas. Ejecutando en modo prefork. Redis está configurado como broker y como almacén de resultados.

image

~ Vemos muchos latidos perdidos en tareas de ejecución prolongada. Por lo tanto, el problema informado en los problemas vinculados aún persiste. ~

Lo mismo ocurre con los latidos del corazón discapacitados.

@jsynowiec Cuando me enfrenté a este problema, lo único que funcionó para mí fue ejecutar a los trabajadores con chismes desactivados, mencioné algo al respecto aquí https://github.com/celery/celery/issues/4843#issuecomment -459789086

Estamos experimentando el mismo problema con apio 4.4.2 y redis como corredor. Durante un período de 48 horas, el apio consume hasta 60 GB de RAM hasta que finalmente se queda sin memoria.
Ninguna de las soluciones mencionadas aquí tuvo ningún efecto en este comportamiento.

Estamos experimentando el mismo problema con apio 4.4.2 y redis como corredor. Durante un período de 48 horas, el apio consume hasta 60 GB de RAM hasta que finalmente se queda sin memoria.
Ninguna de las soluciones mencionadas aquí tuvo ningún efecto en este comportamiento.

¿Probaste nuestra última versión de parche?
¿Tiene las mismas condiciones que el OP?

Las pérdidas de memoria todavía están presentes en v4.4.6 Ejecutamos trabajadores con las configuraciones enumeradas en un comentario anterior . OP usa RabbitMQ, usamos Redis como corredor.

image

+1, notando que el uso de la memoria aumenta gradualmente durante 24 horas incluso con un trabajo mínimo. Creo que este tema debería reabrirse.

¿Puedes crear un perfil y descubrir la raíz de la pérdida de memoria?

Las pérdidas de memoria todavía están presentes en v4.4.6 Ejecutamos trabajadores con las configuraciones enumeradas en un comentario anterior . OP usa RabbitMQ, usamos Redis como corredor.

image

Parece que este es un problema diferente o que nuestra solución no fue correcta.
Dado que esto resolvió el problema del OP, probablemente sea un problema diferente, ¿verdad?

[2020-07-31 10:51:53,176: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=19.2 KiB (+19.2 KiB), count=180 (+180), average=109 B
[2020-07-31 10:53:53,271: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=230 KiB (+211 KiB), count=2160 (+1980), average=109 B
[2020-07-31 10:54:53,364: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=250 KiB (+19.2 KiB), count=2340 (+180), average=109 B

....

[2020-07-31 12:24:10,633: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=49.9 MiB (+76.8 KiB), count=478620 (+720), average=109 B
[2020-07-31 12:25:14,528: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=49.9 MiB (+19.2 KiB), count=478800 (+180), average=109 B
[2020-07-31 12:27:22,346: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=49.9 MiB (+57.6 KiB), count=479340 (+540), average=109 B
[2020-07-31 12:28:26,265: WARNING/MainProcess] /usr/local/lib/python3.8/site-packages/redis/client.py:90: size=50.2 MiB (+269 KiB), count=481860 (+2520), average=109 B

CELERY_RESULT_BACKEND = False CELERY_IGNORE_RESULT = True CELERY_MAX_TASKS_PER_CHILD = 1 CELERY_WORKER_PREFETCH_MULTIPLIER = 1 CELERY_TASK_RESULT_EXPIRES = 10 CELERY_BROKER_POOL_LIMIT = 70 CELERY_REDIS_MAX_CONNECTIONS = 100
app.conf.broker_transport_options = {'visibility_timeout': 43200}

celery -A proj worker --concurrency=70 --prefetch-multiplier=1 -Ofair --pool=gevent -n --without-gossip --without-mingle

¿El cliente de Redis pierde memoria? Estoy usando apio v4.4.6 con gevent, redis como corredor y sin backend de resultados.

Quizás eso también sea un problema. ¿Quizás está en gevent?
CC @jamadden @andymccurdy
¿Puede ayudarnos a resolver este problema y asegurarse de que no se pierda ningún recuerdo?

¿Quizás está en gevent?

No estamos usando gevent . Los trabajadores se inician con concurrencia = 1 y prefork.

Hola chicos, no estoy seguro de por qué este problema está cerrado, hemos tenido este problema durante 2 años, actualizando a la última versión de Apio cada vez, y todavía tenemos grandes servidores (64-128GB de RAM) que se quedan sin RAM constantemente porque de estos problemas de pérdida de memoria.

¿Existe alguna solución sin cambiar a Celery 3 o reemplazar Rabbitmq?

Esto hace que Celery sea completamente inestable en entornos de producción, espero que se pueda solucionar, no podemos degradar a Celery 3, por lo que estamos planeando pasar a otra solución (tal vez Dramatiq) para dejar de preocuparnos de que Celery se coma la RAM de todos los servidores. producción cada 2 días.

@arielcamino : he estado usando la configuración worker_max_tasks_per_child para reemplazar las instancias de los trabajadores después de 100 ~ tareas que han ayudado a mantener el uso de la memoria, al menos para mis servidores. Estoy ejecutando pequeñas instancias de 512 MB y esto ayudó (anteriormente agotaba mi memoria RAM), así que tal vez te ayude.

@Skowt wow, eso es muy útil, ¡muchas gracias! Lo intentaré ahora mismo.

@arielcamino : he estado usando la configuración worker_max_tasks_per_child para reemplazar las instancias de los trabajadores después de 100 ~ tareas que han ayudado a mantener el uso de la memoria, al menos para mis servidores. Estoy ejecutando pequeñas instancias de 512 MB y esto ayudó (anteriormente agotaba mi memoria RAM), así que tal vez te ayude.

Gracias por compartir tu solución. Esto no ayudó aquí, aunque estamos usando redis.

@thedrow No tengo conocimiento de ninguna fuga de memoria en redis-py. Si redis-py tuvo una fuga, supongo que alguien lo habría encontrado fuera del entorno de Celery y lo habría informado al rastreador de problemas de redis-py.

Feliz de ayudar donde puedo (uso Celery w / Redis como corredor en varios proyectos), pero no he encontrado este problema en mis implementaciones.

No tengo conocimiento de pérdidas de memoria en las versiones actuales de gevent. Supongo (espero) que alguien hubiera dicho algo si se hubiera encontrado con eso (ha sucedido una o dos veces antes). Mis implementaciones actuales de gevent tienen varios trabajadores (web y en segundo plano) durante semanas seguidas usando gevent en gran medida y no hemos encontrado pérdidas de memoria.

Hola chicos, no estoy seguro de por qué este problema está cerrado, hemos tenido este problema durante 2 años, actualizando a la última versión de Apio cada vez, y todavía tenemos grandes servidores (64-128GB de RAM) que se quedan sin RAM constantemente porque de estos problemas de pérdida de memoria.

¿Existe alguna solución sin cambiar a Celery 3 o reemplazar Rabbitmq?

Esto hace que Celery sea completamente inestable en entornos de producción, espero que se pueda solucionar, no podemos degradar a Celery 3, por lo que estamos planeando pasar a otra solución (tal vez Dramatiq) para dejar de preocuparnos de que Celery se coma la RAM de todos los servidores. producción cada 2 días.

¿Cuántos trabajadores tienes? ¿Cuántas tareas ejecutas? ¿Con qué frecuencia ejecuta estas tareas y cuánto tardan normalmente en finalizar?

La razón por la que Rabbitmq / celery comienza a usar mucho ram puede estar relacionada con la cantidad de tareas en cola. Si pone en cola demasiadas tareas y los trabajadores no pueden completarlas todas, se ampliará la cola y esta cola utilizará cada vez más RAM y, finalmente, consumirá toda la RAM disponible. Creo que este problema también podría ocurrir con Redis.

Tengo otra teoría, pero primero quiero saber si esta podría ser la razón de su problema.

@ardilom lo siento, me acabo de dar cuenta de que no estamos enviando datos de RabbitMQ a datadog, pero intentaré aclarar nuestra situación, así es como la RAM de algunos servidores cae cada 2 días:
memory-leaks-1

Siempre comprobamos el número de tareas pendientes, y normalmente es alrededor de 0 (este dato es de hace unos días):

memory-leaks-2

Ejecutamos alrededor de 250.000 tareas por día, tenemos alrededor de 10 trabajadores, cada uno con alrededor de 4 a 10 de simultaneidad, el tiempo de ejecución promedio es de alrededor de 5 segundos, depende del tipo de tarea.

Siempre revisamos messages_ready para asegurarnos de que no haya demasiadas tareas en cola (esto es lo que ves en la segunda imagen), ¿crees que está bien medir messages_ready ? Eventualmente tenemos algunos picos, pero normalmente estos están cerca de 0.

Para resolver el problema, simplemente reinicio el trabajador de Apio manualmente y el uso de RAM vuelve a ser normal.

Avíseme si necesita algo más, acabo de cambiar la configuración de worker_max_tasks_per_child en uno de los servidores de tareas, para ver si hay alguna diferencia con el resto de ellos después de aplicar la configuración.

¡Gracias!

Hola chicos, esto es para confirmar que al cambiar worker_max_tasks_per_child a 1000 en mi caso, se solucionó el problema 🎉 gracias de nuevo @Skowt

Algo que no mencioné ayer, estoy usando el modo "prefork", tal vez pasar a gevent sea otra forma de resolver el problema.

@arielcamino Este problema se cerró ya que
Necesitamos a alguien con acceso a un entorno de producción donde se reproduzca el error para depurar el problema.
Si no tenemos uno, tendremos que determinar que este problema no es procesable.

Hola, ¿podemos reabrir este problema? Estamos experimentando fugas similares, usando apio == 4.4.7 (con rabbitmq) tenemos al trabajador funcionando estable durante un par de horas, a veces mucho más, y luego, de repente, comienza a filtrarse lentamente y termina usando toda la memoria.

Actualmente se usa prefork con --concurrency=1 y la bandera --max-tasks-per-child=100 que no parece ayudar ya que el proceso principal parece ser el que tiene una fuga.

celery_leak

Puedo proporcionar más información para ayudar a depurar este problema.

Hola, ¿podemos reabrir este problema? Estamos experimentando fugas similares, usando apio == 4.4.7 (con rabbitmq) tenemos al trabajador funcionando estable durante un par de horas, a veces mucho más, y luego, de repente, comienza a filtrarse lentamente y termina usando toda la memoria.

Actualmente se usa prefork con --concurrency=1 y la bandera --max-tasks-per-child=100 que no parece ayudar ya que el proceso principal parece ser el que tiene una fuga.

celery_leak

Puedo proporcionar más información para ayudar a depurar este problema.

reabrir el problema no es un gran problema, es el interés de alguien que se enfrenta a esto en producción y que ayude a rastrear y contribuir con una solución o al menos descubrir la causa raíz de la fuga en la producción.

Definitivamente puedo ayudar, pero me quedé sin ideas sobre qué hacer, ejecuté un par de herramientas pero no pude identificar mucho sobre el problema. Lo único que lo reduce un poco son las instantáneas de tracemalloc que tomé, que muestran el aumento de la memoria en los mismos lugares cada dos minutos más o menos. Este es el top 10 comparando dos instantáneas:

/usr/local/lib/python3.8/site-packages/celery/events/dispatcher.py:148: size=259 KiB (+218 KiB), count=1026 (+867), average=259 B
/usr/local/lib/python3.8/site-packages/kombu/messaging.py:178: size=231 KiB (+194 KiB), count=1056 (+888), average=224 B
/usr/local/lib/python3.8/site-packages/amqp/connection.py:513: size=217 KiB (+182 KiB), count=703 (+591), average=316 B
/usr/local/lib/python3.8/site-packages/celery/events/dispatcher.py:214: size=207 KiB (+174 KiB), count=704 (+592), average=302 B
/usr/local/lib/python3.8/site-packages/kombu/messaging.py:200: size=204 KiB (+171 KiB), count=704 (+592), average=296 B
/usr/local/lib/python3.8/site-packages/amqp/transport.py:253: size=203 KiB (+171 KiB), count=703 (+591), average=296 B
/usr/local/lib/python3.8/site-packages/amqp/connection.py:508: size=184 KiB (+154 KiB), count=703 (+591), average=268 B
/usr/local/lib/python3.8/site-packages/celery/worker/consumer/consumer.py:445: size=182 KiB (+153 KiB), count=352 (+296), average=528 B
/usr/local/lib/python3.8/site-packages/amqp/channel.py:1758: size=169 KiB (+143 KiB), count=703 (+593), average=247 B
/usr/local/lib/python3.8/site-packages/kombu/asynchronous/hub.py:301: size=167 KiB (+140 KiB), count=351 (+295), average=486 B

El problema aún existe
Esto sucede cuando una tarea de apio accede al contexto de la aplicación para realizar una función.
No lo liberará ni lo desechará después de realizar la tarea.

--max-tasks-per-child=

no fue útil

Hola, ¿podemos reabrir este problema? Estamos experimentando fugas similares, usando apio == 4.4.7 (con rabbitmq) tenemos al trabajador funcionando estable durante un par de horas, a veces mucho más, y luego, de repente, comienza a filtrarse lentamente y termina usando toda la memoria.
Actualmente se usa prefork con --concurrency=1 y la bandera --max-tasks-per-child=100 que no parece ayudar ya que el proceso principal parece ser el que tiene una fuga.
celery_leak
Puedo proporcionar más información para ayudar a depurar este problema.

reabrir el problema no es un gran problema, es el interés de alguien que se enfrenta a esto en producción y que ayude a rastrear y contribuir con una solución o al menos descubrir la causa raíz de la fuga en la producción.

para mí si agrego --max-tasks-per-child funciona.
como para este ejemplo de argumentos --autoscale=5,2 --max-tasks-per-child=40 el resultado es así

Screenshot 2020-08-13 at 2 26 13 PM

Si bien creo que una actualización reciente del apio introdujo la pérdida de memoria, no puedo estar completamente seguro. Compartiré que la siguiente configuración resolvió la fuga.

No puedo decir qué configuraciones son válidas por la documentación, así que estoy configurando todos estos valores en mi archivo de configuración de Django.

CELERY_CONCURRENCY = CELERY_WORKER_CONCURRENCY = 1
CELERY_MAX_TASKS_PER_CHILD = CELERY_WORKER_MAX_TASKS_PER_CHILD = 1

Esto no soluciona la fuga que estamos viendo, como también ocurre en la piscina de gevent. Lo que noté es que tenemos la cola de celeryev bastante ocupada. Debido a que tracemalloc mostró el envío de eventos como una de las posibles fuentes de la fuga, deshabilité explícitamente los eventos de tareas y apagué nuestra instancia de flor, por ahora parece que la fuga ya no está ocurriendo, dejaré que se ejecute durante el fin de semana y compartiré los resultados aquí.

posibles fuentes de la fuga. Deshabilité explícitamente los eventos de tareas y apagué nuestra instancia de flor.

Punto de datos anecdótico de alguien que ha estado observando este problema en silencio desde el principio (y nunca lo ha experimentado directamente): estoy al tanto de otro proyecto (con una carga de trabajo no insustancial para el apio) en el que hacer lo anterior tuvo el mismo resultado de detener una fuga de memoria. Teniendo solo información de segunda mano, _obviamente_ no puedo confirmar que sea el mismo problema subyacente (AFAIK, era rabbitmq, no tengo idea de gevent, etc.), pero es interesante que se correlacione.

Sospecho que tiene algo que ver con la conexión rabbitmq de alguna manera, la pila que hemos estado observando esta fuga:

  • apio (última versión): ya sea prefork o gevent pool, ambos muestran el mismo patrón de fugas.
  • rabbitmq (cloudamqp SaaS)
  • flor

Hemos revisado todas nuestras tareas en busca de fugas y no pudimos encontrar ninguna, por eso mi sospecha de ser algo del lado del apio.

Un hecho interesante es que actualmente tenemos muchos trabajadores en ejecución, y noté que, una vez que uno comienza a filtrarse, también se muestra en Flower como fuera de línea.

Cuando me quedé sin ideas sobre dónde buscar, desactivé los eventos de flores y tareas y seguiré monitoreando si la fuga volverá o no.

Estoy abierto a creer que es otra parte de mi pila la que está perdiendo memoria en este momento. Es posible que el apio haya tenido un comportamiento fortuito en el pasado que contribuyó a controlar las pérdidas de memoria, pero todos juntos no parece que tengamos problemas lo suficientemente similares como para confirmarlo. Sé que muchos de nosotros estamos corriendo ...

  • Una gran cantidad de tareas anidadas a la vez, o
  • Algunos monolíticos que inician el procesamiento de múltiples núcleos dentro del trabajador

En estos casos, solo debemos ser inteligentes al permitir o no permitir un cierto nivel de simultaneidad, cola de tareas y tareas por trabajador secundario. Además, todos deberíamos utilizar protecciones integradas que puedan eliminar las tareas que consumen mucha memoria antes de que tengan la oportunidad de bloquear nuestros servidores.

Un número cada vez mayor de personas está ejecutando procesos estrictos vinculados a la CPU y a la memoria en el apio, para lo cual no fue realmente hecho, así que creo que la documentación de inicio rápido debería incluir más detalles sobre esto.

Como ya mencioné en mis comentarios anteriores, estamos ejecutando trabajadores con max-tasks-per-child y concurrencia configurados en 1 desde hace mucho tiempo. No hace nada por la pérdida de memoria. Además, estamos utilizando Redis como corredor y como backend de resultados.

Según mis observaciones, cuando se usa RabbitMQ como intermediario, si establecer max-tasks-per-child en 1 "resuelve" la pérdida de memoria, lo más probable es que sea un problema con la implementación de la tarea, no con apio.

Lo que estamos observando y reportando es diferente. Incluso si dejamos al trabajador inactivo durante varios días, sin procesar una sola tarea, todavía pierde memoria hasta un punto en el que alcanza el límite de memoria y el supervisor lo mata. Puede encontrar más detalles y gráficos de memoria en comentarios anteriores.

Con el trabajador procesando una sola tarea según lo programado, el gráfico de memoria debería mostrar más o menos una onda cuadrada, pero puede ver claramente que el uso general de memoria solo aumenta.
Screenshot 2020-08-14 at 20 42 24

Me las arreglé para incluir el perfil de los trabajadores del apio en nuestra hoja de ruta. Compartiré volcados de memoria y más detalles cuando comencemos a trabajar en esto.

Puedo confirmar que apagar la flor (y deshabilitar explícitamente los eventos de tareas a través de la configuración) solucionó la fuga.

Como mencioné antes, en el momento en que el trabajador comenzó a gotear, noté en flor que se desconectaba y el celeryev siempre se mostraba bastante ocupado, así que seguí el camino más fácil y apagué la flor.

Desafortunadamente, no pude encontrar el código que causa la fuga. Pero al menos existe esta solución.

entonces probablemente esto no sea un problema de apio sino de flores.

@auvipy flower desencadena el problema, pero la fuga definitivamente ocurre en el trabajador (apio)

@auvipy flower desencadena el problema, pero la fuga definitivamente ocurre en el trabajador (apio)

lo suficientemente justo. gracias por compartir.

Estoy usando apio con Redis y Flower, y debo decir que actualmente no veo ningún problema de memoria. ¿Algo que quieras de mí con respecto a los datos?

@auvipy no usa Flower. Los trabajadores se inician con eventos desactivados.

@auvipy no usa Flower. Los trabajadores se inician con eventos desactivados.

intente depurar y averiguar la raíz de la pérdida de memoria. podría ser apio o tu podrías. sería mejor si pudiera compartir pruebas unitarias y de integración

intente depurar y averiguar la raíz de la pérdida de memoria. podría ser apio o tu podrías. sería mejor si pudiera compartir pruebas unitarias y de integración

Se menciona aquí que vemos OOM debido a que el trabajador de apio pierde memoria incluso si el trabajador no procesa ninguna tarea.
No se pueden compartir pruebas unitarias o de integración, ya que esto expondría la propiedad intelectual de la empresa. Lo siento. Pero logré agregar una tarea para capturar volcados de memoria en trabajadores de producción en nuestra hoja de ruta interna. Compartirá contadores y referencias para algunos escenarios cuando esté hecho.

@jsynowiec Si puedes hacerlo antes de 5.0.0 GA (sigue el # 6266 para actualizaciones) sería increíble.

Una vez que una corrección de errores aterriza en master, también se volverá a exportar a 4.x.

@thedrow ¿ Cuándo se planea una GA de 5.0? Desafortunadamente, tenemos un código heredado que aún se debe migrar a Py3 😞, por lo que estamos atascados con Celery 4 por el momento.

Tenemos un bloqueador de versiones y algo de documentación para completar.
La respuesta es muy pronto.

Puedo confirmar que apagar la flor detiene la fuga. Llevamos funcionando sin fugas casi un mes.

Así que todavía hay un error en algún lugar de nuestro mecanismo de publicación de eventos.
¿Alguien tiene una idea de lo que podría ser?

No usamos Flower y los trabajadores comienzan sin --events , sin embargo, experimentamos pérdidas de memoria continuas.

La respuesta es muy pronto.

Me las arreglé para asignar alta prioridad a la obtención de volcados de memoria y contadores de objetos de los trabajadores de producción. Debería poder publicar algunos datos en las próximas semanas. También hemos elevado la prioridad en la finalización de la migración de py2-> py3, por lo que todo debería ejecutarse y perfilarse con Python 3.

Lo que me preocupa es que estamos hablando de dos temas diferentes aquí.

Aparentemente. Uno está relacionado con eventos y tal vez con Flower, tal vez usando también RabbitMQ como corredor. De acuerdo con los problemas reportados aquí, en GitHub, aparece aquí y allá desde hace unos años. El otro (que afecta a mi proyecto) está relacionado con diferentes componentes y muy probablemente relacionado con el uso de Redis como corredor. O tal vez en la raíz, esos son los mismos problemas que se originan en el mismo código quién sabe 🤷🏼. Como el que tiene trail haciendo un seguimiento de las subtareas y las instancias con fugas de AsyncResult 😉

@thedrow @auvipy Solo les

Además, al finalizar la migración de Python3, encontramos otro problema que parece estar relacionado con https://github.com/celery/celery/issues/4470 o https://github.com/celery/celery/issues/5359. Bajo ciertas condiciones en los sistemas Linux, mientras se usa Redis como intermediario, las llamadas a join_native cuelgan indefinidamente a pesar de que todas las tareas dentro del grupo ya se han realizado. Quick strace apunta a que literalmente cuelga de read, lo que podría indicar algunas cosas de kernel / lib de bajo nivel. Por ahora cambiamos a simple, agrupando join mientras nos enfocamos en las pérdidas de memoria.

Hola a todos, finalmente _algunos_ datos: celery-memtrace-1.tar.xz , firma , mi clave .

El archivo contiene registros de tracemalloc de 8 trabajadores después de ~ 16 días, un gráfico de uso de memoria para el período y cierta información de la versión (incluido el banner de inicio de Celery).

Honestamente, no he pasado mucho tiempo analizando nada de esto, pero a) nuestro código nunca estuvo en la lista, b) también puede ser una interacción extraña con SQLAlchemy que también usamos en todas partes, por lo que no es imposible que el problema está en otro lugar o es un problema de combinación / interacción.

Si cualquier otro detalle sería útil, por favor pregunte. También continuamos ejecutando esos 8 trabajadores con este registro de uso de memoria, por lo que quizás podamos recopilar más / mejores datos.

EDITAR : También este comentario de este hilo está relacionado, todavía usamos la misma configuración.

Espero que encuentre la causa raíz de esta fuga.
Trataré de hacer algo de tiempo para investigar esto yo mismo.

Me pregunto si esto podría ayudar a mitigar el problema.
https://reliability.substack.com/p/run-python-servers-more-efficiently

Estamos investigando la posibilidad de que el origen de las pérdidas de memoria esté dentro de la biblioteca de solicitudes , no en el apio en sí. ¿Alguien más que esté experimentando pérdidas de memoria en el apio al usar solicitudes en las tareas?

@ErrorInPersona Sí, estamos registrando OOM en trabajadores con y sin solicitudes por igual.

@drbig ¿

Screenshot_2020-11-17_12-56-28

Bueno, mire el "verde", el piso está subiendo, lento pero seguro ... Entonces, excepto por una rápida confirmación de "sí, todavía es un problema", no hay mucho que agregar por mi parte, desafortunadamente.

Sin embargo, he hojeado el enlace que - try running some workers with jemalloc forced in , así que llegaré a eso, _ eventualmente_.

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