Celery: Непрерывная утечка памяти

Созданный на 23 июн. 2018  ·  129Комментарии  ·  Источник: celery/celery

Утечка памяти в родительском процессе рабочего Celery.
Это не дочерний процесс, выполняющий задачу.
Это случается внезапно каждые несколько дней.
Если вы не остановите Celery, он потребляет память сервера за десятки часов.

Эта проблема возникает, по крайней мере, в Celery 4.1, но также встречается в Celery 4.2.
Celery работает на Ubuntu 16, а брокеры используют RabbitMQ.

memory

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

Самый полезный комментарий

Почему закрыли этот вопрос?

Все 129 Комментарий

Вы используете рабочие процессы Canvas? Может быть, # 4839 имеет отношение.

Также я предполагаю, что вы используете пул prefork для параллелизма рабочих?

Спасибо georgepsarakis.

Я не использую рабочий процесс.
Я использую prefork concurrency 1 на одном сервере.

Скорость увеличения кажется довольно линейной, довольно странной. Обрабатывает ли воркер задачи в течение этого периода времени? Кроме того, можете ли вы добавить примечание с полной командой, которую вы используете для запуска воркера?

Да. Рабочий продолжает нормально обрабатывать задачу.

Рабочий запускается следующей командой.

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

Эта проблема возникает как в производственной, так и в тестовой среде.
Я могу добавить профиль памяти и тестовый результат в тестовую среду.
Если я могу что-нибудь сделать, пожалуйста, скажите что-нибудь.

Нам нужно понимать, что работает воркер в то время, когда наблюдается увеличение памяти. Любая информация и подробности, которые вы можете предоставить, обязательно будут. Также хорошо, что вы можете это воспроизвести.

Хотя это был случай, произошедший во время, отличное от графика, следующий журнал был выведен в то время, когда началась утечка памяти.

