我有几个关于芹菜的问题。请帮我解决这个问题。
我们是否需要将项目代码放在每个 celery worker 中?如果是,如果我增加了工作人员的数量并且我正在更新我的代码,那么在所有工作人员实例中更新代码的最佳方法是什么(无需每次都手动将代码推送到每个实例)?
使用-Ofair芹菜工人作为参数禁用工人预取,即使已经设置PREFETCH_LIMIT=8 or so?
重要提示:rabbitmq 代理是将任务分配给工作人员还是工作人员从代理中提取任务?
在一个系统中拥有多个 celery worker(子进程与内核数量一样多)是否有意义?我看到很少有人在一个系统中运行多个 celery 工人。
补充上一个问题,两个场景的性能差异是什么:一个系统中的单个worker(8核)或两个worker(并发4)
请回答我的问题。提前致谢。
我们是否需要将项目代码放在每个 celery worker 中?如果是,如果我增加了工作人员的数量并且我正在更新我的代码,那么在所有工作人员实例中更新代码的最佳方法是什么(无需每次都手动将代码推送到每个实例)?
是的。celery worker 运行您的代码,因此它自然需要访问该代码。您如何使代码可访问完全取决于您。一些方法包括:
作为部署的一部分,代码更新和重新启动工作人员
如果您在 kubernetes pod 中运行您的 celery worker,这归结为构建一个新的 docker 镜像并将您的 worker 升级到新镜像。使用滚动更新可以实现零停机。
来自存储库的计划同步和工作程序通过广播重新启动
如果您在更传统的环境中运行您的 celery 工作人员,或者由于某种原因您不想重建整个映像,您可以使用一些对所有工作人员可用的中央文件系统,您可以在其中更新文件,例如按计划同步 git 存储库或通过某种触发器。重新启动所有 celery 工作人员很重要,以便他们重新加载代码。这可以通过远程控制来完成。
为每个任务动态加载代码
例如,在 omega|ml 中,我们提供 lambda 风格的无服务器执行任意 Python 脚本,这些脚本动态加载到工作进程中。为了避免模块加载和依赖问题,保留max-tasks-per-child=1和使用 prefork 池很重要。虽然这会增加一些开销,但我们发现这是一个易于管理的折衷(特别是我们运行机器学习任务,因此在每个任务之后加载脚本和重新启动工作程序的开销很小不是问题)
即使设置了 PREFETCH_LIMIT=8 左右,在 celery 工作器中使用 -Ofair 作为参数禁用工作器中的预取?
-O fair 阻止工作进程预取任务,除非有空闲进程。然而,我最近偶然发现了速率限制的一个怪癖。在实践中,我没有遇到过预取和速率限制的问题,但是与任何分布式系统一样,考虑执行的异步性质的影响是值得的(这不是 Celery 特有的,而是适用于所有此类系统) .
重要提示:rabbitmq 代理是将任务分配给工作人员还是工作人员从代理中提取任务?
Rabbitmq 不知道工作人员(也不知道 celery 支持的任何其他代理)——他们只是维护一个消息队列。也就是说,是工作人员从代理中提取任务。
可能会出现的一个问题是,如果我的工作人员在执行任务时崩溃会怎样。这有几个方面:worker和worker processes之间有区别。worker 是从代理开始消费任务的单个任务,它不执行任何任务代码。任务代码由工作进程之一执行。当使用 prefork 池(这是默认值)时,一个失败的工作进程会简单地重新启动,而不会影响整个工作进程或其他工作进程。
在一个系统中拥有多个 celery worker(子进程与内核数量一样多)是否有意义?我看到很少有人在一个系统中运行多个 celery 工人。
这取决于您需要运行的工作负载的规模和类型。一般来说,CPU 密集型任务应该在并发设置不超过内核数的 worker 上运行。如果您需要处理的任务多于核心数,请运行多个工作线程来横向扩展。请注意,如果您的 CPU 密集型任务一次使用多个内核(例如,在机器学习工作负载/数值处理中经常出现这种情况),则应该是每个任务使用的内核总数,而不是并发运行的任务总数告知您的决定。
补充上一个问题,两个场景的性能差异是什么:一个系统中的单个worker(8核)或两个worker(并发4)
一般很难说,最好运行一些测试。例如,如果 4 个并发运行的任务使用了单个节点上的所有内存,则添加另一个工作程序将无济于事。但是,如果您有两个队列,例如具有不同的到达率(例如一个用于低频但高优先级的执行,另一个用于高频但低优先级的执行),它们都可以在同一节点上同时运行,而无需担心 CPU 或内存,单个节点即可。
| 归档时间: |
|
| 查看次数: |
319 次 |
| 最近记录: |