资讯专栏INFORMATION COLUMN

Celery实际使用与内存泄漏问题(面试)

0x584a / 740人阅读

摘要:结论执行完任务不释放内存与原一直没有被销毁有关,因此可以适当配置小点,而任务并发数与配置项有关,每增加一个必然增加内存消耗,同时也影响到一个何时被销毁,因为是均匀调度任务至每个,因此也不宜配置过大,适当配置。

1.实际使用

监控task的执行结果:任务id,结果,traceback,children,任务状态

​ 配置 backend="redis://127.0.0.1:6379/5"给Celery的app对象,直接在redis中查看

​ 还可以

健壮celerycelery -A proj worker -l info

☁  proj  tree
├── __init__.py 
├── celery.py | app=Clery("proj",include=["proj.tasks"])
                app.config_from_object("proj.config")
                if __name__==__main__: app.start()
├── config.py |  CELERY_RESULT_BACKEND = "redis://127.0.0.1:6379/6"
                BROKER_URL = "redis://127.0.0.1:6379/5"      
└── tasks.py  |  @app.task            # 注意这个文件名必须是tasks.py
                def add(x, y): return x + y             

​ tasks可以有多个在celery.py中添加一行代码加载任务函数

app.autodiscover_tasks(["proj.sms", "proj.email"])

Scheduler计划定时任务:celery -A proj worker -B -l info

#config.py
CELERY_TIMEZONE = "Asia/Shanghai" # 指定时区
from datetime import timedelta
CELERYBEAT_SCHEDULE = {
    "add-every-30-seconds": {
         "task": "proj.tasks.add", # 指定要执行的函数任务
         "schedule": timedelta(seconds=30), # 指定计划时间间隔30s执行一次task
         "args": (16, 16)
    },
}

celery.schedules import crontab定时周期任务:(比如每周一执行一次 )

​ 只需要修改 "schedule": crontab(hour=7, minute=30, day_of_week=1),

2.celery扩展使用

指定队列名:

​ 启动加上-Q参数 celery -A proj worker --loglevel=info -Q "testq"

​ 跑任务时 add.delay(3,4,queue="testq")

指定开启的worker进程数:单个Celery进程每分钟就可以处理数百万个任务

​ 底层是调用的Python的multiprocessing模块中的Pool进程池思想来做

​ 启动加上-c参数 celery -A proj worker --loglevel=info -c 2 2个worker进程来同时抢任务

图像化查看broker里面的数据,查看任务状态,以及任务的详细信息:flower的webUI

pip install flower 注意创建celery实例app时指定的broker设置的redis/5

​ 任意目录执行 celery flower --port=5555 --broker=redis://localhost:6379/5

3.DJango-celery模式(嵌入到大型DJango项目中)

应用: django调用celery跑异步任务,常见场景有注册成功,发送邮件可以异步来防止网络IO阻塞,以及耗时间的任务,可以在WEB应用中使用这种异步方式

安装django-celery==3.1.17celery==3.1.17对应

创建celery必须的数据库表结构 python manage.py migrate

django项目的settings.py文件中追加如下内容:backend,任务执行结果超时时间,worker并发数也就是 -c 指定的数据,指定任务周期存储在orm数据库中

在django的app应用目录下创建tasks.py任务文件@task def add(x,y):

开启django服务和celery服务,虽然耦合了,还要开python manage.py celery worker --loglevel=info

4.内存泄漏问题

celery内存泄露分析

celery配置项如下

CELERYD_CONCURRENCY = 2      celery worker并发数
CELERYD_MAX_TASKS_PER_CHILD = 5   每个worker最大执行任务数

 
执行celery -A ansibleAPI.celery worker启动celery,通过ps -ef | grep celery可以看到两个celery worker进程(8226,8228)。

利用celery worker进行某个任务,当worker没有执行到最大任务时(即销毁重建),每执行一次任务占用内存必然有所增加,任务数为9,10时(celery均匀调度,并发数*最大任务数),分别有原8228 worker被销毁,重新创建9386 worker及原8226 worker被销毁,重新创建9564 worker,此时,运行第9次时,占用总内存有所下降,运行第10次时,总内存回到初如值,同样任务执行第19、20次情况类似。

celery并发计算规则
celery任务并发只与celery配置项CELERYD_CONCURRENCY 有关,与CELERYD_MAX_TASKS_PER_CHILD没有关系,即CELERYD_CONCURRENCY=2,只能并发2个worker,此时任务处理较大的文件时,执行两次可以看到两个task任务并行执行,而执行第三个任务时,开始排队,直到两个worker执行完毕。

结论
celery执行完任务不释放内存与原worker一直没有被销毁有关,因此CELERYD_MAX_TASKS_PER_CHILD可以适当配置小点,而任务并发数与CELERYD_CONCURRENCY配置项有关,每增加一个worker必然增加内存消耗,同时也影响到一个worker何时被销毁,因为celery是均匀调度任务至每个worker,因此也不宜配置过大,适当配置。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43680.html

相关文章

  • 【进阶1-5期】JavaScript深入之4类常见内存泄漏及如何避免

    摘要:本期推荐文章类内存泄漏及如何避免,由于微信不能访问外链,点击阅读原文就可以啦。四种常见的内存泄漏划重点这是个考点意外的全局变量未定义的变量会在全局对象创建一个新变量,如下。因为老版本的是无法检测节点与代码之间的循环引用,会导致内存泄漏。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第一期,本周的主题...

    red_bricks 评论0 收藏0
  • Android&Java面试题大全—金九银十面试必备

    摘要:需要校验字节信息是否符合规范,避免恶意信息和不规范数据危害运行安全。具有相同哈希值的键值对会组成链表。通过在协议下添加了一层协议对数据进行加密从而保证了安全。常见的非对称加密包括等。 类加载过程 Java 中类加载分为 3 个步骤:加载、链接、初始化。 加载。 加载是将字节码数据从不同的数据源读取到JVM内存,并映射为 JVM 认可的数据结构,也就是 Class 对象的过程。数据源可...

    renweihub 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<