Celery 正确的任务组链

时间:2021-04-24 15:07:50

标签: python python-3.x celery

我有一个字符串列表,它们是文件名:

chunks_list = [["file_1", "file_2"], ["file_3", "file_4", "file_5"], ...]

我需要在 celery 任务中处理这些文件,所以我有一个任务:

@celery_app.task
def process_file_task(filename):
    # do some staff with file 
    # (e.g. produce data to Kafka)

我需要并行运行内部文件列表。并且外部列表应该是连续的

接下来的处理方式应该是:

worker1: file_1
worker2: file_2

第一组结束后开始下一组:

worker1: file_3
worker2: file_4
worker3: file_5

我尝试以这种方式运行我的任务:

sequence_tasks = []
for chunks in chunks_list:
    sequence_tasks.append(
        group([process_file_task.si(filename) for filename in chunks])
    )

tasks_chain = chain(
    tasks_group for tasks_group in sequence_tasks
)()
tasks_chain.get()

问题是我可能有数千个文件。而且这种运行任务的方式消耗了我所有的空闲内存,即使只有数百个。 请告诉我如何以正确的方式设计我的工作流程,以免内存不足。

1 个答案:

答案 0 :(得分:0)

你没有提到设置细节:

  • 您的工作人员在哪里运行?码头工人? (k8s/ecs/..) ec2?
  • 工人concurrency是什么?
  • 每个文件的任务(在同一组内)都必须在单独的工作器上运行吗?

总有一个大写 - 您拥有多少工人的限制。 假设您有 10 个工作人员,每个工作人员在一个组中并发 1 和 1,000 个任务。它们将几乎并行运行(因为您没有 1,000 名工人,只有 10 名),但这很好。 Celery 将确保在完成所有前 1,000 个任务之前,不会启动第二组中的任何任务。如果运行每个任务所需的时间相等,则每个工作人员将处理 100 个任务,然后将移动到下一个块。如果花费的时间不同,Celery 会通过将下一个任务分配给下一个空闲工人来进行优化。

换句话说,您知道设置是什么(假设具有 16GB 和 8 个内核的 EC2 实例)。您还知道(我希望)单个任务可以占用的最大内存大小是多少。如果一个普通任务需要 1GB RAM,您最多可以运行 16 个并行度为 1 的任务或 6 个并行度为 2 的任务等)

相关问题