我应该如何并行化cpu和网络密集型任务的混合(在Celery中)

时间:2017-06-21 13:33:29

标签: concurrency parallel-processing multiprocessing celery

我有一个扫描网络文件系统(可以是远程)的工作,拉取许多文件,对它们运行计算并将结果(每个文件)推送到数据库中。我正在将其转移到芹菜,以便它可以扩大规模。文件数量可能非常大(1M +)。

我不确定采取什么样的设计方法,具体来说:

统一“end2end”任务

任务获取批次(N个文件列表),拉取它们,计算并上传结果。

(使用批处理而不是单个文件是为了优化与远程文件系统和数据库的连接,尽管此时它是一种纯粹的启发式方法)

显然,任务会花费大部分时间等待I / O,因此我们需要使用多个工作进程(远远超过CPU的数量),以便我有足够的任务运行(计算) )同时。

亲:设计简单,编码和控制更容易 con:可能需要根据安装情况单独调整进程池大小,因为它取决于环境(网络,机器等)。

分成专用的小任务

下载,计算,上传(再次,批量) 这个选项很直观,但我实际上并没有看到它的优势。

我很高兴得到一些关于并发设计的教程以及设计建议的参考。

2 个答案:

答案 0 :(得分:2)

您可以编写一个简单的python脚本代替celery,该脚本在k*cpu_count个线程上运行,只是为了连接到远程服务器并获取没有芹菜的文件。

就个人而言,我发现在4到7之间的k值在IO绑定任务的CPU利用率方面给出了更好的结果。根据生成的文件数或您要使用的速率,您可以使用合适数量的线程。

或者,如果您的任务是IO绑定,您可以将celery + gevent或celery与线程一起使用。

对于计算和更新DB,您可以使用芹菜,以便您可以根据您的要求动态扩展。如果您一次需要数据库连接的任务太多,则应该为工作人员使用数据库连接池。

答案 1 :(得分:2)

与每个文件的计算相比,扫描网络文件系统需要多长时间?

远程文件系统的层次结构如何?文件是否均匀分布?你怎么能利用这个优势呢?

我会按照这样的流程: 1.在一个进程中,列出根远程目标文件夹的前两个级别。 2.对于每个发现的文件夹,启动一个单独的芹菜进程,进一步列出这些文件夹的内容。您可能还希望保存已发现文件的位置,以防万一出错。 3.列出远程文件系统的内容以及列出文件终止的所有芹菜进程后,您可以进入处理模式。 4.您可能希望列出包含2个进程的文件,并使用其余的核心开始执行每个文件的工作。

注意:在使用python进行所有操作之前,我还将研究像xargs这样的bash工具如何在远程文件发现中找到工作。 Xargs允许您启动多个C进程来执行您想要的操作。这可能是进行远程文件发现的最有效方法,然后将所有内容传递给python代码。