在我的django项目中,我有以下依赖项:
在dev_settings.py中:
DEBUG = False
BROKER_URL = "django://"
import djcelery
djcelery.setup_loader()
CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERYD_CONCURRENCY = 2
# CELERYD_TASK_TIME_LIMIT = 10
CELERYD_TASK_TIME_LIMIT
根据https://stackoverflow.com/a/17561747/1452356
debug_toolbar
的建议进行评论
我在shell中启动我的worker:
./manage.py celeryd --settings=dev_settings
然后我发送任务:
class ExempleTask(Task):
def run(self, piProjectId):
table = []
for i in range(50000000):
table.append(1)
return None
使用django命令:
class Command(BaseCommand):
def handle(self, *plArgs, **pdKwargs):
loResult = ExempleTask.delay(1)
loResult.get()
return None
使用:
./manage.py purge_and_delete_test --settings=dev_settings
我通过以下方式监控内存使用情况:
watch -n 1 'ps ax -o rss,user,command | sort -nr | grep celery |head -n 5'
每次调用任务时,都会增加celeryd / worker进程的内存消耗,与其中分配的数据量成比例...
这似乎是一个常见的问题(参见其他stackoverflow链接),但是我无法修复它,即使是最新的依赖项。
感谢。
答案 0 :(得分:5)
这是一个Python和操作系统问题,而不是真正的django或芹菜问题。没有太深入:
1)一旦从OS请求了进程,进程就永远不会释放内存寻址空间。它永远不会说“嘿,我在这里完成了,你可以把它拿回来”。在您给出的示例中,我希望流程大小会增长一段时间,然后稳定,可能在高基线上。在您的示例分配之后,您可以调用gc
接口强制垃圾收集以查看
2)这通常不是问题,因为操作系统会将未使用的页面调出,因为您的进程会停止访问已解除分配的地址空间。
3)如果您的进程泄漏了对象引用,阻止python从垃圾回收中重新适应该空间以供以后重用该进程,并要求您的进程要求更多,则会出现问题来自操作系统的地址空间。在某些时候,操作系统会骂叔叔,并且(可能)用它的oomkiller或类似机制杀死你的进程。
4)如果你正在泄漏,要么修复泄漏,要么设置CELERYD_MAX_TASKS_PER_CHILD
,你的子进程将(可能)在沮丧操作系统之前自杀。
这是关于Python内存管理的一个很好的一般性讨论: CPython memory allocation
还有一些小事:
使用xrange
而非range
- 范围将生成所有值,然后迭代该列表。 xrange
只是一个发电机。设置Django DEBUG = False?