芹菜不释放记忆

Dec*_*Qiu 12 python amqp rabbitmq celery

看起来芹菜在任务完成后不释放内存.每次任务完成时,都会有5m-10m的内存泄漏.因此,随着成千上万的任务,很快就会耗尽所有内存.

BROKER_URL = 'amqp://user@localhost:5672/vhost'
# CELERY_RESULT_BACKEND = 'amqp://user@localhost:5672/vhost'

CELERY_IMPORTS = (
    'tasks.tasks',
)

CELERY_IGNORE_RESULT = True
CELERY_DISABLE_RATE_LIMITS = True
# CELERY_ACKS_LATE = True
CELERY_TASK_RESULT_EXPIRES = 3600
# maximum time for a task to execute
CELERYD_TASK_TIME_LIMIT = 600
CELERY_DEFAULT_ROUTING_KEY = "default"
CELERY_DEFAULT_QUEUE = 'default'
CELERY_DEFAULT_EXCHANGE = "default"
CELERY_DEFAULT_EXCHANGE_TYPE = "direct"
# CELERYD_MAX_TASKS_PER_CHILD = 50
CELERY_DISABLE_RATE_LIMITS = True
CELERYD_CONCURRENCY = 2
Run Code Online (Sandbox Code Playgroud)

可能与问题相同,但它没有答案: RabbitMQ/Celery/Django内存泄漏?

我没有使用django,我的包是:

Chameleon==2.11
Fabric==1.6.0
Mako==0.8.0
MarkupSafe==0.15
MySQL-python==1.2.4
Paste==1.7.5.1
PasteDeploy==1.5.0
SQLAlchemy==0.8.1
WebOb==1.2.3
altgraph==0.10.2
amqp==1.0.11
anyjson==0.3.3
argparse==1.2.1
billiard==2.7.3.28
biplist==0.5
celery==3.0.19
chaussette==0.9
distribute==0.6.34
flower==0.5.1
gevent==0.13.8
greenlet==0.4.1
kombu==2.5.10
macholib==1.5.1
objgraph==1.7.2
paramiko==1.10.1
pycrypto==2.6
pyes==0.20.0
pyramid==1.4.1
python-dateutil==2.1
redis==2.7.6
repoze.lru==0.6
requests==1.2.3
six==1.3.0
tornado==3.1
translationstring==1.1
urllib3==1.6
venusian==1.0a8
wsgiref==0.1.2
zope.deprecation==4.0.2
zope.interface==4.0.5
Run Code Online (Sandbox Code Playgroud)

我刚刚添加了一个测试任务,test_string是一个大字符串,它仍然有内存泄漏:

@celery.task(ignore_result=True)
def process_crash_xml(test_string, client_ip, request_timestamp):
    logger.info("%s %s" % (client_ip, request_timestamp))
    test = [test_string] * 5
Run Code Online (Sandbox Code Playgroud)

Eri*_*ken 11

有两种设置可以帮助您减轻 celery 工作人员不断增长的内存消耗:

\n\n
\n

使用此选项,您可以配置工作进程在被新进程替换\xe2\x80\x99s 之前可以执行的最大任务数。如果您无法控制内存泄漏,例如来自闭源 C 扩展的内存泄漏,这非常有用。

\n
\n\n
\n

使用此选项,您可以配置工作线程在被新进程替换\xe2\x80\x99s之前可以执行的最大驻留内存量。\n如果您存在无法控制的内存泄漏(例如来自闭源 C 的内存泄漏),这将非常有用扩展。

\n
\n

但是,这些选项仅适用于默认池(预分叉)。

\n

为了安全地防止线程和 gevent 池的内存泄漏,您可以添加一个名为memmon的实用程序进程,它是主管的superlance扩展的一部分。

\n

Memmon 可以监控所有正在运行的工作进程,并在超出预定义的内存限制时自动重新启动它们。

\n

以下是 Supervisor.conf 的配置示例:

\n
[eventlistener:memmon]\ncommand=/path/to/memmon -p worker=512MB\nevents=TICK_60\n
Run Code Online (Sandbox Code Playgroud)\n


小智 7

当您启动工作进程时,只需设置 max-tasks-per-child 选项,如下所示,以便在每个任务后重新启动工作进程:

\n

celery -A app worker --loglevel=info --max-tasks-per-child=1

\n

这是文档:

\n

https://docs.celeryproject.org/en/latest/userguide/workers.html#max-tasks-per-child-setting

\n
\n

使用此选项,您可以配置工作进程在被新进程替换\xe2\x80\x99s 之前可以执行的最大驻留内存量。

\n

如果您无法控制内存泄漏,例如来自闭源 C 扩展的内存泄漏,这非常有用。

\n

可以使用workers --max-memory-per-child参数或使用worker_max_memory_per_child设置来设置该选项。

\n
\n


Dec*_*Qiu 6

正是此配置选项使我的工作人员无法释放内存。

CELERYD_TASK_TIME_LIMIT = 600
Run Code Online (Sandbox Code Playgroud)

请参考:https : //github.com/celery/celery/issues/1427