Celery: 持续的内存泄漏

创建于 2018-06-23  ·  129评论  ·  资料来源: celery/celery

Celery的worker的父进程中存在内存泄漏。
它不是执行任务的子进程。
每隔几天突然发生一次。
除非您停止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并发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,一切都很好。

对于内存泄漏问题,我将rabuntm 16,celery 4.1.0与rabbitmq一起使用。 我通过docker部署了它。

内存泄漏是由MainProcess而非ForkPoolWorker引起的。 ForkPoolWorker的内存使用率是正常的,但是MainProcess的内存使用率始终在增加。 在五秒钟内,大约有0.1MB的内存泄漏。 内存泄漏不会在工作立即开始后开始,而是可能在一两天后开始。

我使用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
由于这个问题,每隔几天我必须重新启动工作人员
日志中没有任何明显的线索,但是我怀疑重新连接会产生影响; 因为我已经在内存开始持续增长的某个时间重新连接日志条目
我的conf是ubuntu 17,1个服务器-1个具有3个并发性的worker; 后端有Rabbit和Redis; 所有软件包均为最新版本

@marvelph @ dmitry-kostin您能否提供您的确切配置(当然省略敏感信息)以及可能重现此问题的任务或示例? 另外,您是否对工作程序内存增加开始出现的平均正常运行时间间隔有任何估计?

该配置位于默认位置附近

进口=('app.tasks',)
result_persistent =真
task_ignore_result = False
task_acks_late = True
worker_concurrency = 3
worker_prefetch_multiplier = 4
enable_utc = True
时区=“欧洲/莫斯科”
broker_transport_options = {'visibility_timeout':3600,'confirm_publish':True,'fanout_prefix':True,'fanout_patterns':True}

screenshot 2018-06-25 11 35 17
基本上,这是新的部署节点; 它于06/21 18-50部署; 盯着05/00左右增长6/23,最后在23-00左右崩溃了6/23

任务非常简单,没有超级逻辑,我想我可以在一个清晰的临时项目中重现整个情况,但现在没有空闲时间,如果我很幸运,我会在周末尝试做一个完整的例子

UPD
如您所见,任务本身消耗了一些内存,您可以通过图中的峰值看到它,但是当内存开始泄漏时,没有任何任务产生或任何其他活动

@marvelph @ dmitry-kostin @jxltom我注意到您使用Python3。 您介意为该过程启用tracemalloc吗? 您可能需要打补丁工作进程才能记录内存分配跟踪,如果需要帮助,请告诉我。

@georgepsarakis您的意思是在特定的时间间隔(例如5分钟)内启用worker和日志统计信息中的tracemalloc(例如,前10个内存使用情况文件)吗?

@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上,我使用有监督的功能对其进行操作。

@georgepsarakis
由于我的测试环境可以容忍性能下降,因此可以使用tracemalloc。
您可以制作修补的芹菜来转储内存使用情况吗?

@jxltom我用5分钟打赌tracemalloc不会帮助您定位问题
例如,我有5个节点,其中只有3个节点在最近4天中有此问题,这次有2个节点工作正常,因此定位问题将非常棘手。
我觉得有些开关会打开,然后内存开始增长,直到此开关的内存消耗看起来非常好

我试图找出在其他正在运行的系统中是否也发生了类似的问题。
发生的频率各不相同,但是在使用Celery 4.x的三个系统上发生了内存泄漏,而在一个系统上没有发生。
存在内存泄漏的系统是Python 3.5.x,没有内存泄漏的系统是Python2.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我能够重现此内容,并为我提供访问权限

更新:通过将代理URL更新为环境变量,我将代理从rabbitmq更新为redis,并保持docker /代码完全相同。 它运行了4天,没有内存泄漏

因此,我认为此问题与Rabbitmq经纪人有关。

如果可能的话,请尝试运行基准测试命令,这里提到: https :

该系统正在运行带有20台服务器的工作者。
昨天发生了内存泄漏,但是几乎同时在所有服务器上都发生了。
memoryleak

不知道它是否相关,将其保留在此处以防万一。

我对celery和rabbitmq有一个不同的问题(celery失去连接并开始每秒重新连接负载,cpu在1个内核上变为100%,beat无法发送新任务,需要重新启动celery)。

我在这里报告此问题的原因是触发因素:经过几天的监视,我认为我找到了问题的开始,似乎是Rabbitmq将一些消息从内存移到了磁盘。 那时celery开始尝试尽可能快地重新连接,rabbitmq日志显示每秒数十次连接/断开操作,一次大约10次左右。 重新启动rabbitmq不能解决问题,重新启动celery可以立即解决问题。 我没有适当的修复程序,但例如,设置一个过期策略以使消息始终保留在内存中可以解决此问题,此后我再也没有看到它。

鉴于此问题的某些细节与我所见相符(用redis交换Rabbitmq可以解决此问题,没有一个明确的起点,它同时在多个工作人员/服务器上发生)跟我发现的一样

测试套件已从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') !

我已更新为使用具有相同压力测试套件的celery 3.1.25,一切都很好。

顺便说一句,对于每个正在寻求快速解决方案的人–用@jxltom建议,用redis代替直到现在我才有超过一周的稳定时间可以使用redis
所以问题肯定在兔子<->芹菜边界附近

@dieeasy我们遇到了同样的问题。 我假设您正在使用RPC结果后端。 如果是这样,请尝试切换到数据库结果后端,看看是否有帮助。 导致此问题的原因是: httpshttps

我有相同的内存泄漏问题
记忆
image

版本
蟒蛇3.6.5芹菜4.2.1后端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

python

-编码:utf-8--

从kombu import Queue,交换
从oslo_log导入日志作为日志记录

从app.conf导入CONF

日志= logging.getLogger(__ name__)

