celery占用大内存问题记录

celery worker占用大内存记录

定位

命令参考

  1. top命令下,M键开启按MEM列排序的进程列表,按H则查看线程列表,由于worker没有子线程,所以只显示一条记录;
  2. c命令,开始COMMAND列详细情况,可以找到对应的进程启动者;
  3. o键,开启筛选功能,输入COMMAND=celery只显示celery名的进程列表;

top的内存大小列为:VIRT, RES,分别为虚拟内存与实际内存占用;

到这里,就已经定位到了消耗内存的进程是哪些,启动者是哪个,如果还想看下进程间的关系,则使用命令:

ps -auxf

来查看进程之间的关系,通过上面的top命令可以知道进程PID,此时就可以通过PID来过滤:

ps -auxf | grep PID -A 20 -B 20

在celery中,可以看到celery进程是以父子进程的形式管理的,父woker会创建多个子worker来执行任务,在显示的数据中能看到父worker与子worker的内存占用情况,如下图所示:
这里写图片描述

原因

  1. celery的worker进程是有工作时间与次数限制的,也就是说,如果调用次数到达一次数次,就会被回收,并重新创建(这里有错,见下面说明)。显然这里的情况就很有可能是进程没有被正常回收,那就可能是因为进程一直有个任务在运行,所以首先我去查询了对应的执行日志,结果发现日志一切正常,且worker的CPU也没显示在执行任务,所以这个排除;

错误点说明

默认情况下,celery的worker是没有对进程执行任务数作限制的,见官网说明
Maximum number of tasks a pool worker process can execute before it’s replaced with a new one. Default is no limit.
所以需要自己配置worker_max_tasks_per_child值,django下配置:CELERYD_MAX_TASKS_PER_CHILD

  1. 其次我想到的是一些非正常网络连接或文件打开,确没有正常释放文件句柄,导致资源一直在消耗,所以我去检查下进程文件句柄的使用情况,采用如下命令:
lsof -n | grep 12987

过虑出该进程的句柄使用列表,结果发现其句柄数量正常:ps -aux | grep celery | wc -c
3. 没有办法了,只能祭出神器google了,查询到一篇不错的文章:不错的celery问题博客,该文章中提到了celery内存泄露的问题,但是写于2010年,版本已经非常落后,且他只说明了一个问题,supervisor执行restart操作,不会使得子进程重启,所以建议大家使用stop+start操作,或是配置supervisor stopasgroup=true,相关参考见:官方配置issuesissues

经过上面这些无用的过程,最终结论还是,supervisorctl下执行stop + start
还有官网下stop worker的命令,也就是建议使用kill -TERM PID

还有这篇文章:最大执行次数可以配置小点最大执行任务数CELERYD_MAX_TASKS_PER_CHILD

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值