【Django Celery取消预取机制】

文章描述了在Django+Celery+Redis环境中,如何通过设置Celery的配置参数来取消预取机制,以确保worker每次只处理一个任务,防止长时间占用任务导致其他worker无法获取新任务的问题。尝试在settings.py和启动命令中设置并发量和预取量未达到预期效果,最终解决方案是在celery.py中设置`CELERY_ACKS_LATE=True`,`CELERYD_CONCURRENCY=1`和`CELERYD_PREFETCH_MULTIPLIER=1`。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Django Celery取消预取机制

基本情况

Django + celery,消息队列用的是redis,开启Django服务后,接着开启celery,开启celery的命令如下:

# Linux
celery -A zy_ds worker -l info  # 测试使用
nohup celery -A zy_ds worker -l info > celery.log 2>&1 &  # 正常启动
nohup celery -A zy_ds worker --prefetch-multiplier=1 -l info > celery.log 2>&1 &  # 设置并发量为1

# Windows
celery -A zy_ds worker -l info -P eventlet  # Windows中需要加-P eventlet
# Windows中需要提前pip install eventlet

settings.py中celery的配置如下:

# ../zy_ds/zy_ds/settings.py
# celery配置
CELERY_BROKER_URL = 'redis://:123456@127.0.0.1:6379/0'
CELERY_RESULT_BACKEND = 'redis://:123456@127.0.0.1:6379/0'

# celery内容等消息的格式设置
CELERY_TASK_SERIALIZER = 'pickle'
CELERY_RESULT_SERIALIZER = 'pickle'
CELERY_ACCEPT_CONTENT = ['pickle', 'application/json']

# Worker并发数量,一般默认CPU核数,可以不设置
CELERY_WORKER_CONCURRENCY = 1

# 预取机制(每次去消息队列读取任务的数量,默认值是4) 
CELERY_PREFETCH_MULTIPLIER = 1

项目主目录中的celery.py设置如下:

# ../zy_ds/zy_ds/celery.py
import os
from celery import Celery
from django.conf import settings

# 设置环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'zy_ds.settings')

# 实例化
app = Celery('zy_ds')

# namespace='CELERY'作用是允许你在Django配置文件中对Celery进行配置
# 但所有Celery配置项必须以CELERY开头,防止冲突
app.config_from_object('django.conf:settings', namespace='CELERY')

# 自动从Django的已注册app中寻找加载worker函数(例如每个app下的tasks.py)
app.autodiscover_tasks(settings.INSTALLED_APPS)

问题

本人在settings.py中设置的worker并发数量是1,预取的数量也是1,就是想实现worker每次只从redis消息队列中拿一个任务,每次只执行一个任务,并且禁用预取机制。(因为预取机制很有可能导致这样一个问题:一个worker在执行某个耗时任务A时,它预取的任务B长时间被它占用并得不到释放,会使其他worker想要取任务时取不到,导致执行效率低下)

尝试1:(在启动命令中添加参数:-O fair)
celery -A zy_ds worker --loglevel=info -O fair

尝试2:(在settings.py中添加如下参数)
CELERY_ACKS_LATE = True
CELERY_CONCURRENCY = 1
CELERY_PREFETCH_MULTIPLIER = 1

除此之外也试过其他方法,均无效

解决

重点是在celery.py中添加参数,而不是在settings.py中添加,celery.py参数添加如下:

# ../zy_ds/zy_ds/celery.py
import os
from celery import Celery
from django.conf import settings

# 设置环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'zy_ds.settings')

# 实例化
app = Celery('zy_ds')

# 添加配置参数,取消预取机制
app.conf.CELERY_ACKS_LATE = True
app.conf.CELERYD_CONCURRENCY = 1  # 并发的worker数量 可选
app.conf.CELERYD_PREFETCH_MULTIPLIER = 1  # 预取的任务数量

app.config_from_object('django.conf:settings', namespace='CELERY')

# 自动从Django的已注册app中寻找加载worker函数(例如每个app下的tasks.py)
app.autodiscover_tasks(settings.INSTALLED_APPS)
### 加速Django下载速度的方法 #### 1. 使用异步任务队列处理文件生成和发送 对于大型文件或复杂的数据处理操作,同步执行可能会阻塞HTTP请求响应时间。采用`celery`这样的消息队列工具能够有效缓解这一问题。通过将耗时的任务交给后台工作进程去完成,前端可以立即返回成功状态给用户,并允许用户提供一个链接稍后获结果。 例如,在涉及大量记录的CSV导出场景下,利用`django-import-export-celery`插件可以让这些过程在独立的工作线程中运行[^1]: ```python from import_export_celery.models import ExportJob, ImportJob job = ExportJob.objects.create( app_label='your_app', model_name='YourModel' ) result = job.process() ``` #### 2. 缓存机制的应用 为了加快重复访问相同资源的速度,应该充分利用浏览器端和服务端之间的缓存策略。设置合适的Cache-Control头信息,使得客户端能够在一定时间内重用之前已经加载过的版本而无需再次发起网络请求;同时也可以考虑部署分布式内存对象存储系统如Redis作为中间层来暂存热点数据片段,从而减轻主数据库的压力并缩短读延迟[^2]。 #### 3. 静态文件优化与CDN分发 当涉及到图片、样式表以及其他不经常变动的内容时,建议将其托管至专门设计用于高速传输此类资产的服务提供商处——即内容传递网络(CDN),它们通常在全球范围内拥有众多节点位置,可依据访客地理位置自动选最近服务器提供服务,进而达到最佳用户体验效果。 #### 4. 数据库查询效率改进 针对特定情况下因频繁交互造成的瓶颈现象,可以通过相关联的对象字段(`select_related`)或者批量检索多个外键指向的目标实例(`prefetch_related`)的方式减少SQL语句的数量级,以此降低I/O成本并提升整体吞吐量表现[^4]。 ```python queryset = YourModel.objects.select_related('foreign_key_field').all() serializer = YourModelSerializer(queryset, many=True) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值