GDo*_*orn 5 python django memory-leaks celery
我有一个巨大的芹菜任务基本上像这样工作:
@task
def my_task(id):
if settings.DEBUG:
print "Don't run this with debug on."
return False
related_ids = get_related_ids(id)
chunk_size = 500
for i in xrange(0, len(related_ids), chunk_size):
ids = related_ids[i:i+chunk_size]
MyModel.objects.filter(pk__in=ids).delete()
print_memory_usage()
Run Code Online (Sandbox Code Playgroud)
我还有一个manage.py命令,只运行my_task(int(args [0])),因此可以排队或在命令行上运行.
在命令行上运行时,print_memory_usage()会显示相对恒定的内存量.
当在celery中运行时,print_memory_usage()显示内存量不断增加,一直持续到进程被终止(我使用Heroku的内存限制为1GB,但其他主机会有类似的问题.)内存泄漏似乎与chunk_size对应; 如果我增加chunk_size,每次打印的内存消耗会增加.这似乎暗示芹菜正在记录查询本身,或者我的堆栈中的其他东西.
芹菜会在其他地方记录查询吗?
其他说明:
事实证明这与芹菜没有任何关系。相反,是 new relic 的记录器消耗了所有内存。尽管 DEBUG 设置为 False,它仍将每个 SQL 语句存储在内存中,准备将其发送到日志服务器。我不知道它是否仍然如此,但在任务完全完成之前它不会刷新该内存。
解决方法是对每个 id 块使用子任务,以对有限数量的项目进行删除。
当将其作为管理命令运行时这不是问题的原因是 new relic 的记录器没有集成到命令框架中。
提出的其他解决方案试图减少分块操作的开销,这对解决 O(N) 扩展问题没有帮助,或者在超出内存限制时强制 celery 任务失败(该功能在时间,但最终可能会进行无限次重试。)