我有一个庞大的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()
我还有一个manage.py命令,只需运行my_task(int(args [0]))即可将其排队或在命令行上运行。
在命令行中运行时,print_memory_usage()显示使用的内存量相对稳定。
当在celery中运行时,print_memory_usage()显示内存不断增加,直到进程被杀死(我正在使用具有1GB内存限制的Heroku,但其他主机会有类似的问题)。内存泄漏似乎对应于chunk_size;如果增加chunk_size,则每次打印时内存消耗会增加。这似乎表明celery本身正在记录查询,或者我的堆栈中的其他东西正在记录。
Celery是否在其他地方记录查询?
其他注意事项:
-DEBUG关闭。 -无论是使用RabbitMQ还是Amazon的SQS作为队列,都会发生这种情况。 -这在本地和Heroku上都发生(尽管由于拥有16 GB的RAM而在本地未被杀死)。 -任务实际上会做更多的事情,而不仅仅是删除对象。稍后,它通过MyModel.objects.get_or_create()创建新对象。这也表现出相同的行为(在celery下内存增长,在manage.py下不增长)。
itertools.islice(related_ids, i, i + chunk_size)
而不是related_ids[i:i+chunk_size]
。这可能不是唯一的因素,但这样做可以减少一些复制。 - Steve Howard