因此,我们有一个 kubernetes 集群,运行一些带有 celery 工作线程的 pod。我们使用 python3.6 来运行这些工作程序,celery 版本是 3.1.2(我知道,真的很旧,我们正在努力升级它)。我们还设置了一些自动缩放机制来动态添加更多的 celery 工作人员。
问题如下。假设在任何给定时间我们都有 5 个工人。然后会出现大量任务,从而增加 Pod 的 CPU/RAM 使用率。这会触发一个自动缩放事件,比方说,添加两个 celery 工作单元。所以现在这两个新的 celery 工人承担了一些长时间运行的任务。在完成运行这些任务之前,kubernetes 会创建一个缩减事件,杀死这两个工作人员,并杀死那些长时间运行的任务。
此外,由于遗留原因,如果任务未完成,我们没有重试机制(并且我们现在无法实现)。
所以我的问题是,有没有办法告诉 kubernetes 等待 celery 工作线程运行完所有待处理的任务?我想解决方案必须包括某种方法来通知芹菜工作人员以使其停止接收新任务。现在我知道 Kubernetes 有一些脚本可以处理这种情况,但我不知道在这些脚本上写什么,因为我不知道如何让 celery Worker 停止接收任务。
任何想法?
我写了一个博客文章 https://blog.dy.engineering/hpa-for-celery-workers-6efd82444aee正是关于那个主题 - 看看吧。
当 Kubernetes 决定杀死一个 pod 时,它首先发送 SIGTERM 信号,以便您的应用程序有时间正常关闭,之后如果您的应用程序没有结束 - Kubernetes 将通过发送 SIGKILL 信号来杀死它。
SIGTERM 到 SIGKILL 之间的这个周期可以通过以下方式调整terminationGracePeriodSeconds
(更多关于它here https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution).
换句话说,如果最长的任务需要 5 分钟,请确保将此值设置为高于 300 秒。
如您所见,芹菜为您处理这些信号here https://docs.celeryq.dev/en/stable/userguide/workers.html#stopping-the-worker(我想这也与您的版本相关):
应使用 TERM 信号来完成关闭。
当启动关闭时,工作人员将完成当前的所有工作
在实际终止之前执行任务。如果这些任务是
重要的是,你应该等待它完成后再做任何事情
激烈的,比如发送 KILL 信号。
正如文档中所解释的,您可以设置acks_late=True
配置 https://docs.celeryq.dev/en/stable/reference/celery.app.task.html#celery.app.task.Task.acks_late因此,如果任务意外停止,它将再次运行。
我没有找到文档的另一件事(几乎可以肯定我在某个地方看到过它) - Celery 工作人员在收到 SIGTERM 后不会收到新任务 - 所以你应该安全地终止工作人员(可能需要设置worker_prefetch_multiplier = 1
以及)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)