[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

Похоже, это произошло при временном отключении связи с RabbitMQ.

@marvelph, так это происходит во время переподключений RabbitMQ? Возможно, эти проблемы связаны:

Да.
Похоже переподключение срабатывает.

Похоже, у меня такая же проблема ... Мне так сложно понять, что ее вызывает и почему происходит утечка воспоминаний. Меня это раздражает минимум месяц. Я прибегаю к использованию сельдерея 3, и все в порядке.

Для проблемы с утечкой памяти я использую ubuntu 16, celery 4.1.0 с rabbitmq. Развернул через докер.

Утечка памяти связана с MainProcess, а не с ForkPoolWorker. Использование памяти ForkPoolWorker является нормальным, но использование памяти MainProcess постоянно увеличивается. В течение пяти секунд просачивается около 0,1 МБ памяти. Утечка памяти начинается не сразу после начала работы, а может быть через один-два дня.

Я использовал gdb и pyrasite для внедрения запущенного процесса и пытался gc.collect() , но ничего не собиралось.

Я проверил журнал, произошла consumer: Connection to broker lost. Trying to re-establish the connection... , но пока я не уверен, что это время, когда происходит утечка памяти.

Есть какие-нибудь подсказки по устранению этой проблемы и выяснению того, что происходит на самом деле? Спасибо.

Поскольку @marvelph упомянул, что это может быть связано с повторным подключением rabbitmq, я пытаюсь остановить свой сервер rabbitmq. Использование памяти увеличивалось после каждого повторного подключения, ниже приводится журнал. Итак, я могу подтвердить эту проблему https://github.com/celery/kombu/issues/843 .

Но после переподключения соединения использование памяти перестает постепенно увеличиваться. Так что я не уверен, что это причина утечки памяти.

Я попытаюсь использовать redis, чтобы выяснить, связана ли эта проблема с утечкой памяти с rabbitmq или нет.

[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

Хотя я проверил журналы, я нашел журнал повторного подключения во время утечки памяти, но также был случай, когда утечка памяти началась в момент, когда повторное подключение не произошло.
Я согласен с идеей jxlton.

Также, когда я использовал Celery 3.x, я не сталкивался с такой проблемой.

такая же проблема здесь
screenshot 2018-06-25 11 09 22
Каждые несколько дней мне приходится перезапускать воркеров из-за этой проблемы
в логах нет каких-либо значимых зацепок, но у меня есть подозрение, что повторное подключение может повлиять; так как я повторно подключил записи журнала где-то во времени, когда память начинает постоянно расти
Моя конфигурация - ubuntu 17, 1 сервер - 1 рабочий с 3 параллелизмом; кролик и редис на бэкэнде; все пакеты - последние версии

@marvelph @

конфиг близок к дефолту

import = ('app.tasks',)
result_persistent = Верно
task_ignore_result = Ложь
task_acks_late = Верно
worker_concurrency = 3
worker_prefetch_multiplier = 4
enable_utc = Истина
timezone = 'Европа / Москва'
broker_transport_options = {'visibility_timeout': 3600, 'confirm_publish': True, 'fanout_prefix': True, 'fanout_patterns': True}

screenshot 2018-06-25 11 35 17
В основном это новый развернутый узел; развернут 21.06 18-50; начал расти 23.06 около 05-00 и наконец разбился 23.06 около 23-00

задача довольно проста и в ней нет суперлогики, я думаю, что смогу воспроизвести всю ситуацию на четком временном проекте, но пока у меня нет свободного времени, если мне повезет, я постараюсь сделать полный пример на выходных

UPD
Как вы можете видеть, сама задача потребляет некоторую память, вы можете видеть это по пикам на графике, но в то время, когда память начала просачиваться, не было никаких задач или каких-либо других действий

@marvelph @ @jxltom Я заметил, что вы используете Python3. Не могли бы вы включить tracemalloc для процесса? Возможно, вам потребуется исправить рабочий процесс, чтобы записывать трассировки выделения памяти, дайте мне знать, если вам понадобится помощь с этим.

@georgepsarakis Вы имеете в виду включить tracemalloc в статистике рабочих и журналов, например в 10 самых популярных файлах использования памяти, с определенным интервалом, например, 5 минут?

@jxltom Я думаю, что что-то подобное поможет найти ту часть кода, которая отвечает за это. Как вы думаете?

@georgepsarakis Я пытался использовать gdb и https://github.com/lmacken/pyrasite для внедрения процесса утечки памяти и запуска отладки через tracemalloc. Вот 10 лучших файлов с наибольшим использованием памяти.

Я использую resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024 и использование памяти действительно постепенно увеличивается.

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

Вот разница между двумя снимками примерно через 5 минут.

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

Есть предложения, как продолжить отладку? Я понятия не имею, как действовать дальше. Спасибо.

@georgepsarakis

Хочу немного времени вырезать проект для воспроизведения.

Это настройка из сельдерея.

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

Планировщик имеет следующие настройки.

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

На EC 2 я использую supervisord для управления им.

@georgepsarakis
Поскольку моя тестовая среда может терпеть снижение производительности, вы можете использовать tracemalloc.
Можете ли вы сделать пропатченный Celery для сброса использования памяти?

@jxltom Я уверен, что tracemalloc за 5 минут не поможет найти проблему
Например, у меня 5 узлов, и только 3 из них имели эту проблему в течение последних 4 дней, а 2 работали нормально все это время, поэтому будет очень сложно найти проблему ..
Я чувствую, что есть какой-то переключатель, который включается, а затем память начинает расти, пока потребление памяти этим переключателем не будет выглядеть очень хорошо

Я попытался выяснить, возникали ли подобные проблемы в других работающих системах.
Частота возникновения различается, но утечка памяти произошла в трех системах, использующих Celery 4.x, и не произошла в одной системе.
Система с утечкой памяти - Python 3.5.x, а система без утечки памяти - Python 2.7.x.

@ dmitry-kostin В чем разница с двумя другими обычными узлами, используют ли они один и тот же rabbitmq в качестве брокера?

Поскольку в нашем обсуждении упоминалось, что это может быть связано с rabbitmq, я запустил еще один новый узел с той же конфигурацией, за исключением использования вместо него redis. Пока что этот узел не имеет утечки памяти после 24 часов работы. Я выложу его здесь, если у него будет утечка памяти позже

@marvelph Значит, вы имеете в виду, что три системы с утечкой памяти используют python3, а та, которая в порядке, использует python2?

@jxltom вообще никакой разницы, и да, они на python 3 и rabit в качестве брокера и redis на бэкэнде
Я сделал тестовый пример, чтобы воспроизвести это, если это удастся через пару дней, я дам учетные данные этим серверам для тех, кто знает, как найти эту ошибку.

@jxltom
Да.
Что касается моей среды, в Python 2 проблем не возникает.

Я отслеживал утечку памяти через tracemalloc в течение более длительного периода.

Начальное использование памяти, о котором сообщает модуль resource составляет 146.58MB , по прошествии 3,5 часов он сообщает об использовании памяти 224.21MB .

Ниже приведена разница снимков, о которой сообщает 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

Любые идеи? Похоже, не течет ни один файл?

Я также импортировал gc , а gc.collect() возвращает 0 ...

@georgepsarakis Мне удалось воспроизвести это, пингуйте меня, чтобы получить доступ к кредитам

Обновление: я обновил брокера с rabbitmq до redis, обновив URL-адрес брокера как переменную среды и сохранив docker / code полностью таким же. И работает 4 дня и утечки памяти нет .

Поэтому я считаю, что эта проблема связана с брокером rabbitmq.

Если возможно, попробуйте запустить команду тестирования, упомянутую здесь: https://github.com/celery/celery/issues/2927#issuecomment -171455414

В этой системе работают рабочие с 20 серверами.
Вчера произошла утечка памяти, но она происходит почти на всех серверах одновременно.
memoryleak

Не знаю, связано ли это, оставив это здесь, на случай, если это поможет.

У меня другая проблема с сельдереем и rabbitmq (сельдерей теряет соединение и начинает повторно подключаться много раз в секунду, процессор работает на 100% на 1 ядре, beat не может отправлять новые задачи, необходимо перезапустить сельдерей).

Причина, по которой я сообщаю об этом, является триггером: после нескольких дней мониторинга я думаю, что обнаружил начало проблемы, и похоже, что rabbitmq перемещает некоторые сообщения из памяти на диск. В это время сельдерей начинает пытаться повторно подключиться так быстро, как это возможно, и журналы rabbitmq показывают десятки операций подключения / отключения в секунду, партиями по ~ 10 или около того за раз. Перезапуск rabbitmq не решает проблему, перезапуск сельдерея сразу же устраняет ее. У меня нет правильного исправления, но, например, установка политики истечения срока действия, позволяющая сообщениям всегда оставаться в памяти, позволяет решить эту проблему, и с тех пор я ее не видел.

Учитывая, что некоторые детали этой проблемы совпадают с тем, что я видел (замена rabbitmq на redis исправляет, нет четкой отправной точки, это происходит на более чем одном рабочем / сервере одновременно), я предполагаю, что может быть общий триггер, и он может будь таким же, как я заметил.

Набор тестов изменен с https://github.com/celery/celery/tree/master/funtests/stress на https://github.com/celery/cyanide , и он поддерживает только Python2.

Поэтому я запускаю его на Python2 с rabbitmq в качестве брокера. Он собрал !join: connection lost: error(104, 'Connection reset by peer') . Связано ли это с проблемой утечки памяти?

Вот журнал набора тестов.

➜  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

Вот журнал для рабочего.

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

Я обновился, чтобы использовать сельдерей 3.1.25 с тем же набором стресс-тестов, все в порядке.

КСТАТИ Для всех , кто ищет для быстрого исправления - замена кролика с Redis решает проблему , как @jxltom предложил, я более чем неделю стабильной работы с Redis только сейчас
Так что проблема определенно где-то рядом с границей кролик <-> сельдерей.

@dieeasy, мы столкнулись с той же проблемой. Я предполагаю, что вы используете бэкэнд результатов RPC. Если да, попробуйте переключиться на бэкэнд результатов БД и посмотрите, поможет ли это. Проблема, которая вызывает это: https://github.com/celery/kombu/pull/779 и объясняется здесь: https://github.com/celery/kombu/pull/779#discussion_r134961611

У меня такая же проблема с утечкой памяти
объем памяти
image

Версия
python 3.6.5 сельдерей 4.2.1 backend redis брокер rabbitmq

Конфиг

[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

`` питон

- - кодировка: utf-8 - -

из очереди импорта комбу, Exchange
из журнала импорта oslo_log как логгирования

из app.conf импортировать CONF

ЖУРНАЛ = logging.getLogger (__ имя__)

celery_queues = (
Очередь ('im', exchange = Exchange ('sender'), routing_key = 'im'),
Очередь ('sms', exchange = Exchange ('sender'), routing_key = 'sms'),
Очередь ('почта', exchange = Exchange ('отправитель'), routing_key = 'mail'),
Очередь ('ivr', exchange = Exchange ('sender'), routing_key = 'ivr')
)

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

При необходимости я могу предоставить дополнительную информацию.

Как бы то ни было, у меня возникла эта проблема, и я могу постоянно ее воспроизводить, открывая консоль управления rabbitmq, переходя к соединениям и закрывая соединения с трафиком от сельдерея к rabbitmq.

Я тестировал сельдерей 4.1 и 4.2 и rabbitmq 3.7.7-1
РЕДАКТИРОВАТЬ: также Python версии 3.6.5 и ubuntu 16.04 (изображение AWS EC2)

У меня утечка памяти с сельдереем 4.2.1 и брокером Redis. Объем памяти увеличивается со 100 МБ до 500 МБ (ограничено) за 3 часа, а рабочие процессы помечаются как отключенные в цветке. И prefork pool, и gevent показывают одну и ту же проблему.

@yifeikong, возможно, это не та же проблема, но в вашем случае не могли бы вы попробовать предложенное решение https://github.com/celery/celery/pull/4839#issuecomment -447739820?

@georgepsarakis Я использую Python 3.6.5, поэтому эта ошибка меня не касается. Я буду использовать tracemalloc, чтобы провести небольшое исследование. Если это была ошибка сельдерея, я открою новый выпуск. Спасибо

Возможно та же причина с # 5047 , кажется, что эта ошибка может привести к другому явлению.

Мы сталкиваемся с той же утечкой памяти при запуске Celery 4.2.1, Kombu 4.2.2 и python3.6 с RabbitMQ в качестве брокера.

$ 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

Я могу сказать, что мы пробовали много вещей, которые другие люди упоминали как возможные обходные пути (redis в качестве брокера, используя jemalloc, libamqp, monkey path __del__ на AsyncResult ), но у нас всегда заканчивалась утечка памяти.

Анализируя наш журнал, мы заметили, что у нас было много сообщений, связанных с пропущенными сердцебиениями из сплетен.

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

Последнее, что мы пробовали, - это отключить сплетни, запустив рабочих с помощью --without-gossip странно, отключение сплетен имело немедленный эффект.

Вы можете видеть это здесь:
celery-memory-14d

Поскольку мы отключили сплетни в двух проектах, в которых работают работники сельдерея, потребление памяти улучшилось.

Если вы обратите внимание, раньше у нас были похожие всплески памяти, как описано здесь https://github.com/celery/celery/issues/4843#issuecomment -399833781

Одна вещь, которую я пытался полностью понять, - это каковы последствия полного отключения сплетен, поскольку это описывается только как общение работник <-> работник, и если бы кто-нибудь мог пролить свет на это, я был бы очень благодарен.

Надеюсь, это поможет, и спасибо за тяжелую работу.

Почему закрыли этот вопрос?

К этому выпуску есть активные отзывы и интерес, поэтому я открываю его снова.

Что ж, @georgepsarakis, поскольку мы диагностировали мою утечку как не # 4839, и вы подозревали, что это была # 4843, я перейду к этой теме утечки, по крайней мере, пока. Я не уверен, что № 4843 - моя утечка. Согласно первоначальной проблеме в этой теме:

Эта проблема возникает, по крайней мере, в Celery 4.1, но также встречается в Celery 4.2.
Celery работает на Ubuntu 16, а брокеры используют RabbitMQ.

Я сейчас на:

Python 2.7.12
Ubuntu 16.04.1 amd64
RabbitMQ 3.7.5

с использованием:

Сельдерей 4.1.1
librabbitmq 2.0.0
amqp 2.4.0
лоза 1.1.4
бильярд 3.5.0.5
комбу 4.2.2.post1
gevent 1.2.2

Однако Celery 4.1.1 + gevent 1.2.2 у меня не протекает (как и Celery 3.1.25 + gevent 1.2.2 AFAICT); Celery 4.2.1 + gevent 1.3.7 делает. К сожалению, gevent 1.3.7 и gevent 1.2.2 не являются взаимозаменяемыми, чтобы продемонстрировать (или исключить) библиотеку gevent как возможный источник проблемы.

РЕДАКТИРОВАТЬ: Хм ... похоже, есть патч gevent (022f447dd), который, похоже, может исправить ошибку, с которой я столкнулся. Я постараюсь заставить это работать.

Я применил 022f447 к Celery 4.1.1 и установил gevent 1.3.7. Эта комбинация Celery + gevent запустилась ... и создала шаблоны использования памяти, соответствующие утечке, с которой я столкнулся. Я установлю Celery 4.2.1 + gevent 1.2.2 (с обратным патчем) и посмотрю, получу ли я обычный шаблон использования памяти.

Я заметил, что gevent 1.4.0 отсутствует. Может, мне стоит попробовать и это, чтобы посмотреть, как он себя ведет.

Celery 4.2.1 + gevent 1.2.2 + обратный патч для gevent 1.2.2, похоже, не вызывает утечки, как Celery 4.2.1 + gevent 1.3.7.

Celery 4.2.1 + gevent 1.4.0, похоже, протекает примерно с той же скоростью, что и 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.

Теперь, если я правильно понимаю, что AMQP делает под капотом, тогда у него есть свое собственное сердцебиение, и когда он обнаруживает разорванное соединение, он продолжает и повторно подключается под капотом. В зависимости от типов событий, которые включены (сплетни, сердцебиение), утечка информации может происходить довольно быстро.
Это должно быть верно для любой версии eventlet и gevent, но у некоторых могут возникать проблемы с подключением, которые ухудшают / становятся более заметными.

Привет,

Я подозреваю, что у нас такая же проблема.
Наша конфигурация ниже. Могу ли я опровергнуть или подтвердить, что это та же проблема, что обсуждается здесь?

Python: 2.7
Сельдерей: 4.2.1
ОС: CentOS версии 6.10
Redis как брокер

На прикрепленном изображении вы можете увидеть:

  1. Потребление памяти постоянно увеличивается и падает при перезапуске.
  2. 13 января - перешли с сельдерея 3.1.25 на 4.2.1. Темпы роста потребления памяти растут.

image

ОБНОВИТЬ

Несмотря на эту проблему, мы обновились до Python 3.6, и с тех пор похоже, что утечки больше не происходит.

image
(апгрейд был 19 февраля)

@georgepsarakis

Не уверен, насколько это актуально, но у меня 2 ГБ места под SWAP израсходованы сельдереем в процессе производства. Остановка Флауэра не очистила память, но остановка Сельдерея сделала.

может кто-нибудь попробовать сельдерей 4.3rc1?

@auvipy Я установил Celery 4.3.0rc1 + gevent 1.4.0. pip обновил бильярд до 3.6.0.0 и комбу 4.3.0.

Немного озадачено, что винная версия 1.2.0 также не требовалась для пакета rc1, учитывая, что # 4839 исправлено этим обновлением.

В любом случае, Celery 4.3.0 rc1, похоже, работает нормально.

@ ldav1s большое спасибо за отзыв. Таким образом, в py-amqp виноград объявлен как зависимость. В новых установках будет установлена ​​последняя версия vine , но этого может не произойти в существующих.

@thedrow, возможно, нам также следует объявить зависимость в требованиях

Давайте откроем вопрос об этом и обсудим это там.

Celery 4.3.0rc1 + gevent 1.4.0 работает уже пару дней. Похоже, он протекает так же, как и Celery 4.2.1 + gevent 1.4.0.

image

Такая же утечка с сельдереем 4.2.1, python 3.6

Есть обновления по этому поводу?

здесь такая же проблема

Привет,

У меня аналогичная проблема, но я не уверен, что это то же самое.

После того, как я перенес наше приложение для сельдерея в другую среду / сеть, у рабочих сельдерея началась утечка. Ранее приложение celery и экземпляр rabbitmq находились в одной среде / сети.

Моя конфигурация находится на 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

Приложение состоит из нескольких воркеров с пулом событий, запускаемых командой в супервизоре:

[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

Поведение утечки памяти выглядит так, каждые ~ 10 часов обычно начинает утечка 1 работник, максимум 2:
image

Итак, я создал широковещательное сообщение для выполнения на каждом воркере, для использования tracemalloc, это результат верхней команды на машине, есть утечка только одного рабочего с 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 ТОП 10 результатов по утечке воркера

[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

ТОП 1 с 25 кадрами

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)

Надеюсь, это может помочь, в журналах нет ошибок, кроме пропущенного биения между рабочими. Теперь я пытаюсь использовать точную версию библиотек, которые мы использовали в старом env.

ОБНОВЛЕНИЕ: Используя те же самые точные зависимости версий библиотеки и пульс брокера каждые 5 минут, приложение выглядело стабильным в течение более длительного времени: более 2 дней, чем оно снова просочилось.

Были небольшие всплески, продолжавшиеся ~ 1 час время от времени, но они были «поглощены / собраны» .. последний, похоже, начал всплеск.

После 1-го всплеска, 1-го пандуса я перезапустил протекающего рабочего .. как вы можете видеть, другой рабочий начал протекать после него или, возможно, он уже протекал, 2-й пандус.

image

Собираюсь потестить без пульса.

ОБНОВЛЕНИЕ: без сердцебиения снова просочился через 2 дня, такое же поведение

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

ОБНОВИТЬ:
Используя сельдерей 4.3.0, кажется, что проблема решена, и он стабилен в течение недели.
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)

Пожалуйста, дайте мне знать, могу ли я чем-то помочь, инструментируя код. При необходимости предоставьте ссылки и пример.

Спасибо

У меня тоже утечка памяти. Похоже, мне удалось найти причину.
https://github.com/celery/celery/blob/master/celery/events/dispatcher.py#L75
Я вижу, что этот буфер начинает расти после проблем с подключением к rabbit. Я не понимаю, почему он не может в конечном итоге очистить события, он продолжает расти со временем и потребляет все больше и больше барана. Передача buffer_while_offline=False здесь https://github.com/celery/celery/blob/master/celery/worker/consumer/events.py#L43, похоже, исправляет утечку для меня. Может кто-нибудь проверить, связано ли это?

@ yevhen-m большое спасибо! Это помогло нам решить проблему утечки памяти!

Хорошо, что у нас есть обходной путь, но можем ли мы найти правильное решение?

непрерывно следить за этой проблемой утечки памяти

image

celery-pod-screencshot-lastweek

Я использую сельдерей в производственной среде и развертываю его через докер.
Как и на скриншоте, у нас та же проблема.
Наша производственная конфигурация показана ниже.

Родительский образ Docker: python 3.6.8-buster
Версия сельдерея: 4.2.0
Параметры команды:

  • параллелизм 4
  • предварительная выборка-умножитель 8
  • Нет result_backend
  • acks_late и reject_on_worker_lost

Интересно, решит ли обновление версии сельдерея до 4.3.0 проблему утечки памяти.

Спасибо!

celery 4.4.0 - последняя стабильная версия

Команда, есть ли обновления по этой проблеме? Было ли это исправлено в celery 4.4.0?

Команда, есть ли обновления по этой проблеме? Было ли это исправлено в celery 4.4.0?

К сожалению нет. Теперь он адресован.

Команда, есть ли обновления по этой проблеме? Было ли это исправлено в celery 4.4.0?

он будет доступен в 4.4.1

он будет доступен в 4.4.1

это исправлено в текущей версии 4.4.1?

@auvipy Проблема все еще присутствует в Celery 4.4.2 и 4.4.6. Мы видим одинаковые утечки памяти у всех рабочих.

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 fair --without-heartbeat --without-gossip -c 1 -l . Мы также используем флаги -n и -Q для установки имени исполнителя и очередей. Запуск в режиме prefork. Redis настроен как брокер и как хранилище результатов.

image

~ Мы видим много пропущенных ударов сердца при длительных задачах. Таким образом, проблема, указанная в связанных задачах, все еще сохраняется. ~

То же самое и с отключенным сердцебиением.

@jsynowiec Когда я столкнулся с этой проблемой, единственное, что у меня сработало, - это запуск рабочих с отключенными сплетнями, я кое-что упомянул здесь https://github.com/celery/celery/issues/4843#issuecomment -459789086

У нас возникла та же проблема с сельдереем 4.4.2 и Redis в качестве брокера. В течение 48 часов сельдерей потребляет до 60 ГБ оперативной памяти, пока, наконец, не иссякнет память.
Ни одно из названных здесь решений не повлияло на это поведение.

У нас возникла та же проблема с сельдереем 4.4.2 и Redis в качестве брокера. В течение 48 часов сельдерей потребляет до 60 ГБ оперативной памяти, пока, наконец, не иссякнет память.
Ни одно из названных здесь решений не повлияло на это поведение.

Вы пробовали нашу последнюю версию патча?
У вас такие же условия, как у ОП?

Утечки памяти все еще присутствуют в версии 4.4.6. Мы запускаем воркеры с настройками, перечисленными в предыдущем комментарии . OP использует RabbitMQ, мы используем Redis в качестве брокера.

image

+1, заметив, что использование памяти постепенно увеличивается в течение 24 часов даже при минимальной работе. Я считаю, что этот вопрос следует снова открыть.

Вы можете профилировать и выяснить причину утечки памяти?

Утечки памяти все еще присутствуют в версии 4.4.6. Мы запускаем воркеры с настройками, перечисленными в предыдущем комментарии . OP использует RabbitMQ, мы используем Redis в качестве брокера.

image

Похоже, это другая проблема или наше исправление неверно.
Поскольку это решило проблему OP, это, вероятно, другая проблема, верно?

[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

У Redis-клиента утечка памяти? Я использую celery v4.4.6 с gevent, redis в качестве брокера и без результата.

Может, это тоже проблема. Может дело в гевенте?
CC @jamadden @andymccurdy
Не могли бы вы помочь нам решить эту проблему и убедиться, что с вашей стороны не происходит утечки памяти?

Может дело в гевенте?

Мы не используем gevent . Рабочие запускаются с concurrency = 1 и prefork.

Привет, ребята, не знаю, почему эта проблема закрыта, у нас эта проблема существует уже 2 года, каждый раз обновляется до последней версии Celery, и по-прежнему на больших серверах (64-128 ГБ ОЗУ) постоянно заканчивается ОЗУ, потому что этой проблемы с утечкой памяти.

Есть ли обходной путь без перехода на Celery 3 или замены Rabbitmq?

Это делает Celery полностью нестабильным в производственных средах, я надеюсь, что это можно исправить, мы не можем перейти на Celery 3, поэтому мы планируем перейти на другое решение (возможно, Dramatiq), чтобы перестать беспокоиться о том, что Celery съедает всю оперативную память сервера. изготовление каждые 2 дня.

@arielcamino - я использовал настройку worker_max_tasks_per_child для замены рабочих экземпляров после 100 ~ задач, что помогло поддерживать использование памяти, по крайней мере, для моих серверов. Я использую крошечные экземпляры размером 512 МБ, и это помогло (раньше у меня была истощена память), так что, возможно, это поможет вам.

@Skowt вау, это очень полезно, большое спасибо! Сейчас попробую.

@arielcamino - я использовал настройку worker_max_tasks_per_child для замены рабочих экземпляров после 100 ~ задач, что помогло поддерживать использование памяти, по крайней мере, для моих серверов. Я использую крошечные экземпляры размером 512 МБ, и это помогло (раньше у меня была истощена память), так что, возможно, это поможет вам.

Спасибо, что поделились своим обходным путем. Здесь это не помогло - однако мы используем redis.

@thedrow Я не знаю об утечках памяти в redis-py. Если бы в redis-py была утечка, я предполагаю, что кто-то столкнулся бы с ней за пределами среды Celery и сообщил об этом в средство отслеживания проблем redis-py.

Рад помочь, где могу (я использую Celery w / Redis в качестве брокера в нескольких проектах), но я не сталкивался с этой проблемой в своих развертываниях.

Мне неизвестны утечки памяти в текущих версиях gevent. Я предполагаю (надеюсь), что кто-то сказал бы что-нибудь, если бы столкнулся с этим (это уже случалось один или два раза раньше). В моем текущем развертывании gevent несколько рабочих процессов (веб и фон) работают неделями, интенсивно используя gevent, и мы не сталкивались с утечками памяти.

Привет, ребята, не знаю, почему эта проблема закрыта, у нас эта проблема существует уже 2 года, каждый раз обновляется до последней версии Celery, и по-прежнему на больших серверах (64-128 ГБ ОЗУ) постоянно заканчивается ОЗУ, потому что этой проблемы с утечкой памяти.

Есть ли обходной путь без перехода на Celery 3 или замены Rabbitmq?

Это делает Celery полностью нестабильным в производственных средах, я надеюсь, что это можно исправить, мы не можем перейти на Celery 3, поэтому мы планируем перейти на другое решение (возможно, Dramatiq), чтобы перестать беспокоиться о том, что Celery съедает всю оперативную память сервера. изготовление каждые 2 дня.

Сколько у вас рабочих? Сколько задач вы выполняете? Как часто вы выполняете эти задачи и сколько времени обычно занимает их выполнение?

Причина, по которой Rabbitmq / celery начинает использовать много оперативной памяти, может быть связана с количеством задач в очереди. Если вы ставите в очередь слишком много задач, и рабочие не могут выполнить их все, это увеличит очередь, и эта очередь будет использовать все больше и больше оперативной памяти, и в конечном итоге она будет использовать всю доступную оперативную память. Я считаю, что эта проблема может возникнуть и с Redis.

У меня есть другая теория, но сначала я хочу знать, может ли это быть причиной вашей проблемы.

@ardilom извините, я только что понял, что мы не отправляем данные RabbitMQ в datadog, но я постараюсь прояснить нашу ситуацию, вот как оперативная память некоторых серверов снижается каждые 2 дня:
memory-leaks-1

Мы всегда проверяем количество ожидающих задач, и обычно оно составляет около 0 (эти данные были получены несколько дней назад):

memory-leaks-2

Мы выполняем около 250 000 задач в день, у нас около 10 рабочих, каждый из которых имеет от 4 до 10 одновременных операций, среднее время выполнения составляет около 5 секунд, это зависит от типа задачи.

Мы всегда проверяем messages_ready, чтобы убедиться, что в очереди не слишком много задач (это то, что вы видите на втором изображении). Как вы думаете, можно ли измерять messages_ready ? В конечном итоге у нас есть пики, но обычно они близки к нулю.

Для решения проблемы я просто перезапускаю Celery worker вручную, и использование ОЗУ снова становится нормальным.

Сообщите мне, если вам что-то еще нужно, я только что изменил настройку worker_max_tasks_per_child на одном из серверов задач, чтобы увидеть, есть ли разница с остальными после применения конфигурации.

Спасибо!

Привет, ребята, это подтверждает, что изменение worker_max_tasks_per_child на 1000 в моем случае устранило проблему 🎉 еще раз спасибо @Skowt

То, что я вчера не упомянул, я использую режим «prefork», возможно, переход на gevent - еще один способ решить проблему.

@arielcamino Эта проблема была закрыта, так как мы
Нам нужен кто-то с доступом к производственной среде, в которой воспроизводится ошибка, для отладки проблемы.
Если у нас его нет, мы должны определить, что эта проблема не подлежит устранению.

Здравствуйте, мы можем снова открыть эту проблему? У нас наблюдаются аналогичные утечки, используя celery == 4.4.7 (с rabbitmq), у нас есть рабочий, работающий стабильно в течение нескольких часов, иногда намного больше, а затем внезапно начинает медленно течь и в конечном итоге использует всю память.

В настоящее время используется предварительная вилка с --concurrency=1 и флагом --max-tasks-per-child=100 который, похоже, не помогает, поскольку кажется, что происходит утечка родительского процесса.

celery_leak

Я могу предоставить дополнительную информацию, чтобы помочь отладить эту проблему.

Здравствуйте, мы можем снова открыть эту проблему? У нас наблюдаются аналогичные утечки, используя celery == 4.4.7 (с rabbitmq), у нас есть рабочий, работающий стабильно в течение нескольких часов, иногда намного больше, а затем внезапно начинает медленно течь и в конечном итоге использует всю память.

В настоящее время используется предварительная вилка с --concurrency=1 и флагом --max-tasks-per-child=100 который, похоже, не помогает, поскольку кажется, что происходит утечка родительского процесса.

celery_leak

Я могу предоставить дополнительную информацию, чтобы помочь отладить эту проблему.

Повторное открытие проблемы не представляет большого труда, это заинтересованность тех, кто сталкивается с ней в производственной среде, и помогает отслеживать и вносить исправление или, по крайней мере, выяснять основную причину утечки в производственной среде.

Я определенно могу помочь, но у меня закончились идеи о том, что делать, я запустил пару инструментов, но не смог определить суть проблемы. Единственное, что сужает его, - это сделанные мной снимки tracemalloc, которые показывают увеличение памяти в одних и тех же местах каждые пару минут или около того. Это топ-10 сравнения двух снимков:

/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

Проблема все еще существует
Это происходит, когда контекст приложения доступа к задаче сельдерея для выполнения функции
Он не освобождает или не утилизирует его после выполнения задачи

--max-tasks-per-child=

не помог

Здравствуйте, мы можем снова открыть эту проблему? У нас наблюдаются аналогичные утечки, используя celery == 4.4.7 (с rabbitmq), у нас есть рабочий, работающий стабильно в течение нескольких часов, иногда намного больше, а затем внезапно начинает медленно течь и в конечном итоге использует всю память.
В настоящее время используется предварительная вилка с --concurrency=1 и флагом --max-tasks-per-child=100 который, похоже, не помогает, поскольку кажется, что происходит утечка родительского процесса.
celery_leak
Я могу предоставить дополнительную информацию, чтобы помочь отладить эту проблему.

Повторное открытие проблемы не представляет большого труда, это заинтересованность тех, кто сталкивается с ней в производственной среде, и помогает отслеживать и вносить исправление или, по крайней мере, выяснять основную причину утечки в производственной среде.

для меня, если я добавлю --max-tasks-per-child это сработает.
как для этого примера аргументов --autoscale=5,2 --max-tasks-per-child=40 результат будет таким

Screenshot 2020-08-13 at 2 26 13 PM

Хотя я считаю, что недавнее обновление сельдерея привело к утечке памяти, я не могу быть полностью уверен. Поделюсь, что следующая настройка устранила утечку.

Я не могу сказать, какие настройки действительны по документации, поэтому я устанавливаю все эти значения в моем файле настроек Django.

CELERY_CONCURRENCY = CELERY_WORKER_CONCURRENCY = 1
CELERY_MAX_TASKS_PER_CHILD = CELERY_WORKER_MAX_TASKS_PER_CHILD = 1

Это не решает наблюдаемую утечку, как это также происходит в пуле gevent. Я заметил, что у нас очень занята очередь сельдерея. Поскольку tracemalloc показал отправку событий как один из возможных источников утечки, я явно отключил события задач и отключил наш экземпляр цветка, на данный момент похоже, что утечки больше не происходит, я позволю ей работать на выходных и поделюсь результаты здесь.

возможные источники утечки Я явно отключил события задач и отключил наш экземпляр цветка

Анекдотические данные от человека, который с самого начала молча наблюдал за этой проблемой (и никогда не сталкивался с ней напрямую): мне известен еще один проект (с немалой рабочей нагрузкой для сельдерея), в котором выполнение вышеуказанного имело тот же результат: остановка утечки памяти. Имея только информацию из вторых рук, я _ очевидно_ не могу подтвердить, что это была даже та же основная проблема (AFAIK это был rabbitmq, не знаю о gevent и т.д.), но интересно, что это коррелирует.

Я подозреваю, что это как-то связано с подключением rabbitmq, стеком, который мы наблюдали за этой утечкой:

  • сельдерей (последняя версия): либо prefork, либо gevent pool, оба показывают одинаковую картину утечки.
  • rabbitmq (CloudAMQP SaaS)
  • цветок

Мы проверили все наши задачи на предмет утечек и не смогли найти утечек, поэтому я подозреваю, что это что-то на стороне сельдерея.

Один интересный факт заключается в том, что в настоящее время у нас работает много рабочих, и я заметил, что как только одна начинает протекать, она также отображается на цветке как офлайн.

Поскольку у меня закончились идеи, где искать, я отключил события цветов и задач и продолжу отслеживать, вернется ли утечка или нет.

Я открыт для того, чтобы поверить, что это еще одна часть моего стека, из-за которой происходит утечка памяти на данный момент. Возможно, сельдерей в прошлом имел случайное поведение, которое способствовало контролю утечек памяти, но, похоже, у всех нас вместе нет достаточно похожих проблем, чтобы подтвердить это. Я знаю, что многие из нас либо бегут ...

  • Сразу огромное количество вложенных задач, или
  • Несколько монолитных, запускающих многоядерную обработку внутри рабочего

В этих случаях нам просто нужно уметь разрешать или запрещать определенный уровень параллелизма, очереди задач и задач для каждого дочернего работника. Кроме того, все мы должны использовать встроенные средства защиты, которые могут убивать задачи, требующие большого количества памяти, прежде чем они получат возможность вывести из строя наши серверы.

Все больше людей запускают в сельдерее тяжелые процессы, связанные с процессором и памятью, для чего он на самом деле не предназначен, поэтому я думаю, что документация по быстрому запуску должна включать более подробную информацию об этом.

Как уже упоминалось в моих предыдущих комментариях, мы уже давно запускаем воркеры с max-tasks-per-child и параллелизмом, установленным на 1 . Это ничего не делает с утечкой памяти. Более того, мы используем Redis как брокер, так и сервер результатов.

По моим наблюдениям, когда RabbitMQ используется в качестве брокера, если установка max-tasks-per-child на 1 "решает" утечку памяти, это, скорее всего, проблема с реализацией задачи, а не с сельдереем.

То, что мы наблюдаем и о чем сообщаем, отличается. Даже если мы оставляем воркер бездействующим в течение нескольких дней, не обрабатывая ни одной задачи, он все равно приводит к утечке памяти до такой степени, что достигает предела памяти и прекращается супервизором. Вы можете найти более подробную информацию и диаграммы памяти в более ранних комментариях.

Когда рабочий обрабатывает одну задачу по расписанию, диаграмма памяти должна более или менее показывать прямоугольную волну, но вы можете ясно видеть, что общее использование памяти только возрастает.
Screenshot 2020-08-14 at 20 42 24

Мне удалось включить профилирование сельдерея в нашу дорожную карту. Я поделюсь дампами памяти и другими подробностями, когда мы начнем над этим работать.

Я могу подтвердить, что отключение цветков (и явное отключение событий задач в настройках) устранило утечку.

Как я упоминал ранее, в тот момент, когда рабочий начал протекать, я заметил в цветке, что он отключается, а сельдерей всегда показывал довольно занятый, поэтому я пошел простым путем и выключил цветок.

К сожалению, я не смог найти фрагмент кода, вызывающий утечку. Но, по крайней мере, есть обходной путь.

тогда наверное дело не в сельдерее, а в цветке?

@auvipy flower вызывает проблему, но утечка определенно происходит на рабочем (сельдерей)

@auvipy flower вызывает проблему, но утечка определенно происходит на рабочем (сельдерей)

справедливо. Спасибо, что поделился.

Я использую Celery с Redis и Flower и должен сказать, что в настоящее время не вижу проблем с памятью. Что-нибудь, что вы можете от меня пожелать в отношении данных?

@auvipy не использует цветок. Рабочие запускаются с отключенными событиями.

@auvipy не использует цветок. Рабочие запускаются с отключенными событиями.

попробуйте отладить и выяснить причину утечки памяти. может быть сельдерей или ваш мог. было бы лучше, если бы вы могли поделиться модульными и интеграционными тестами

попробуйте отладить и выяснить причину утечки памяти. может быть сельдерей или ваш мог. было бы лучше, если бы вы могли поделиться модульными и интеграционными тестами

Здесь упоминается, что мы видим OOM из-за утечки памяти из сельдерея, даже если рабочий процесс не обрабатывает никаких задач.
Невозможно поделиться модульными или интеграционными тестами, так как это может раскрыть IP компании. Простите. Но мне удалось добавить в нашу внутреннюю дорожную карту задачу по сбору дампов памяти производственных рабочих. Когда это будет сделано, поделится счетчиками и ссылками для нескольких сценариев.

@jsynowiec Если вы сможете сделать это до 5.0.0 GA (следуйте # 6266 для обновлений), это было бы здорово.

Как только исправление обнаружено в мастере, оно также будет перенесено на 4.x.

@thedrow Когда планируется

У нас есть один блокировщик релизов и некоторая документация, которую нужно завершить.
Ответ очень скоро.

Я могу подтвердить, что отключение цветов останавливает утечку. Уже почти месяц работаем без протечек.

Так что где-то в нашем механизме публикации событий все еще есть ошибка.
Есть ли у кого-нибудь идеи, что это может быть?

Мы не используем Flower, и рабочие процессы запускаются без --events , но при этом постоянно возникают утечки памяти.

Ответ очень скоро.

Мне удалось уделить первоочередное внимание получению дампов памяти и счетчиков объектов от производственников. Я смогу опубликовать некоторые данные в ближайшие недели. Мы также повысили приоритет при завершении переноса py2-> py3, поэтому все должно работать и профилироваться с использованием Python 3.

Меня беспокоит то, что мы говорим здесь о двух разных вопросах.

По всей видимости. Один из них связан с событиями и, возможно, с Flower, возможно, также с использованием RabbitMQ в качестве брокера. Согласно сообщениям о проблемах здесь, на GitHub, он появляется то тут, то там уже несколько лет. Другой (который влияет на мой проект) связан с разными компонентами и, скорее всего, связан с использованием Redis в качестве брокера. Или, может быть, в корне, это те же проблемы, которые происходят из того же кода, кто знает 🤷🏼. Как тот, где trail отслеживает подзадачи и утечки экземпляров AsyncResult 😉

@thedrow @auvipy Просто

Кроме того, при завершении миграции Python3 мы столкнулись с другой проблемой, которая, похоже, связана с https://github.com/celery/celery/issues/4470 или https://github.com/celery/celery/issues/5359. При определенных условиях в системах Linux при использовании Redis в качестве брокера вызовы join_native зависают на неопределенное время, несмотря на то, что все задачи в группе уже выполнены. Quick strace указывает на то, что он буквально зависает при чтении, что может указывать на некоторые низкоуровневые вещи ядра / библиотеки. На данный момент мы перешли на простой пул join поскольку мы сосредоточились на утечках памяти.

Всем привет - наконец-то _некоторые_ данные: celery-memtrace-1.tar.xz , подпись , мой ключ .

Архив содержит журналы tracemalloc от 8 рабочих через ~ 16 дней, график использования памяти за период и некоторую информацию о версии (включая баннер запуска Celery).

Честно говоря, я не потратил сколько-нибудь значительного времени на анализ всего этого, но а) наш код никогда не был в списке, б) это может быть какое-то странное взаимодействие с SQLAlchemy, которое мы также используем повсюду, поэтому не исключено, что проблема находится в другом месте, или это проблема комбинации / взаимодействия.

Если какие-либо другие подробности будут вам полезны, пожалуйста, спрашивайте. Мы также продолжаем запускать эти 8 рабочих процессов с ведением журнала использования памяти, так что, возможно, мы сможем собрать больше / лучше данных.

РЕДАКТИРОВАТЬ : Также этот комментарий из этой ветки связан - мы по-прежнему используем те же настройки.

Надеюсь, вы найдете причину этой утечки.
Я постараюсь найти время и сам разобраться в этом.

Интересно, поможет ли это решить проблему.
https://reliability.substack.com/p/run-python-servers-more-efficiently

Мы исследуем возможность того, что источник утечки памяти находится в библиотеке запросов, а не в самом сельдерее. Кто-нибудь еще, кто испытывает утечки памяти в сельдерее, использует запросы в задачах?

@ErrorInPersona Да, мы регистрируем OOM в воркерах как с запросами, так и без них.

@drbig Удачи?

Screenshot_2020-11-17_12-56-28

Что ж, посмотрите на "зеленый", пол поднимается, медленно, но верно ... Так что, кроме быстрого подтверждения "да, это все еще проблема", с моей стороны, к сожалению, особо нечего добавить.

Однако я просмотрел ссылку, которую предоставил - try running some workers with jemalloc forced in , так что я доберусь до этого _eventually_.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги