【问题标题】:Can celery wait until enough resource (RAM) is available?芹菜可以等到有足够的资源(RAM)可用吗?
【发布时间】:2022-01-27 17:40:29
【问题描述】:

我有一个程序对大图像进行大量计算,显然它只能处理系统 RAM 允许的这么多请求。

我使用 Celery+Redis 对这些长任务进行排队,想知道是否有任何方法可以指示 Celery 在开始新任务之前先检查 RAM 可用性(但仍然让它们排队)?某种类型的锁会在 RAM 被完成的任务释放后打开?

我会很高兴看到任何建议或方向。

【问题讨论】:

    标签: python redis parallel-processing celery task-queue


    【解决方案1】:

    这可以使用celery inspect解决

    检索集群状态和整体内存占用。

    结合retry or ack late

    想法

    任务启动时,可以查询集群(或外部服务)获取所有内存占用信息:

    # example
    from celery import Celery
    app = Celery(...)
    app.control.inspect().active()
    

    它为每个可用的工作人员返回大量信息。

    之后,您应该应用某种基于内存的规则并继续计算或决定后处理:

    # example
    @celery.task(bind=True)
    def task(self, *args, **kwargs):
        if is_there_enought_memory():
            do_stuff()
        else:
            time.sleep(...)
            self.retry(...)
    

    当不满足最低要求时,任务会等待一定的时间,然后自行重新调度任务。

    【讨论】:

    • 感谢您的回复。使用您的解决方案,似乎当从一项任务中释放内存时,队列中的多个任务将开始处理,尽管资源只够一个。那是对的吗?必须有某种类型的锁,这样只有 celery 才能确切知道要启动多少个任务。
    • 该任务将仅从一项任务中再次处理。它会再次检查内存可用性
    • 实际上会启动多个任务。在开始一项任务时,它所需的内存并不仅仅被完全预订。内存使用在任务执行期间发生变化,具体取决于正在计算的内容。示例:每个任务有 3 个步骤,最多需要 5GB(假设只有第 2 步需要 5GB)。 is_there_enought_memory() 将对多个任务返回 True 并将全部启动,但是在第 2 步中的每个任务都需要 5GB 并且程序将崩溃。
    • 如果内存占用是一个原子任务,并且cannon是可以估计的,所以在并发环境中这个canon是可以避免的。否则,如果您可以估计占用或进程可以中断,则似乎可以稍后使用 .retry() 恢复它。
    猜你喜欢
    • 1970-01-01
    • 2019-09-01
    • 2021-06-02
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 2021-04-20
    • 1970-01-01
    相关资源
    最近更新 更多