【问题标题】:Threadpool Python future in a celery job appears to be blocking芹菜作业中的 Threadpool Python 未来似乎正在阻塞
【发布时间】:2021-08-09 12:46:44
【问题描述】:

这是 python 3.9 和 Django 3.2,在 docker 中运行。

我正在尝试在芹菜作业中运行一个期货池,其中该池是一个线程池。 我允许50个工人,这绰绰有余。 Celery 在 docker 容器中运行。 期货是在循环中创建的。循环从速率受限的 API 中读取多个页面,并将数据写入表中。未来会调用一个 CPU 密集型进程来处理刚刚更新的数据。

第一次,它有效。 Future 被提交并且执行立即移到循环的顶部:Future 并发运行。

但在第一次迭代之后,我看到了我不理解的行为。使用带时间戳的日志消息,主循环的执行会暂停,直到未来完成,持续 8 到 15 秒的挂壁时间。 在未来任务结束时添加日志消息表明情况确实如此。一旦 future 结束,主循环就会重新开始。

线程池是在 celery 任务的顶部创建的。

    pool = ThreadPoolExecutor(max_workers=50)

未来提交并保存:

f = pool.submit(self.cpu_intensive_task, job_id=job_id,
                                location_filter=location)
list_of_futures.append(f)

然后下一个循环迭代开始。

稍后,我会这样做:

 wait(list_of_futures, timeout=60)

虽然行为看起来像是在等待未来完成,但这不是问题。

如果一个线程池的线程用完了,它的行为会是这样吗?提交总是立即成功。

【问题讨论】:

  • 您是否尝试过在 wait() 中使用 return_when=ALL_COMPLETED,以便它不会等到超时实际用完?
  • 主线程停止的问题发生在代码到达 wait() 之前。我对此毫不怀疑。无论我做什么,等待都无关紧要。如果我在提交之后还有另一个等待隐藏在循环的第一次迭代之后才被激活,那么我会有一个解释。但是,我会添加您推荐的内容。
  • 如果您可以编译您所做工作的净化版本,那么我想它会更容易理解。 :)
  • 是的,我会尝试做一个最小的例子。我怀疑这是由于与在 Celery 中运行的一些交互。最奇怪的是,它在第​​一个未来可以正常工作,但以后就不行了。
  • 在 Celery 之外运行时效果很好。

标签: python celery concurrent.futures


【解决方案1】:

当使用pool=gevent 运行 celery 时,ThreadPoolExecutor 似乎阻塞了。

使用pool=preforkpool=threads 有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多