celery_queues =(
Queue('im',exchange = Exchange('sender'),routing_key ='im'),
Queue('sms',exchange = Exchange('sender'),routing_key ='sms'),
列('mail',exchange = Exchange('sender'),routing_key ='mail'),
列('ivr',exchange = Exchange('sender'),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())

如果需要,我可以提供更多信息。

对于它的价值,我遇到了这个问题,可以通过打开rabbitmq管理控制台,建立连接并关闭从芹菜到rabbitmq的连接来始终如一地重现它。

我已经用芹菜4.1和4.2以及Rabbitmq 3.7.7-1进行了测试
编辑:也是python版本3.6.5和ubuntu 16.04(AWS EC2图像)

我的芹菜4.2.1和Redis Broker发生内存泄漏。 内存在3小时内从100 MiB增长到500 MiB(受限),并且工作人员在花朵中被标记为离线。 prefork池和gevent都显示相同的问题。

@yifeikong这可能不是一个相同的问题,但是对于您的情况,您可以尝试建议的解决方案https://github.com/celery/celery/pull/4839#issuecomment -447739820吗?

@georgepsarakis我正在使用Python 3.6.5,因此我不受此错误的影响。 我将使用tracemalloc进行一些研究。 如果是芹菜虫,我要再开一个新的问题。 谢谢

可能与#5047的原因相同,似乎此错误可能导致不同的现象。

我们面临着以RabbitMQ作为代理运行Celery 4.2.1,Kombu 4.2.2和python3.6的相同内存泄漏。

$ 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, __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

由于我们在运行芹菜工人的两个项目中停用了八卦,因此内存消耗得到了改善。

如果您注意的话,在我们遇到类似此处所述的类似内存高峰之前,参见

我一直试图完全理解的一件事是完全禁用八卦的含义,因为它仅被描述为“工人<->工人沟通”,如果有人能对此有所了解,我将非常感激。

希望这会有所帮助,并感谢您的辛勤工作。

为什么关闭此问题?

在这个问题上有积极的反馈和兴趣,所以我要重新开始。

@georgepsarakis好吧,因为我们诊断出我的泄漏不是#4839,并且您怀疑它是#4843,至少现在我将转到该泄漏线程。 我不确定#4843是否也是我的泄漏。 根据此线程的最初问题:

此问题至少发生在Celery 4.1中,并且也发生在Celery 4.2中。
Celery在Ubuntu 16上运行,代理使用RabbitMQ。

我目前在:

python 2.7.12
Ubuntu 16.04.1 amd64
兔子MQ 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. 1月13日-我们将芹菜3.1.25升级到4.2.1。 内存消耗的增长速度在增长。

image

更新

不管这个问题如何,我们都升级到了python 3.6,从那以后似乎不再发生泄漏了。

image
(升级时间为2月19日)

@georgepsarakis

不知道这有多重要,但是我正在生产中的芹菜耗尽了我2GB的SWAP空间。 停止Flower不会清除内存,但是停止Celery可以清除内存。

有人可以尝试芹菜4.3rc1吗?

@auvipy我安装了Celery 4.3.0rc1 + gevent 1.4.0。 pip将台球升级到3.6.0.0和kombu 4.3.0。

有点疑惑的是,rc1软件包也不需要vine 1.2.0,因为该升级已修复了#4839。

无论如何,Celery 4.3.0 rc1似乎可以正常运行。

@ ldav1s非常感谢您的反馈。 因此,实际上在py-amqp中将vine声明为依赖vine版本,但是在现有版本中可能不会发生。

@thedrow也许我们也应该在Celery需求中声明依赖项?

让我们打开一个关于它的问题并在那里进行讨论。

Celery 4.3.0rc1 + gevent 1.4.0已经运行了几天。 看起来它以与Celery 4.2.1 + gevent 1.4.0相同的方式泄漏。

image

与celery 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,这是计算机上top命令的结果,只有1个工作程序泄漏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

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

我希望它能有所帮助,日志中没有错误,除了工人之间心跳丢失。 现在,我正在尝试使用与旧环境兼容的库的确切版本。

更新:每5分钟使用相同的完全相同的依赖库lib版本和代理心跳,该应用程序看起来稳定了更长的时间:超过2天,而不是再次泄漏。

有小穗持续约1小时的时间,但是被“吸收/收集”了。最后一个看起来像是开始了。

在第一个峰值(第一个斜坡)之后,我重新启动了泄漏的工作程序..正如您所看到的,另一个工作程序在它可能已经泄漏之后开始泄漏,第二个斜坡。

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

更新:
使用celery 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

我在生产环境中使用celery,并通过docker进行部署。
就像屏幕截图一样,我们遇到了同样的问题。
我们的生产配置如下所示。

Docker父映像:python 3.6.8-buster
芹菜版本:4.2.0
命令选项:

  • 并发4
  • 预取乘法器8
  • 没有result_backend
  • acks_late和reject_on_worker_lost

我不知道将celery的版本升级到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标志来设置工作人员名称和队列。 在前叉模式下运行。 将Redis配置为代理和结果存储。

image

〜我们看到许多长时间运行的任务错过了心跳。 因此,链接问题中报告的问题仍然存在。

禁用心跳也是如此。

@jsynowiec当我面对这个问题时,唯一对我https://github.com/celery/celery/issues/4843#issuecomment -459789086

芹菜4.4.2和Redis作为经纪人,我们也遇到了同样的问题。 在48小时的时间范围
此处列出的解决方案均未对该行为产生任何影响。

芹菜4.4.2和Redis作为经纪人,我们也遇到了同样的问题。 在48小时的时间范围
此处列出的解决方案均未对该行为产生任何影响。

您是否尝试了我们最新的补丁程序版本?
您是否具有与OP相同的条件?

v4.4.6上仍然存在内存泄漏。我们使用前面的注释中列出的设置来运行worker。 OP使用RabbitMQ,我们使用Redis作为代理。

image

+1,注意内存使用量会在24小时内逐渐增加,即使完成的工作量很少。 我认为这个问题应该重新讨论。

您可以剖析并找出内存泄漏的根源吗?

v4.4.6上仍然存在内存泄漏。我们使用前面的注释中列出的设置来运行worker。 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 。 工人从并发= 1和预叉开始。

嗨,大家好,不确定为什么这个问题已经解决了,我们已经有2年了,每次更新到Celery的最新版本,仍然有大量的服务器(64-128GB RAM)不断用完RAM,因为此内存泄漏问题。

是否有任何解决方法而不降级到Celery 3或替换Rabbitmq?

这使得Celery在生产环境上完全不稳定,我希望它可以解决,我们不能降级到Celery 3,因此我们计划迁移到另一个解决方案(也许是Dramatiq),以避免担心Celery占用了整个服务器的RAM。每2天生产一次。

@arielcamino-我一直在使用设置worker_max_tasks_per_child来替换100个任务之后的工作实例,这至少有助于维护服务器的内存使用率。 我正在运行512MB的微型实例,这有所帮助(以前会耗尽我的内存),所以也许会对您有所帮助。

@Skowt哇,这非常有帮助,非常感谢! 立即尝试。

@arielcamino-我一直在使用设置worker_max_tasks_per_child来替换100个任务之后的工作实例,这至少有助于维护服务器的内存使用率。 我正在运行512MB的微型实例,这有所帮助(以前会耗尽我的内存),所以也许会对您有所帮助。

感谢您分享您的解决方法。 这对这里没有帮助-尽管我们正在使用Redis。

@thedrow我不知道redis-py中有任何内存泄漏。 如果redis-py发生泄漏,我认为有人会在Celery环境之外遇到该泄漏,并将其报告给redis-py问题跟踪器。

很乐意为您提供帮助(我在一些项目中使用Celery w / Redis作为代理),但是我在部署中并未遇到此问题。

我不知道当前版本的gevent中有任何内存泄漏。 我假设(希望)某人会在遇到某事时说过一句话(之前发生过一两次)。 我当前的gevent部署使用gevent一次要花费数周的时间来处理多个工作人员(网络和后台),而且我们还没有遇到内存泄漏的情况。

嗨,大家好,不确定为什么这个问题已经解决了,我们已经有2年了,每次更新到Celery的最新版本,仍然有大量的服务器(64-128GB RAM)不断用完RAM,因为此内存泄漏问题。

是否有任何解决方法而不降级到Celery 3或替换Rabbitmq?

这使得Celery在生产环境上完全不稳定,我希望它可以解决,我们不能降级到Celery 3,因此我们计划迁移到另一个解决方案(也许是Dramatiq),以避免担心Celery占用了整个服务器的RAM。每2天生产一次。

你有几个工人? 您运行多少个任务? 您多久执行一次此任务,通常需要多长时间完成一次?

Rabbitmq / celery开始使用大量ram的原因可能与排队的任务数量有关。 如果您排队太多任务而工作人员无法完成全部任务,它将扩大队列,并且此队列将使用越来越多的RAM,最终将消耗所有可用的RAM。 我相信Redis也可能发生此问题。

我有另一种理论,但首先我想知道这是否是导致您出现问题的原因。

@ardilom对不起,我刚刚意识到我们没有将RabbitMQ数据发送到datadog,但是我将尝试阐明我们的情况,这就是某些服务器RAM每2天减少一次的方式:
memory-leaks-1

我们总是检查待处理的任务数,通常为0(此数据来自几天前):

memory-leaks-2

我们每天运行大约250,000个任务,我们大约有10个工人,每个工人具有大约4到10个并发性,平均运行时间约为5秒,这取决于任务的类型。

我们总是检查messages_ready ,以确保没有太多任务排队(这是您在第二张图片中看到的),您认为可以衡量messages_ready吗? 我们最终会有一些峰值,但通常这些峰值接近0。

为了解决该问题,我只是手动重新启动Celery worker,并且RAM使用率再次恢复正常。

让我知道您是否还有其他需要,我刚刚更改了其中一台任务服务器上的worker_max_tasks_per_child的设置,以查看应用配置后其余任务服务器之间是否有任何区别。

谢谢!

嗨,大家好,这是为了确认我的情况下将worker_max_tasks_per_child更改为1000,已修复此问题again再次感谢@Skowt

昨天我没有提到的东西,我使用的是“ prefork”模式,也许转移到gevent是解决问题的另一种方法。

@arielcamino由于我们解决了一个特定的内存泄漏,因此已关闭此问题。 我们还没有找到导致内存泄漏的另一个原因。 我们知道有问题,但我们不知道如何重现。
我们需要可以访问生产环境的人员,在该环境中可以复制错误以调试问题。
如果没有,我们将不得不确定该问题不可行。

您好,我们可以重新打开这个问题吗? 我们正在经历类似的泄漏,使用celery == 4.4.7(使用rabbitmq),使工作程序稳定运行几个小时,有时甚至更多,然后突然开始缓慢泄漏并最终耗尽所有内存。

当前使用带有--concurrency=1和标志--max-tasks-per-child=100 prefork,这似乎无济于事,因为父进程似乎是一个正在泄漏的进程。

celery_leak

我可以提供更多信息来帮助调试此问题。

您好,我们可以重新打开这个问题吗? 我们正在经历类似的泄漏,使用celery == 4.4.7(使用rabbitmq),使工作程序稳定运行几个小时,有时甚至更多,然后突然开始缓慢泄漏并最终耗尽所有内存。

当前使用带有--concurrency=1和标志--max-tasks-per-child=100 prefork,这似乎无济于事,因为父进程似乎是一个正在泄漏的进程。

celery_leak

我可以提供更多信息来帮助调试此问题。

重新解决问题不是什么大问题,这是生产中面临此问题的人员的利益,并有助于跟踪和提供解决方案,或者至少找出生产中泄漏的根本原因。

我绝对可以帮忙,但是我在解决方法上没有想法,我使用了几种工具,但对问题的了解不多。 唯一可以缩小范围的是我拍摄的tracemalloc快照,该快照显示每两分钟左右相同位置的内存增加。 这是比较两个快照的前十名:

/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

问题仍然存在
当celery任务访问应用程序上下文以执行功能时,会发生这种情况
执行任务后不会释放或处置它

--max-tasks-per-child=

没有帮助

您好,我们可以重新打开这个问题吗? 我们正在经历类似的泄漏,使用celery == 4.4.7(使用rabbitmq),使工作程序稳定运行几个小时,有时甚至更多,然后突然开始缓慢泄漏并最终耗尽所有内存。
当前使用带有--concurrency=1和标志--max-tasks-per-child=100 prefork,这似乎无济于事,因为父进程似乎是一个正在泄漏的进程。
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池中发生。 我注意到的是,我们的celeryev队列非常繁忙。 因为tracemalloc将事件分发显示为泄漏的可能来源之一,所以我明确禁用了任务事件并关闭了我们的花实例,现在看来泄漏不再发生了,我让它运行到周末并共享结果在这里。

我明确禁用了任务事件并关闭了我们的花实例,这可能是导致泄漏的原因

某人的轶事数据点,他从一开始就一直静静地观看着这个问题(并且从未直接经历过):我知道另一个项目(芹菜的工作量并不大)在进行上述操作时具有相同的结果停止内存泄漏。 仅拥有二手信息,我_显然无法确认它甚至是相同的潜在问题(AFAIK是rabbitmq,不知道gevent等),但是有趣的是它相互关联。

我怀疑它与rabbitmq连接有某种关系,我们一直在观察此泄漏的堆栈:

  • 芹菜(最新版本):前叉或gevent池,都显示相同的泄漏模式。
  • rabbitmq(cloudamqp SaaS)

我们检查了所有任务是否有泄漏,找不到泄漏,这就是为什么我怀疑自己是芹菜的原因。

一个有趣的事实是,我们目前有许多工人在运行,而且我注意到,一旦有人泄漏,它也会在花上显示为脱机状态。

当我没有办法去寻找外观时,我禁用了花和任务事件,并将继续监视泄漏是否会再次出现。

我愿意相信这是我的堆栈的另一部分正在泄漏内存。 Celery过去可能有过偶然的行为,这有助于控制内存泄漏,但是我们所有人似乎都没有足够类似的问题来确认这一点。 我知道我们很多人都在跑步...

  • 一次有大量的嵌套任务,或者
  • 一些在工作人员中启动多核处理的整体

在这些情况下,我们只需要明智地允许或禁止一定程度的并发,任务排队和每个童工的任务即可。 此外,我们所有人都应该使用内置的防护措​​施,这些措施可以杀死需要大量内存的任务,然后才有机会使我们的服务器崩溃。

越来越多的人在celery中运行繁重的CPU绑定和内存绑定进程,这并不是真的要这么做的,因此我认为快速入门文档应包括有关此方面的更多详细信息。

正如我之前的评论中已经提到的那样,从很久以前开始,我们正在运行的工人都将max-tasks-per-child和并发性设置为1 。 它对泄漏内存没有任何作用。 此外,我们将Redis用作代理和结果后端。

根据我的观察,当RabbitMQ用作代理时,如果将max-tasks-per-child1 “解决”内存泄漏,则很可能是任务实现的问题,而不是芹菜的问题。

我们观察和报告的内容是不同的。 即使我们将工作人员闲置几天而不处理任何一项任务,它也会将内存泄漏到达到内存限制并被主管杀死的程度。 您可以在前面的评论中找到更多详细信息和内存图表。

当工作人员按计划处理单个任务时,内存图表应该或多或少显示出方波状,但您可以清楚地看到总体内存使用量只会增加。
Screenshot 2020-08-14 at 20 42 24

我已经成功地将芹菜工人的概况介绍纳入了我们的路线图。 当我们开始进行这项工作时,我将分享内存转储和更多细节。

我可以确认关闭花朵(并通过设置显式禁用任务事件)修复了泄漏。

正如我之前提到的,在工人开始漏水的那一刻,我在花中注意到花会下线,而芹菜树总是很忙,所以我通过简单的方法关闭了花。

不幸的是,我找不到导致泄漏的那段代码。 但是至少可以解决此问题。

那么这可能不是芹菜问题,而是花朵?

@auvipy flower触发了此问题,但泄漏肯定发生在工作人员(芹菜)上

@auvipy flower触发了此问题,但泄漏肯定发生在工作人员(芹菜)上

很公平。 感谢分享。

我正在将芹菜与Redis和Flower一起使用,不得不说我目前没有看到任何内存问题。 关于数据,您想从我这里得到什么?

@auvipy没有使用Flower。 在禁用事件的情况下启动工作程序。

@auvipy没有使用Flower。 在禁用事件的情况下启动工作程序。

请尝试调试并找出内存泄漏的根源。 可能是芹菜,也可能是。 最好是可以共享单元测试和集成测试

请尝试调试并找出内存泄漏的根源。 可能是芹菜,也可能是。 最好是可以共享单元测试和集成测试

此处提到,即使芹菜工人未处理任何任务,我们也会看到由于芹菜工人泄漏内存而导致的OOM。
无法共享单元测试或集成测试,因为这会暴露公司的IP。 对不起。 但是我设法在我们的内部路线图上添加了一个任务,以捕获生产工人的内存转储。 完成后将共享一些场景的计数器和引用。

@jsynowiec如果可以在5.0.0 GA(更新为#6266)之前完成,那就

一个错误修正进入master之后,它也会被反向移植到4.x。

@thedrow 5.0的GA何时计划? 不幸的是,我们有一些遗留代码仍要迁移到Py3😞,因此我们暂时还停留在Celery 4上。

我们有一个发行阻止程序和一些文档要完成。
答案很快。

我可以确认关闭花会阻止泄漏。 我们已经运行了将近一个月而没有泄漏。

因此,我们的事件发布机制中仍然存在某个错误。
有谁知道这可能是什么?

我们不使用Flower,并且没有--events ,但是我们会遇到连续的内存泄漏。

答案很快。

我设法分配了高优先级,以从生产人员那里获取内存转储和对象计数器。 我应该能够在接下来的几周内发布一些数据。 我们还提高了完成py2-> py3移植的优先级,因此所有内容都应使用Python 3运行并进行概要分析

我担心的是,我们在这里谈论两个不同的问题。

显然。 一个与事件有关,也许与Flower有关,也可能使用RabbitMQ作为经纪人。 根据这里报道的问题,几年来,它在GitHub上出现了。 另一个(影响我的项目)与不同的组件有关,最有可能与将Redis用作代理有关。 也许从根本上讲,这些都是源自认识🤷🏼的相同代码的相同问题。 就像trail跟踪子任务和泄漏AsyncResult instances实例一样

@thedrow @auvipy只是让您知道我们现在正在转向工作人员的内存配置文件。

此外,在完成Python3迁移的完成时,我们遇到了另一个似乎与https://github.com/celery/celery/issues/4470https://github.com/celery/celery/issues/5359相关的问题join_native调用也会无限期挂起。 快速strace指向它的字面意义为“读取时挂起”,这可能表示某些低级内核/库内容。 现在我们切换到普通模式,因为我们专注于内存泄漏,所以将join池化。

大家好-终于有了一些数据: celery-memtrace-1.tar.xz签名我的密钥

存档包含〜16天后来自8个工作人员的tracemalloc日志,该时间段的内存使用情况图和一些版本信息(包括Celery启动横幅)。

老实说,我还没有花很多时间来分析这些问题,但是a)我们的代码从未出现在列表中,b)可能与SQLAlchemy发生了一些怪异的交互,我们也在各处使用了SQLAlchemy,因此问题并非并非不可能在其他地方,或者是组合/互动问题。

如果还有其他详细信息有用,请询问。 我们还将继续使用此内存使用情况日志来运行这8个工作程序,因此也许将能够收集更多/更好的数据。

编辑:此线程也与此注释相关-我们仍然使用相同的设置。

希望您能找到造成此泄漏的根本原因。
我会花一些时间自己研究一下。

我想知道这是否可以缓解问题。
https://reliability.substack.com/p/run-python-servers-更有效率

我们正在研究内存泄漏源在请求库中而不是芹菜本身的可能性。 还有其他人正在使用任务中的请求在芹菜中经历内存泄漏吗?

@ErrorInPersona是的,我们正在有和没有请求的情况下在工作人员中注册OOM。

@drbig有运气吗?

Screenshot_2020-11-17_12-56-28

好吧,看看“绿色的那一面”,地板在慢慢地上升,但是肯定是……。不幸的是,除了快速确认“是的,这仍然是一个问题”,我的补充并不多。

但是,我已经略过了@thedrow提供的链接,并且我的待办事项列表(无底洞)现在包括- try running some workers with jemalloc forced in ,所以我将_eventually_做到这一点。

此页面是否有帮助?
0 / 5 - 0 等级