弹性豆茎上自动缩放的 django 应用程序的多个 celery beat 实例

Posted

技术标签:

【中文标题】弹性豆茎上自动缩放的 django 应用程序的多个 celery beat 实例【英文标题】:Multiple instances of celerybeat for autoscaled django app on elasticbeanstalk 【发布时间】:2017-02-28 10:33:19 【问题描述】:

我正在尝试找出构建 Django 应用程序的最佳方式,该应用程序使用 Celery 在自动缩放的 AWS ElasticBeanstalk 环境中处理异步和计划任务。

到目前为止,我只使用了带有 Celery + Celerybeat 的单实例 Elastic Beanstalk 环境,并且效果很好。但是,我希望在我的环境中运行多个实例,因为不时有一个实例崩溃,并且实例备份需要很长时间,但我无法将当前架构扩展到多个实例,因为Celerybeat 应该在所有实例中只运行一次,否则 Celerybeat 安排的每个任务都将被多次提交(环境中的每个 EC2 实例一次)。

我已经阅读了多种解决方案,但它们似乎都存在不适合我的问题:

使用 django 缓存 + 锁定:这种方法更像是一种快速修复而不是真正的解决方案。如果您有很多计划任务并且需要添加代码来检查每个任务的缓存,这不是解决方案。此外,任务仍会多次提交,这种方法只能确保停止执行重复项。 将 leader_only 选项与 ebextensions 一起使用:最初工作正常,但如果环境中的 EC2 实例崩溃或被替换,这将导致根本没有运行 Celerybeat 的情况,因为领导者仅在创建时定义一次环境。 为 Elastic Beanstalk 工作器层中的异步任务创建一个新的 Django 应用程序:很好,因为 Web 服务器和工作器可以独立扩展,并且 Web 服务器性能不受工作器执行的巨大异步工作负载的影响。但是,这种方法不适用于 Celery,因为工作层 SQS 守护程序会删除消息并将消息正文发布到预定义的 url。此外,我不喜欢有一个完整的附加 Django 应用程序,该应用程序需要从主应用程序导入模型,并且如果在主应用程序中修改了任务,则需要单独更新和部署。

如何在分布式 Elastic Beanstalk 环境中将 Celery 用于计划任务而不重复任务?例如。如何确保在 Elastic Beanstalk 环境中始终在所有实例中运行一个实例(即使当前带有 Celerybeat 的实例崩溃)?

还有其他方法可以实现吗?将 Elastic Beanstalk 的 Worker Tier 环境与 Django 结合使用的最佳方式是什么?

【问题讨论】:

您找到解决方案了吗?我有同样的问题 您能告诉我解决方案吗?我有同样的问题。 正如我在下面提到的,我改用 django-q 来管理任务,因为我可以在一小时内解决我的问题,而我想不出一个简单的 Celery 解决方案。 【参考方案1】:

我想你可以将 celery beat 挑出到不同的组。

您的 Auto Scaling 组运行多个 django 实例,但 celery 未包含在扩展组的 ec2 配置中。

你应该为 celery beat 设置不同的(或只有一个)实例

【讨论】:

【参考方案2】:

如果有人遇到类似问题:我最终切换到了 django 的不同队列/任务框架。它被称为 django-q,并在不到一个小时的时间内设置完毕并开始工作。它具有我需要的所有功能,并且比 Celery 更好地集成了 Django(因为 djcelery 不再处于活动状态)。

Django-q 超级好用,而且比庞大的 Celery 框架更轻巧。我只能推荐它!

【讨论】:

我不确定如何管理多个 celery beat 实例的答案是不使用 celery beat。 这不应该是解决方案。但我决定分享我最终所做的事情,因为其他人可能仍然会发现它很有用,以防他们被困在同一点上。 这应该是对原始问题的评论而不是答案

以上是关于弹性豆茎上自动缩放的 django 应用程序的多个 celery beat 实例的主要内容,如果未能解决你的问题,请参考以下文章

在弹性豆茎上创建环境时出现 502

在弹性豆茎上运行 celery-worker

如何在弹性豆茎上安装 ng

让 peewee 在弹性豆茎上工作

如何在弹性豆茎上更新 python Flask 应用程序?

在弹性豆茎上运行 knex 迁移