Celery 任务偶尔会在错误的工作线程上运行

问题描述 投票:0回答:1

我在 Heroku 上使用 Django 和 celery 以及 Redis。 我有两个队列,称为“celery”和“letters

我在 Heroku 上有两种工作类型

  • worker(具有大量 RAM 的 Dyno)。它可以运行两个队列中的任务
  • letter-worker 是一个较小的实例:它应该只处理“letters”队列中的任务。

我的heroku procfile如下所示:

worker: REMAP_SIGTERM=SIGQUIT celery -A shareforce.taskapp worker --loglevel=info --concurrency=3 --prefetch-multiplier=2 -Q letters,celery
letter-worker: REMAP_SIGTERM=SIGQUIT celery -A shareforce.taskapp worker --loglevel=info --concurrency=2 --prefetch-multiplier=2 -Q letters -X celery

在我的配置中我有这个设置

CELERY_TASK_DEFAULT_QUEUE = "celery"

我有以下芹菜任务:

@shared_task(queue="celery")
def generate_export(**kwargs):
    pass

我这样称呼它:

generate_export.delay()

偶尔,大约有五十分之一的人会在信件工作人员上运行,导致其内存不足,从而重新启动应用程序,从而杀死任一工作人员上正在运行的任何任务。

我不知道这怎么可能或如何解决。

任何有关如何修复或调试它的建议的帮助将不胜感激。

heroku celery django-celery
1个回答
0
投票

您遇到的问题可能是由任务路由设置错误或 -X celery 标志未能正确从 letter-worker 中删除 celery 队列引起的。

这里更全面地解释了此问题的潜在原因和解决方案。

  1. 配置任务路由 如果应用了 CELERY_TASK_DEFAULT_QUEUE = "celery" 设置,则 celery 队列将成为没有指定队列的任务的目标。仔细检查并没有什么坏处,但由于您在定义任务时直接分配queue =“celery”,所以不可能需要它。

验证任务队列中的分配:验证generate_export是否正确赋予了queue =“celery”。鉴于您说它偶尔在信件工作人员上运行,Celery 的路由中可能存在竞争条件或错误。

Celery 的排除 (-X) 标志 您的 letter-worker 配置的 -X celery 设置旨在将 celery 队列排除在外。但有时,由于配置错误,信件工作人员可能会无意中从 celery 队列中选择作业。

解决方案:确保在您的配置中配置了正确的路由规则,并将作业手动路由到适当的工作人员,而不是使用 -X celery。

  1. 将显式任务路由付诸实践 为了保证作业被适当地路由到合适的队列,您可以建立更详细的任务路由策略。

将以下内容添加到您的settings.py中:

通过这种方式,作业将始终按照您指定的路由规则发送到正确的队列。

  1. Procfile 中不同的任务类别 Heroku Procfile 中指定了哪些工作人员负责哪些队列。您可以清楚地区分不同的任务类型,而不是依赖于 -X:

对您的 Heroku Procfile 进行以下更改: 通过这种方式,worker 仅处理来自 celery 队列的作业,并且 letter-worker 仅处理来自 letters 队列的任务。由于队列分配负责分离,因此不再需要 -X 标志。

  1. 管理工作队列中的并发 限制并发可以通过减少在信件工作人员上执行的并发任务量来帮助您防止信件工作人员遇到内存过载。尽管您将并发度设置为 2,但如果内存问题持续存在,您可能希望进一步减少并发度,以防止较小的作业使较小的实例过载。

  2. 额外故障排除 检查工作日志记录:在 Celery 中打开更彻底的日志记录,以监控哪些员工正在从事哪些工作。这将帮助您确定为什么将特定任务分配给不正确的员工。 通过使用worker命令将日志级别设置为debug,您可以提高日志的详细程度: 注意 Redis:Redis 的队列中有时可能仍有某些作业,由于旧的设置或任务分配冲突,这些作业被不正确的工作线程拾取。可以监视 Redis 队列以确保它们正常运行。

完整设置:修改 Procfile 以在芹菜队列和信件队列之间划分劳动力。 确保您的设置清楚地说明了任务路由。py。 修改内存密集型或并发密集型进程以避免较小实例过载。 要密切关注任务执行和路由,请使用调试和日志记录。 按照这些说明,您应该能够保证您的信件工作人员仅完成信件队列中的作业,而远离芹菜中的任务。

© www.soinside.com 2019 - 2024. All rights reserved.