Celery: Vazamento contínuo de memória

Criado em 23 jun. 2018  ·  129Comentários  ·  Fonte: celery/celery

Há um vazamento de memória no processo pai do trabalhador de Celery.
Não é um processo filho executando uma tarefa.
Acontece de repente a cada poucos dias.
A menos que você pare o Celery, ele consome a memória do servidor em dezenas de horas.

Este problema ocorre pelo menos no Celery 4.1 e também ocorre no Celery 4.2.
Celery está sendo executado no Ubuntu 16 e os corretores usam RabbitMQ.

memory

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

Comentários muito úteis

Por que este problema foi encerrado?

Todos 129 comentários

Você está usando fluxos de trabalho do Canvas? Talvez # 4839 esteja relacionado.

Além disso, suponho que você esteja usando o pool prefork para simultaneidade do trabalhador.

Obrigado georgepsarakis.

Não estou usando o fluxo de trabalho.
Eu uso a simultaneidade prefork 1 em um único servidor.

A taxa de aumento parece bastante linear, bastante estranha. O trabalhador está processando tarefas durante esse período? Além disso, você pode adicionar uma nota com o comando complete que está usando para iniciar o trabalhador?

sim. O trabalhador continua a processar a tarefa normalmente.

O trabalhador é iniciado com o seguinte comando.

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

Esse problema está ocorrendo no ambiente de produção e no ambiente de teste.
Posso adicionar perfil de memória e saída de teste ao ambiente de teste.
Se houver algo que eu possa fazer, por favor, diga algo.

Precisamos entender o que o trabalhador está executando durante o tempo em que o aumento de memória é observado. Quaisquer informações e detalhes que você possa fornecer com certeza. Também é bom que você possa reproduzir isso.

Embora tenha ocorrido em um momento diferente do gráfico, o próximo registro foi gerado no momento em que o vazamento de memória começou.

[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 ocorreu quando a conexão com RabbitMQ foi temporariamente cortada.

@marvelph então ocorre durante as reconexões do RabbitMQ? Talvez esses problemas estejam relacionados:

sim.
Parece que a reconexão o aciona.

Parece que estou tendo o mesmo problema ... É tão difícil para mim descobrir o que o aciona e por que há um vazamento de memória. Isso me irrita por pelo menos um mês. Eu volto para o aipo usado 3 e está tudo bem.

Para o problema de vazamento de memória, estou usando ubuntu 16, celery 4.1.0 com rabbitmq. Eu o implantei via docker.

O vazamento de memória é com MainProcess, não ForkPoolWorker. O uso de memória de ForkPoolWorker é normal, mas o uso de memória de MainProcess está sempre aumentando. Por cinco segundos, cerca de 0,1 MB de memória vazou. O vazamento de memória não começa depois que o trabalho começa imediatamente, mas talvez depois de um ou dois dias.

Usei gdb e pyrasite para injetar o processo em execução e tentei gc.collect() , mas nada foi coletado.

Eu verifiquei o log, o consumer: Connection to broker lost. Trying to re-establish the connection... aconteceu, mas por agora não tenho certeza se este é o momento em que ocorre o vazamento de memória.

Alguma dica para depurar esse problema e descobrir o que realmente acontece? Obrigado.

Como @marvelph mencionou que pode estar relacionado com a reconexão rabbitmq, tento parar meu servidor rabbitmq. O uso de memória aumentou após cada reconexão, a seguir está o log. Portanto, posso confirmar este https://github.com/celery/kombu/issues/843 problema.

Mas depois que a conexão for reconectada, o uso de memória para e aumenta gradualmente. Portanto, não tenho certeza se esse é o motivo do vazamento de memória.

Vou tentar usar o redis para descobrir se esse problema de vazamento de memória está relacionado com o rabbitmq ou não.

[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

Embora tenha verificado os logs, encontrei um log de reconexão no momento do vazamento de memória, mas também houve um caso em que um vazamento de memória começou no momento em que a reconexão não ocorreu.
Eu concordo com a ideia de jxlton.

Além disso, quando estava usando o Celery 3.x, não encontrei esse problema.

mesmo problema aqui
screenshot 2018-06-25 11 09 22
A cada poucos dias eu tenho que reiniciar os trabalhadores devido a este problema
não há nenhuma pista significativa nos registros, mas suspeito que reconexões podem afetar; já que reconectei as entradas de registro em algum momento em que a memória começa a crescer constantemente
Meu conf é ubuntu 17, 1 servidor - 1 trabalhador com 3 simultaneidade; coelho e redis no backend; todos os pacotes são as versões mais recentes

@marvelph @

a configuração está próxima ao padrão

importações = ('app.tasks',)
result_persistent = True
task_ignore_result = False
task_acks_late = True
worker_concurrency = 3
worker_prefetch_multiplier = 4
enable_utc = True
fuso horário = 'Europa / Moscou'
broker_transport_options = {'visibility_timeout': 3600, 'confirm_publish': True, 'fanout_prefix': True, 'fanout_patterns': True}

screenshot 2018-06-25 11 35 17
Basicamente, este é um novo nó implantado; foi implantado em 21/06 18-50; começou a crescer em 23/06 por volta de 05-00 e finalmente caiu em 23/06 por volta de 23-00

a tarefa é muito simples e não há superlógica lá, acho que posso reproduzir toda a situação em um projeto temporário claro, mas não tenho tempo livre por enquanto, se eu tiver sorte, tentarei fazer um exemplo completo no fim de semana

UPD
como você pode ver, a tarefa em si consome um pouco de memória, você pode vê-la por picos no gráfico, mas no momento em que a memória começou a vazar não houve nenhuma tarefa produzida ou qualquer outra atividade

@marvelph @ @jxltom Percebi que você usa Python3. Você se importaria de ativar o tracemalloc para o processo? Pode ser necessário corrigir o processo de trabalho para registrar os rastreamentos de alocação de memória. Avise-me se precisar de ajuda com isso.

@georgepsarakis Você quer dizer habilitar tracemalloc nas estatísticas de trabalho e registro, como os 10 principais arquivos de uso de memória, em um intervalo específico, como 5 minutos?

@jxltom Acho que algo assim ajudaria a localizar a parte do código que é responsável. O que você acha?

@georgepsarakis Eu tentei usar gdb e https://github.com/lmacken/pyrasite para injetar o processo de vazamento de memória e iniciar a depuração via tracemalloc. Aqui está o arquivo top 10 com maior uso de mem.

Eu uso resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 e o uso de memória 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

Aqui está a diferença entre dois instantâneos após cerca de 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

Alguma sugestão de como continuar a depurar isso? Não tenho ideia de como proceder. Obrigado.

@georgepsarakis

Quero um tempinho para cortar o projeto para reprodução.

É cenário de aipo.

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

O agendador possui as seguintes configurações.

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),
    },
}

