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