Celery:AWS ECS Autoscale 缩减事件(如何不破坏长时间运行的任务?)
Posted
技术标签:
【中文标题】Celery:AWS ECS Autoscale 缩减事件(如何不破坏长时间运行的任务?)【英文标题】:Celery: AWS ECS Autoscale scale-in Event (how to not destroy long running tasks?) 【发布时间】:2021-05-13 11:51:37 【问题描述】:我正在 AWS ECS 集群中运行 Python Celery(分布式任务队列库)工作程序(每个 EC2 实例运行 1 个 Celery 工作程序),但这些任务运行时间很长,而且不是幂等的。这意味着当发生自动缩放事件时,即 ECS 由于任务负载低而终止运行工作程序的容器之一时,该工作程序上当前正在进行的长时间运行的任务将永远丢失。
是否有人对如何配置 ECS 自动缩放以便在完成之前不终止任何任务有任何建议?理想情况下,ECS 缩减事件将在它想要终止的 EC2 实例中启动 Celery 工作程序的热关闭,但只有在 Celery 工作程序完成热关闭后才实际终止 EC2 实例,这发生在其所有任务完成之后完成。
我也知道有一种叫做实例保护的东西,它可以通过编程方式进行设置,并保护实例不会在缩减自动缩放事件中被终止:https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection-instance
但是,我不知道任何 Celery 信号会在所有任务在热关机中完成后触发,所以我不确定我如何以编程方式知道何时禁用保护。即使我找到了一种在适当的时候禁用保护的方法,谁来管理首先向哪个工作人员发送关闭信号?是否可以将 EC2 配置为在缩减事件中对实例执行自定义操作(例如执行 celery 热关机),而不是仅仅终止 EC2 实例?
【问题讨论】:
【参考方案1】:我认为,当 ECS 缩减您的任务时,它会发送 SIGTERM,等待 30 秒(默认)并使用 SIGKILL 终止任务的容器。
我认为您可以使用此变量增加信号之间的时间:ECS_CONTAINER_STOP_TIMEOUT
。
这样,您的 celery 任务就可以完成,并且不会向该 celery worker 添加新任务(收到 SIGTERM 后热关机)。
这个答案可能会对您有所帮助: https://***.com/a/49564080/1011253
【讨论】:
非常感谢!这是一个很好的建议。我遇到的一个新问题是,我们的部署过程(我们为工人更新代码的地方)似乎被阻塞了,直到工人容器完全死亡,如果他们有很长的工作要完成,这可能需要很长时间。我们在同一个集群上运行了 50 多个应用程序,因此让一个实例暂停任务放置可以阻止其中任何一个更新其任务定义。你会不会有什么想法?我们不确定该怎么做,AWS 支持人员表示使用 AWS Batch,但这对于快速开始和完成小型工作来说并不是很好。 我正在寻找一种解决方案,我们可以让新工作人员使用更新的代码来使用新消息,但旧工作人员可以用很长的 ECS_CONTAINER_STOP_TIMEOUT 完成自己,并且不会阻止其他任务放置。 如果您的自动缩放将基于队列深度,我想您可以这样做。似乎在 ECS 中是可能的 (aws.amazon.com/blogs/containers/…) 我是在 Kubernetes 中完成的,你可以在这里阅读:itay-bittan.medium.com/hpa-for-celery-workers-6efd82444aee 你有没有想出一个可行的解决方案@DominicNapoleon @KeirWhitlock 不是真的。我们曾考虑使用 AWS Batch,但后来决定放弃,因为我们需要立即执行作业,无需等待【参考方案2】:我们公司的做法是不使用 ECS,只使用“普通”EC2(针对此特定服务)。我们有一个“自动扩展”任务,每 N 分钟运行一次,根据情况将集群扩展 M 台新机器(均通过 AWS 参数存储进行配置)。所以基本上芹菜自己放大/缩小。我提到的任务还会向每个超过 10 分钟且完全空闲的工作人员发送关闭信号。当 Celery worker 关闭时,整个机器都会终止(实际上,Celery worker 通过关闭机器电源的@worker_shutdown.connect
处理程序将其关闭——所有这些 EC2 实例都有“终止”关闭策略)。集群每天处理数百万个任务,其中一些任务运行时间长达 12 小时...
【讨论】:
以上是关于Celery:AWS ECS Autoscale 缩减事件(如何不破坏长时间运行的任务?)的主要内容,如果未能解决你的问题,请参考以下文章
Dockerized Celery 部署无需强制 KILL 工作人员(ECS | Beanstalk 多容器)
如何集成 AWS + ELB + AutoScale + Docker + Spring Cloud
如何为 AutoScale 实例使用 AWS 负载均衡器代理协议?
具有 Auto Scaling 与弹性容器服务 (ECS) 的 AWS EC2 - Docker
Autoscale ProvisionedConcurrentExecutions AWS Lambda DependsOn 值 null