No EC 2, estou usando o supervisord para operá-lo.

@georgepsarakis
Como meu ambiente de teste pode tolerar degradação de desempenho, você pode usar tracemalloc.
Você pode fazer um Celery corrigido para eliminar o uso de memória?

@jxltom aposto que tracemalloc com 5 minutos não ajudará a localizar o problema
Por exemplo, eu tenho 5 nós e apenas 3 deles tiveram esse problema nos últimos 4 dias, e 2 funcionaram bem todo esse tempo, então será muito complicado localizar o problema.
Eu sinto que há alguma chave que liga e então a memória começa a crescer, até que o consumo de memória dessa chave pareça muito bom

Tentei descobrir se problemas semelhantes ocorreram em outros sistemas em execução.
A frequência de ocorrência varia, mas ocorreu um vazamento de memória em três sistemas usando Celery 4.x, e não em um sistema.
O sistema que tem vazamento de memória é Python 3.5.x, e o sistema sem vazamento de memória é Python 2.7.x.

@ dmitry-kostin Qual é a diferença com os outros dois nós normais, eles estão usando o mesmo rabbitmq como corretor?

Como nossa discussão mencionou que pode estar relacionado ao rabbitmq, iniciei outro novo nó com a mesma configuração, exceto pelo uso de redis. Até agora, este nó não apresentou vazamento de memória após 24 horas de execução. Vou postar aqui se houver vazamento de memória mais tarde

@marvelph Então, você quer dizer que os três sistemas com vazamento de memória estão usando python3, enquanto o que está bom está usando python2?

@jxltom nenhuma diferença, e sim, eles estão no python 3 e no rabit como corretor e redis no backend
Fiz um exemplo de teste para reproduzir isso, se der certo em alguns dias darei credenciais a esses servidores para alguém que saiba como localizar esse bug

@jxltom
sim.
No que diz respeito ao meu ambiente, não ocorrem problemas no Python 2.

Eu rastreei o vazamento de memória por meio de tracemalloc dentro de um período mais longo.

O uso de memória inicial relatado pelo módulo resource é 146.58MB , após 3,5 horas, ele relata que o uso de memória é 224.21MB .

A seguir está a diferença de instantâneo relatada 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

Alguma ideia? Parece que não é um único arquivo que está vazando?

Eu também importei gc , e gc.collect() retorna 0 ...

@georgepsarakis Consegui reproduzir isso,

Atualização: Eu atualizei o corretor do rabbitmq para o redis atualizando o url do corretor como variável de ambiente e mantenho o docker / código completamente igual. E está funcionando por 4 dias e não há vazamento de memória .

Portanto, acredito que esse problema esteja relacionado com o corretor rabbitmq.

Se possível, tente executar o comando benchmark, mencionado aqui: https://github.com/celery/celery/issues/2927#issuecomment -171455414

Este sistema está executando workers com 20 servidores.
Um vazamento de memória ocorreu ontem, mas está ocorrendo em quase todos os servidores ao mesmo tempo.
memoryleak

Não sei se está relacionado, deixo aqui caso ajude.

Eu tenho um problema diferente com aipo e coelhomq (o aipo perde a conexão e começa a se reconectar várias vezes por segundo, a CPU fica 100% em 1 núcleo, a batida não pode enviar novas tarefas, é necessário reiniciar o aipo).

O motivo pelo qual estou relatando isso aqui é o gatilho: após dias de monitoramento, acho que localizei o início do problema e parece ser o rabbitmq movendo algumas mensagens da memória para o disco. Nesse momento, o aipo começa a tentar se reconectar o mais rápido possível e os registros do rabbitmq mostram dezenas de operações de conexão / desconexão por segundo, em lotes de aproximadamente 10 por vez. Reiniciar o rabbitmq não corrige o problema, reiniciar o aipo corrige imediatamente. Não tenho uma solução adequada, mas, por exemplo, definir uma política de expiração permitindo que as mensagens permaneçam sempre na memória contorna o problema e não o vi desde então.

Dado que alguns detalhes deste problema correspondem ao que eu vi (trocar o rabbitmq pelo redis corrige isso, não há um ponto de partida claro, isso acontece em mais de um trabalhador / servidor ao mesmo tempo) Eu acho que pode haver um gatilho comum e pode seja o mesmo que eu localizei.

O conjunto de testes foi alterado de https://github.com/celery/celery/tree/master/funtests/stress para https://github.com/celery/cyanide e suporta apenas Python2.

Então, eu o executo em Python2 com rabbitmq como corretor. Ele levantou !join: connection lost: error(104, 'Connection reset by peer') . Isso está relacionado ao problema de vazamento de memória?

Aqui está o log do conjunto de testes.

➜  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

Aqui está o registro do trabalhador.

➜  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') !

Eu atualizei para usar o aipo 3.1.25 com a mesma suíte de teste de estresse, está tudo bem.

A propósito, para todos que procuram uma solução rápida - substituir o coelho por redis resolve o problema como @jxltom sugeriu, só agora tenho mais de uma semana de trabalho estável com redis
Portanto, o problema está definitivamente em algum lugar perto da borda do aipo do coelho <->

@dieeasy , tivemos o mesmo problema. Presumo que você esteja usando back-end de resultado RPC. Em caso afirmativo, tente alternar para o back-end de resultado do banco de dados e veja se isso ajuda. O problema que causa isso é: https://github.com/celery/kombu/pull/779 e é explicado aqui: https://github.com/celery/kombu/pull/779#discussion_r134961611

Eu tenho o mesmo problema de vazamento de memória
Memória
image

Versão
python 3.6.5 aipo 4.2.1 backend redis corretor 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

`` `python

- - codificação: utf-8 - -

da fila de importação de kombu, Exchange
de log de importação de oslo_log como registro

de app.conf import CONF

LOG = logging.getLogger (__ name__)

celery_queues = (
Fila ('im', troca = Exchange ('remetente'), routing_key = 'im'),
Fila ('sms', troca = Exchange ('remetente'), routing_key = 'sms'),
Queue ('mail', exchange = Exchange ('sender'), routing_key = 'mail'),
Fila ('ivr', troca = Exchange ('remetente'), routing_key = 'ivr')
)

celery_routes = {
'sender.im': {'queue': 'im', 'routing_key': 'im'},
'sender.sms': {'queue': 'sms', 'routing_key': 'sms'},
'sender.mail': {'queue': 'mail', 'routing_key': 'mail'},
'sender.ivr': {'queue': '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())

Posso fornecer mais informações, se necessário.

Pelo que vale a pena, estou tendo esse problema e posso reproduzi-lo de forma consistente abrindo o console de gerenciamento rabbitmq, indo para conexões e fechando conexões com tráfego de aipo para rabbitmq.

Eu testei com aipo 4.1 e 4.2 e coelhomq 3.7.7-1
EDITAR: também python versão 3.6.5 e ubuntu 16.04 (imagem AWS EC2)

Estou tendo um vazamento de memória com o corretor de aipo 4.2.1 e redis. A memória cresce de 100 MiB para 500 MiB (limitada) em 3 horas, e os trabalhadores são marcados como offline em flor. O pool prefork e o gevent apresentam o mesmo problema.

@yifeikong, este pode não ser o mesmo problema, mas para o seu caso, você poderia tentar a solução proposta https://github.com/celery/celery/pull/4839#issuecomment -447739820?

@georgepsarakis Estou usando Python 3.6.5, então não fui afetado por esse bug. Vou usar tracemalloc para fazer algumas pesquisas. Se foi um bug do aipo, abrirei uma nova edição. Obrigado

Talvez a mesma causa com # 5047 , parece que esse bug pode levar a um fenômeno diferente.

Estamos enfrentando o mesmo vazamento de memória executando Celery 4.2.1, Kombu 4.2.2 e python3.6 com RabbitMQ como corretor.

$ 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

Posso dizer que tentamos muitas coisas que outras pessoas mencionaram como possíveis soluções alternativas (redis como corretor, usando jemalloc, libamqp, caminho do macaco __del__ em AsyncResult ), mas sempre acabamos tendo perda de memória.

Ao analisar nosso log, percebemos que tínhamos muitas mensagens relacionadas a batimentos cardíacos perdidos por fofoca.

{"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@******"}

Uma última coisa que tentamos foi desabilitar a fofoca gerando --without-gossip ; surpreendentemente, desabilitar a fofoca teve um efeito imediato.

Você pode vê-lo aqui:
celery-memory-14d

Desde que desativamos a fofoca em dois projetos que executam operários de aipo, o consumo de memória melhorou.

Se você prestar atenção, antes tínhamos picos de memória semelhantes aos descritos aqui https://github.com/celery/celery/issues/4843#issuecomment -399833781

Uma coisa que venho tentando entender completamente é quais são as implicações de uma fofoca completamente incapacitante, uma vez que ela é apenas descrita como comunicação do trabalhador <-> do trabalhador, se alguém pudesse esclarecer isso, eu ficaria muito grato.

Espero que isso ajude e obrigado pelo trabalho árduo.

Por que este problema foi encerrado?

Há feedback ativo e interesse neste assunto, por isso estou reabrindo.

Bem, @georgepsarakis, uma vez que diagnosticamos meu vazamento como não sendo o # 4839, e você suspeitou que fosse o # 4843, vou passar para este tópico de vazamento pelo menos por agora. Também não tenho certeza se # 4843 é meu vazamento. De acordo com o problema inicial neste tópico:

Este problema ocorre pelo menos no Celery 4.1 e também ocorre no Celery 4.2.
Celery está sendo executado no Ubuntu 16 e os corretores usam RabbitMQ.

Atualmente estou em:

python 2.7.12
Ubuntu 16.04.1 amd64
RabbitMQ 3.7.5

usando:

Aipo 4.1.1
librabbitmq 2.0.0
amqp 2.4.0
videira 1.1.4
bilhar 3.5.0.5
kombu 4.2.2.post1
gevent 1.2.2

No entanto, Celery 4.1.1 + gevent 1.2.2 não vaza para mim (nem Celery 3.1.25 + gevent 1.2.2 AFAICT); Aipo 4.2.1 + gevent 1.3.7 sim. Infelizmente, gevent 1.3.7 e gevent 1.2.2 não são intercambiáveis ​​para demonstrar (ou excluir) uma biblioteca gevent como uma possível fonte do problema.

EDIT: Hmm ... parece haver um patch gevent (022f447dd) que parece que pode corrigir o erro que encontrei. Vou tentar fazer isso funcionar.

Eu apliquei 022f447 ao Celery 4.1.1 e instalei gevent 1.3.7. Essa combinação Celery + gevent funcionou ... e produziu padrões de uso de memória consistentes com o vazamento que tenho experimentado. Vou instalar o Celery 4.2.1 + gevent 1.2.2 (com o patch reverso) e ver se obtenho o padrão de uso de memória normal.

Percebi que gevent 1.4.0 foi lançado. Talvez eu devesse dar uma olhada nisso também para ver como isso se comporta.

O Celery 4.2.1 + gevent 1.2.2 + patch reverso para gevent 1.2.2 não parece produzir o vazamento como o Celery 4.2.1 + gevent 1.3.7.

O aipo 4.2.1 + gevent 1.4.0 parece vazar aproximadamente na mesma taxa que o 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.

Agora, se eu entendi corretamente o que o AMQP faz sob o capô, então ele tem seu próprio batimento cardíaco e quando detecta uma conexão interrompida, ele segue em frente e se reconecta sob o capô. Dependendo dos tipos de eventos ativados (fofoca, pulsação), isso pode vazar muito rápido.
Isso deve ser verdadeiro para qualquer versão de eventlet & gevent, mas alguns podem apresentar problemas de conexão que tornam as coisas piores / mais perceptíveis.

Oi,

Suspeito que estamos tendo o mesmo problema.
Nossa configuração está abaixo. Posso negar ou confirmar que este é o mesmo problema discutido aqui?

Python: 2.7
Aipo: 4.2.1
SO: CentOS versão 6.10
Redis como corretora

Na imagem anexada você pode ver:

  1. O consumo de memória aumenta constantemente e diminui na reinicialização.
  2. Em 13 de janeiro - atualizamos do aipo 3.1.25 para o 4.2.1. O ritmo de aumento do consumo de memória cresce.

image

ATUALIZAR

Independentemente desse problema, atualizamos para o python 3.6 e, desde então, parece que o vazamento não acontece mais.

image
(a atualização foi em 19 de fevereiro)

@georgepsarakis

Não tenho certeza se isso é relevante, mas estou tendo meus 2 GB de espaço SWAP esgotados por aipo em produção. Parar Flower não limpou a memória, mas parar Celery sim.

Alguém poderia experimentar o aipo 4.3rc1?

@auvipy Eu instalei o Celery 4.3.0rc1 + gevent 1.4.0. pip atualizado bilhar para 3.6.0.0 e kombu 4.3.0.

Um tanto intrigado que o vine 1.2.0 também não foi exigido pelo pacote rc1, dado que o # 4839 foi corrigido por essa atualização.

De qualquer forma, o Celery 4.3.0 rc1 parece funcionar bem.

@ ldav1s muito obrigado pelo feedback. Portanto, vine é declarado como uma dependência em py-amqp, na verdade. Em novas instalações, a versão vine recente será instalada, mas isso pode não acontecer nas existentes.

@thedrow talvez devêssemos declarar a dependência nos requisitos do Celery também?

Vamos abrir uma questão sobre isso e discutir lá.

Celery 4.3.0rc1 + gevent 1.4.0 já está em execução há alguns dias. Parece que está vazando da mesma maneira que Celery 4.2.1 + gevent 1.4.0.

image

Tendo o mesmo vazamento com aipo 4.2.1, python 3.6

Alguma atualização sobre isso?

tendo o mesmo problema aqui

Saudações,

Estou enfrentando um problema semelhante, mas não tenho certeza se é o mesmo.

Depois de migrar nosso aplicativo de aipo em um ambiente / rede diferente, os trabalhadores de aipo começaram a vazar. Anteriormente, o aplicativo aipo e a instância rabbitmq estavam no mesmo ambiente / rede.

Minha configuração está em 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)

celeryconfig

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

A aplicação é composta por vários workers com pool de eventos, iniciados via comando no 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

O comportamento do vazamento de memória se parece com isto, a cada ~ 10 horas geralmente 1 trabalhador, no máximo 2 começam a vazar:
image

Então criei uma mensagem de broadcast para ser executada em cada worker, por usar tracemalloc, esse é o resultado do comando top na máquina, há 1 worker vazando apenas com 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 no trabalhador com vazamento

[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 com 25 frames

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 possa ajudar, não há nenhum erro nos logs, além da pulsação perdida entre os trabalhadores. Agora estou tentando usar a versão exata das libs que estávamos usando no antigo env.

ATUALIZAÇÃO: Usando as mesmas dependências exatas versões lib e uma pulsação do corretor a cada 5 minutos, o aplicativo parecia estável por mais tempo: mais de 2 dias, do que vazou novamente.

Houve um pequeno pico continuando por ~ 1 hora de cada vez, mas foram "absorvidos / coletados" .. o último parece ter iniciado o pico.

Após o 1º pico, 1ª rampa, reiniciei o trabalhador com vazamento .. como vocês podem ver outro trabalhador começou a vazar depois dele ou provavelmente já estava vazando, 2ª rampa.

image

Vou testar sem batimento cardíaco.

ATUALIZAÇÃO: sem batimento cardíaco vazou novamente após 2 dias, mesmo comportamento

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

ATUALIZAR:
Usando o aipo 4.3.0 parece que o problema está resolvido e está estável desde uma 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, deixe-me saber se eu puder ajudar de alguma forma, instrumentando o código. Se necessário forneça links e exemplo, por favor.

Obrigada

Também estou tendo um vazamento de memória. Parece que consegui encontrar a causa.
https://github.com/celery/celery/blob/master/celery/events/dispatcher.py#L75
Posso ver que este buffer começa a crescer após problemas de conexão com o coelho. Eu não entendo por que ele falha em limpar eventos eventualmente, ele continua a crescer com o tempo e consumir mais e mais memória RAM. Passar buffer_while_offline=False aqui https://github.com/celery/celery/blob/master/celery/worker/consumer/events.py#L43 parece consertar o vazamento para mim. Alguém pode verificar se isso está relacionado?

@ yevhen-m muito obrigado! Isso nos ajudou a resolver o vazamento de memória!

É bom termos uma solução alternativa, mas podemos encontrar uma solução adequada?

contínuo segue este problema de vazamento de memória

image

celery-pod-screencshot-lastweek

Estou usando aipo em um ambiente de produção e o estou implantando via docker.
Como na captura de tela, estamos tendo o mesmo problema.
Nossa configuração de produção é mostrada abaixo.

Imagem pai do Docker: python 3.6.8-buster
Versão de aipo: 4.2.0
Opções de comando:

  • simultaneidade 4
  • pré-busca-multiplicador 8
  • Sem result_backend
  • acks_late e rejeitar_on_worker_lost

Eu me pergunto se atualizar a versão do aipo para 4.3.0 resolve o problema de vazamento de memória.

Obrigada!

o aipo 4.4.0 é o mais recente estável

Equipe, há alguma atualização sobre esse problema? Isso foi tratado e corrigido no aipo 4.4.0?

Equipe, há alguma atualização sobre esse problema? Isso foi tratado e corrigido no aipo 4.4.0?

Infelizmente não. Agora está endereçado.

Equipe, há alguma atualização sobre esse problema? Isso foi tratado e corrigido no aipo 4.4.0?

estará disponível em 4.4.1

estará disponível em 4.4.1

foi corrigido na versão atual 4.4.1?

@auvipy O problema ainda está presente no Celery 4.4.2 e 4.4.6. Vemos os mesmos vazamentos de memória em todos os trabalhadores.

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,
}

O trabalhador de aipo é iniciado com sinalizadores -O fair --without-heartbeat --without-gossip -c 1 -l . Também usamos os sinalizadores -n e -Q para definir o nome do trabalhador e as filas. Executando no modo pré-garfo. O Redis está configurado como corretor e armazenamento de resultados.

image

~ Vemos muitos batimentos cardíacos perdidos em tarefas de longa duração. Portanto, o problema relatado em questões vinculadas ainda persiste. ~

É o mesmo com os batimentos cardíacos deficientes.

@jsynowiec Quando enfrentei esse problema, a única coisa que funcionou para mim foi administrar os trabalhadores com fofoca desativada, mencionei algo sobre isso aqui https://github.com/celery/celery/issues/4843#issuecomment -459789086

Estamos enfrentando o mesmo problema com o aipo 4.4.2 e redis como corretor. Durante o período de 48 horas, o aipo consome até 60 GB de RAM até ficar sem memória.
Nenhuma das soluções aqui citadas teve qualquer efeito nesse comportamento.

Estamos enfrentando o mesmo problema com o aipo 4.4.2 e redis como corretor. Durante o período de 48 horas, o aipo consome até 60 GB de RAM até ficar sem memória.
Nenhuma das soluções aqui citadas teve qualquer efeito nesse comportamento.

Você tentou nossa versão de patch mais recente?
Você tem as mesmas condições do OP?

Vazamentos de memória ainda estão presentes na v4.4.6. Executamos workers com configurações listadas em um comentário anterior . OP usa RabbitMQ, nós usamos Redis como um corretor.

image

+1, percebendo que o uso da memória aumenta gradualmente ao longo de 24 horas, mesmo com o mínimo de trabalho sendo feito. Acho que essa questão deveria ser reaberta.

você pode criar um perfil e descobrir a raiz do seu vazamento de memória?

Vazamentos de memória ainda estão presentes na v4.4.6. Executamos workers com configurações listadas em um comentário anterior . OP usa RabbitMQ, nós usamos Redis como um corretor.

image

Parece que este é um problema diferente ou que nossa correção não foi correta.
Como isso resolveu o problema do OP, provavelmente é um problema diferente, certo?

[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

Perda de memória no cliente Redis? Estou usando o aipo v4.4.6 com gevent, redis como corretor e nenhum back-end de resultado.

Talvez isso também seja um problema. Talvez esteja no gevent?
CC @jamadden @andymccurdy
Você pode nos ajudar a resolver esse problema e garantir que não haja vazamento de memória do seu lado?

Talvez esteja no gevent?

Não estamos usando gevent . Os trabalhadores são iniciados com simultaneidade = 1 e prefork.

Olá pessoal, não sei por que esse problema foi resolvido. Estamos tendo esse problema há 2 anos, atualizando para a última versão do Celery todas as vezes e ainda tendo grandes servidores (64-128 GB de RAM) constantemente ficando sem RAM porque desses problemas de vazamento de memória.

Existe alguma solução alternativa sem fazer o downgrade para o Celery 3 ou substituir o Rabbitmq?

Isso torna o Celery completamente instável em ambientes de produção, espero que possa ser consertado, não podemos fazer o downgrade para o Celery 3, então estamos planejando mudar para outra solução (talvez Dramatiq) para parar de nos preocupar com o Celery consumindo toda a RAM dos servidores produção a cada 2 dias.

@arielcamino - Tenho usado a configuração worker_max_tasks_per_child para substituir instâncias de trabalho após 100 ~ tarefas, o que ajudou a manter o uso de memória, pelo menos para meus servidores. Estou executando pequenas instâncias de 512 MB e isso ajudou (anteriormente exauriria minha memória ram), então talvez ajude você.

@Skowt uau, isso é super útil, muito obrigado! Vou tentar agora.

@arielcamino - Tenho usado a configuração worker_max_tasks_per_child para substituir instâncias de trabalho após 100 ~ tarefas, o que ajudou a manter o uso de memória, pelo menos para meus servidores. Estou executando pequenas instâncias de 512 MB e isso ajudou (anteriormente exauriria minha memória ram), então talvez ajude você.

Obrigado por compartilhar sua solução alternativa. Isso não ajudou aqui - no entanto, estamos usando o redis.

@thedrow Não estou ciente de nenhum vazamento de memória no redis-py. Se o redis-py tiver um vazamento, presumo que alguém o teria encontrado fora do ambiente do Celery e relatado ao rastreador de problemas do redis-py.

Fico feliz em ajudar onde posso (eu uso o Celery com Redis como corretor em vários projetos), mas não encontrei esse problema em minhas implantações.

Não estou ciente de nenhum vazamento de memória nas versões atuais do gevent. Eu suponho (espero) que alguém teria dito algo se encontrasse isso (já aconteceu uma ou duas vezes antes). Minhas implantações atuais do gevent têm vários trabalhadores (web e plano de fundo) por semanas a fio usando intensamente o gevent e não encontramos vazamentos de memória.

Olá pessoal, não sei por que esse problema foi resolvido. Estamos tendo esse problema há 2 anos, atualizando para a última versão do Celery todas as vezes e ainda tendo grandes servidores (64-128 GB de RAM) constantemente ficando sem RAM porque desses problemas de vazamento de memória.

Existe alguma solução alternativa sem fazer o downgrade para o Celery 3 ou substituir o Rabbitmq?

Isso torna o Celery completamente instável em ambientes de produção, espero que possa ser consertado, não podemos fazer o downgrade para o Celery 3, então estamos planejando mudar para outra solução (talvez Dramatiq) para parar de nos preocupar com o Celery consumindo toda a RAM dos servidores produção a cada 2 dias.

Quantos trabalhadores você tem? Quantas tarefas você executa? Com que frequência você executa essas tarefas e quanto tempo geralmente levam para serem concluídas?

A razão pela qual o Rabbitmq / aipo começa a usar muito RAM pode estar relacionada à quantidade de tarefas enfileiradas. Se você enfileirar muitas tarefas e os trabalhadores não puderem concluí-las todas, isso aumentará a fila e essa fila usará cada vez mais RAM e, eventualmente, consumirá toda a RAM disponível. Acredito que esse problema também possa acontecer com o Redis.

Eu tenho outra teoria, mas primeiro quero saber se essa pode ser a razão do seu problema.

@ardilom desculpe, acabei de perceber que não estamos enviando dados do RabbitMQ para o datadog, mas tentarei esclarecer nossa situação, é assim que a RAM de alguns servidores cai a cada 2 dias:
memory-leaks-1

Sempre verificamos o número de tarefas pendentes e normalmente está em torno de 0 (esses dados são de alguns dias atrás):

memory-leaks-2

Executamos cerca de 250.000 tarefas por dia, temos cerca de 10 trabalhadores, cada um com cerca de 4 a 10 simultaneidade, o tempo médio de execução é em torno de 5 segundos, depende do tipo de tarefa.

Sempre verificamos messages_ready para ter certeza de que não há muitas tarefas na fila (isso é o que você vê na segunda imagem), você acha que pode medir messages_ready ? Eventualmente, temos alguns picos, mas normalmente estão próximos de 0.

Para resolver o problema, eu apenas reinicio o trabalhador do Celery manualmente e o uso de RAM volta ao normal.

Avise-me se precisar de mais alguma coisa, acabei de alterar a configuração de worker_max_tasks_per_child em um dos servidores de tarefas, para ver se há alguma diferença com o restante deles após aplicar a configuração.

Obrigado!

Olá pessoal, isto é para confirmar que alterar worker_max_tasks_per_child para 1000 no meu caso corrigiu o problema 🎉 obrigado novamente @Skowt

Algo que não mencionei ontem, estou usando o modo "prefork", talvez passar para gevent seja outra maneira de resolver o problema.

@arielcamino Este problema foi resolvido porque resolvemos um vazamento de memória específico. Ainda temos que encontrar outra causa para o vazamento de memória. Sabemos que existe um problema, mas não sabemos como reproduzi-lo.
Precisamos de alguém com acesso a um ambiente de produção onde o bug se reproduz para depurar o problema.
Se não tivermos um, teremos que determinar se esse problema não pode ser resolvido.

Olá, podemos reabrir este problema? Estamos experimentando vazamentos semelhantes, usando aipo == 4.4.7 (com rabbitmq) temos o trabalhador funcionando de maneira estável por algumas horas, às vezes muito mais, e então de repente começa a vazar lentamente e acaba usando toda a memória.

Atualmente usando prefork com --concurrency=1 e a sinalização --max-tasks-per-child=100 que não parece ajudar, já que o processo pai parece ser o que está vazando.

celery_leak

Posso fornecer mais informações para ajudar a depurar esse problema.

Olá, podemos reabrir este problema? Estamos experimentando vazamentos semelhantes, usando aipo == 4.4.7 (com rabbitmq) temos o trabalhador funcionando de maneira estável por algumas horas, às vezes muito mais, e então de repente começa a vazar lentamente e acaba usando toda a memória.

Atualmente usando prefork com --concurrency=1 e a sinalização --max-tasks-per-child=100 que não parece ajudar, já que o processo pai parece ser o que está vazando.

celery_leak

Posso fornecer mais informações para ajudar a depurar esse problema.

reabrir o problema não é grande coisa, é o interesse de alguém que enfrenta isso na produção e ajuda a rastrear e contribuir para uma correção ou pelo menos descobrir a causa raiz do vazamento na produção.

Definitivamente posso ajudar, mas fiquei sem ideias sobre o que fazer. Usei algumas ferramentas, mas não consegui identificar muito sobre o problema. A única coisa que limita isso são os instantâneos tracemalloc que tirei, que mostram o aumento da memória nos mesmos lugares a cada dois minutos ou assim. Estes são os 10 primeiros comparando dois instantâneos:

/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

O problema ainda existe
Isso acontece quando uma tarefa de aipo acessa o contexto do aplicativo para fazer uma funcionalidade
Não vai liberar ou descartá-lo após realizar a tarefa

--max-tasks-per-child=

não foi útil

Olá, podemos reabrir este problema? Estamos experimentando vazamentos semelhantes, usando aipo == 4.4.7 (com rabbitmq) temos o trabalhador funcionando de maneira estável por algumas horas, às vezes muito mais, e então de repente começa a vazar lentamente e acaba usando toda a memória.
Atualmente usando prefork com --concurrency=1 e a sinalização --max-tasks-per-child=100 que não parece ajudar, já que o processo pai parece ser o que está vazando.
celery_leak
Posso fornecer mais informações para ajudar a depurar esse problema.

reabrir o problema não é grande coisa, é o interesse de alguém que enfrenta isso na produção e ajuda a rastrear e contribuir para uma correção ou pelo menos descobrir a causa raiz do vazamento na produção.

para mim, se eu adicionar --max-tasks-per-child , funciona.
como para este exemplo de argumentos --autoscale=5,2 --max-tasks-per-child=40 o resultado é assim

Screenshot 2020-08-13 at 2 26 13 PM

Embora eu acredite que uma atualização recente de aipo tenha introduzido o vazamento de memória, não posso estar totalmente confiante. Vou compartilhar que a configuração a seguir resolveu o vazamento.

Não posso dizer quais configurações são válidas pela documentação, então estou configurando todos esses valores no meu arquivo de configurações do Django.

CELERY_CONCURRENCY = CELERY_WORKER_CONCURRENCY = 1
CELERY_MAX_TASKS_PER_CHILD = CELERY_WORKER_MAX_TASKS_PER_CHILD = 1

Isso não resolve o vazamento que estamos vendo, como também acontece na piscina do gevent. O que percebi é que a fila do celeryev está bem ocupada. Como o tracemalloc mostrou o envio de evento como uma das possíveis fontes para o vazamento, desativei explicitamente os eventos de tarefa e desativei nossa instância de flor, por enquanto parece que o vazamento não está mais acontecendo, vou deixá-lo funcionar durante o fim de semana e compartilhar os resultados aqui.

possíveis fontes para o vazamento Desativei explicitamente os eventos de tarefa e desativei nossa instância de flor

Ponto de dados anedótico de alguém que tem observado este problema silenciosamente desde o início (e nunca experimentou diretamente): Estou ciente de um outro projeto (com uma carga de trabalho não insubstancial para aipo) em que fazer o acima teve o mesmo resultado de parando um vazamento de memória. Tendo apenas informações de segunda mão, eu _obviamente_ não posso confirmar que era o mesmo problema subjacente (AFAIK era rabbitmq, nenhuma ideia sobre gevent etc), mas é interessante que isso se correlaciona.

Suspeito que tenha algo a ver com a conexão rabbitmq de alguma forma, a pilha que temos observado este vazamento:

  • aipo (versão mais recente): pré-garfo ou piscina gevent, ambos mostram o mesmo padrão de vazamento.
  • rabbitmq (cloudamqp SaaS)
  • Flor

Verificamos todas as nossas tarefas em busca de vazamentos e não conseguimos encontrar nenhum, então é por isso que suspeito de ser algo do lado do aipo.

Um fato interessante é que atualmente temos muitos trabalhadores em execução, e percebi que, uma vez que um começa a vazar, também aparece na flor como offline.

Quando fiquei sem ideias sobre onde procurar, desativei eventos de flores e tarefas e continuarei monitorando se o vazamento voltará ou não.

Estou aberto a acreditar que é outra parte da minha pilha que está perdendo memória neste momento. O aipo pode ter tido um comportamento acidental no passado que contribuiu para controlar vazamentos de memória, mas todos nós juntos não parecemos ter problemas semelhantes o suficiente para confirmar isso. Eu sei que muitos de nós estão correndo ...

  • Um grande número de tarefas aninhadas de uma vez, ou
  • Alguns monolíticos que iniciam o processamento de vários núcleos dentro do trabalhador

Nesses casos, só precisamos ser inteligentes ao permitir ou proibir um certo nível de simultaneidade, enfileiramento de tarefas e tarefas por criança trabalhador. Além disso, todos nós devemos usar proteções integradas que podem eliminar tarefas que exigem muita memória antes que tenham a oportunidade de travar nossos servidores.

Um número crescente de pessoas está executando processos pesados ​​de CPU e memória no aipo, para o qual ele não foi realmente feito, então acho que a documentação de início rápido deve incluir mais detalhes sobre isso.

Como já mencionado em meus comentários anteriores, estamos executando workers com max-tasks-per-child e simultaneidade definida como 1 há muito tempo. Ele não faz nada sobre o vazamento de memória. Além disso, estamos usando o Redis como corretor e backend de resultados.

Pelas minhas observações, quando RabbitMQ é usado como um corretor, se definir max-tasks-per-child para 1 "resolver" o vazamento de memória, é mais provável que seja um problema com a implementação da tarefa, não aipo.

O que estamos observando e relatando é diferente. Mesmo se deixarmos o trabalhador ocioso por vários dias, sem processar uma única tarefa, ele ainda vaza memória a um ponto em que atinge o limite de memória e é morto pelo supervisor. Você pode encontrar mais detalhes e gráficos de memória em comentários anteriores.

Com o trabalhador processando uma única tarefa na programação, o gráfico de memória deve mostrar mais ou menos uma onda quadrada, mas você pode ver claramente que o uso geral da memória só aumenta.
Screenshot 2020-08-14 at 20 42 24

Consegui colocar o perfil dos trabalhadores do aipo em nosso roteiro. Compartilharei despejos de memória e mais detalhes quando começarmos a trabalhar nisso.

Posso confirmar que desligar o flower (e desabilitar explicitamente os eventos de tarefa por meio das configurações) corrigiu o vazamento.

Como mencionei antes, no momento em que a operária começou a vazar notei na flor que ficava offline e o aipo sempre se mostrava bastante ocupado, então segui pelo caminho mais fácil e desliguei a flor.

Infelizmente, não consegui encontrar o código que causa o vazamento. Mas pelo menos existe esta solução alternativa.

então provavelmente este não é um problema de aipo, mas flor?

A flor

A flor

justo. obrigado por compartilhar.

Estou usando o aipo com Redis e Flower e devo dizer que não estou vendo nenhum problema de memória no momento. Qualquer coisa que você possa querer de mim em relação aos dados?

@auvipy não está usando Flower. Os trabalhadores são iniciados com eventos desabilitados.

@auvipy não está usando Flower. Os trabalhadores são iniciados com eventos desabilitados.

tente depurar e descobrir a raiz do vazamento de memória. poderia ser aipo ou seu poderia. seria melhor se você pudesse compartilhar testes de unidade e integração

tente depurar e descobrir a raiz do vazamento de memória. poderia ser aipo ou seu poderia. seria melhor se você pudesse compartilhar testes de unidade e integração

Mencionado aqui , que vemos OOMs devido ao vazamento de memória do trabalhador aipo, mesmo que nenhuma tarefa seja processada pelo trabalhador.
Não é possível compartilhar testes de unidade ou integração, pois isso exporia o IP da empresa. Desculpe. Mas consegui adicionar uma tarefa para capturar despejos de memória em trabalhadores de produção em nosso roteiro interno. Irá compartilhar contadores e referências para alguns cenários quando estiver pronto.

@jsynowiec Se você puder fazer antes de 5.0.0 GA (siga # 6266 para atualizações), seria incrível.

Assim que uma correção de bug chegar ao master, ela será portada para 4.x também.

@thedrow Quando o GA de 5.0 é planejado? Infelizmente, temos alguns códigos legados que ainda serão migrados para Py3 😞, então estamos presos ao Celery 4 por enquanto.

Temos um bloqueador de liberação e alguma documentação para completar.
A resposta é muito em breve.

Posso confirmar que desligar a flor interrompe o vazamento. Faz quase um mês que corremos sem vazamento.

Portanto, ainda há um bug em algum lugar em nosso mecanismo de publicação de eventos.
Alguém tem ideia do que poderia ser?

Não usamos o Flower e os workers são iniciados sem --events , mas observamos vazamentos de memória contínuos.

A resposta é muito em breve.

Consegui atribuir alta prioridade para obter despejos de memória e contadores de objetos dos trabalhadores de produção. Devo ser capaz de postar alguns dados nas próximas semanas. Também elevamos a prioridade na finalização da portabilidade py2-> py3, então tudo deve ser executado e ter seu perfil criado, usando Python 3

O que me preocupa é que estamos falando de duas questões diferentes aqui.

Aparentemente. Um está relacionado a eventos e talvez Flower, talvez também usando RabbitMQ como corretor. De acordo com os problemas relatados aqui, no GitHub, ele vem à tona aqui e ali há alguns anos. O outro (que afeta meu projeto) está relacionado a diferentes componentes e, provavelmente, relacionado ao uso do Redis como corretor. Ou talvez na raiz, esses são os mesmos problemas que se originam no mesmo código quem sabe 🤷🏼. Como aquele com trail AsyncResult rastreando subtarefas e ocorrendo vazamento de

@thedrow @auvipy Informamos que agora estamos migrando para a criação de perfis de memória dos trabalhadores.

Além disso, ao finalizar a migração do Python3, encontramos outro problema que parece relacionado a https://github.com/celery/celery/issues/4470 ou https://github.com/celery/celery/issues/5359. Sob certas condições em sistemas Linux, ao usar o Redis como corretor, as chamadas para join_native suspensas indefinidamente, apesar de todas as tarefas dentro do grupo já terem sido realizadas. Strace rápido aponta para ele literalmente pendurado na leitura, o que pode indicar algumas coisas de kernel / lib de baixo nível. Por enquanto, mudamos para simples, agrupando join enquanto nos concentramos em vazamentos de memória.

Olá a todos - finalmente _alguns_ dados: celery-memtrace-1.tar.xz , assinatura , minha chave .

O arquivo contém tracemalloc logs de 8 trabalhadores após ~ 16 dias, um gráfico de uso de memória para o período e algumas informações de versão (incluindo banner de inicialização do Celery).

Honestamente, não passei um tempo significativo analisando nada disso, mas a) nosso código nunca esteve na lista, b) pode muito bem ser uma interação estranha com SQLAlchemy que também usamos em todos os lugares, então não é impossível que o problema está em outro lugar, ou é um problema de combinação / interação.

Se quaisquer outros detalhes forem úteis, pergunte. Também continuamos a executar esses 8 trabalhadores com esse registro de uso de memória, então talvez possamos coletar mais / melhores dados.

EDIT : Além disso, este comentário deste tópico está relacionado - ainda usamos as mesmas configurações.

Espero que você encontre a causa raiz desse vazamento.
Vou tentar encontrar algum tempo para me aprofundar nisso.

Eu me pergunto se isso poderia ajudar a mitigar o problema.
https://reliability.substack.com/p/run-python-servers-more-efficiently

Estamos investigando a possibilidade de que a origem dos vazamentos de memória esteja na biblioteca de solicitações e não no aipo em si. Alguém mais que está experimentando vazamentos de memória no aipo usando solicitações nas tarefas?

@ErrorInPersona Sim, estamos registrando OOMs em workers com e sem solicitações semelhantes.

@drbig Teve sorte?

Screenshot_2020-11-17_12-56-28

Bem, olhe para o "verde", o piso está subindo, lenta mas seguramente ... Então, exceto por uma rápida confirmação de "sim, ainda é um problema", não há muito a acrescentar da minha parte, infelizmente.

No entanto, dei uma olhada no link fornecido por - try running some workers with jemalloc forced in , então irei chegar lá, _eventualmente_.

Esta página foi útil?
0 / 5 - 0 avaliações