我有一个工作,扫描网络文件系统(可以是远程的),拉取许多文件,对它们运行计算并将结果(每个文件)推送到数据库中。我正在将其移至芹菜,以便可以扩大规模。文件的数量可能会变得非常庞大(1M +)。
我不确定要采取什么设计方法,特别是:
统一的"end2end"任务
任务获取批处理(N 个文件的列表),拉取它们,计算并上传结果。
(使用批处理而不是单个文件是为了优化与远程文件系统和数据库的连接,尽管此时它是纯粹的启发式方法)
显然,一个任务会花费很大一部分时间等待 I/O,因此我们需要处理多个工作进程(远远超过 # 个 CPU),以便我有足够的任务同时运行(计算)。
优点:设计简单,编码和控制更容易。
缺点:可能需要在每次安装时单独调整进程池大小,因为它取决于环境(网络、计算机等)
拆分为专用的较小任务
下载、计算、上传(再次批量)。
这个选项直观地吸引人,但我实际上并没有看到优势。
我很乐意获得一些有关并发设计教程的参考,以及设计建议。
与每个文件的计算相比,扫描网络文件系统需要多长时间?
远程文件系统的层次结构是什么样的?文件是否均匀分布?您如何利用这一点来发挥自己的优势?
我会遵循这样的过程: 1. 在一个进程中,列出根远程目标文件夹的前两个级别。 2. 对于每个发现的文件夹,启动一个单独的芹菜进程,进一步列出这些文件夹的内容。您可能还希望保存发现文件的位置,以防万一出现问题。 3. 列出远程文件系统的内容以及列出文件终止的所有 celery 进程后,您可以进入处理模式。 4. 您可能希望列出包含 2 个进程的文件,并使用其余内核开始执行每个文件的工作。
注意:在用python做所有事情之前,我还会研究像xargs和find这样的bash工具如何在远程文件发现中协同工作。Xargs 允许您启动多个 C 进程,这些进程可以执行您想要的操作。这可能是进行远程文件发现,然后将所有内容通过管道传输到python代码的最有效方法。
您可以编写一个简单的 python 脚本,该脚本在k*cpu_count
线程上运行,只是为了连接到远程服务器并在没有芹菜的情况下获取文件。
就个人而言,我发现 4 到 7 之间的 k 值在 IO 绑定任务的 CPU 利用率方面提供了更好的结果。根据生成的文件数或要使用的速率,可以使用适当数量的线程。
或者,如果您的任务是 IO 绑定的,则可以将芹菜 + gevent 或芹菜与线程一起使用。
对于计算和更新数据库,您可以使用芹菜,以便您可以根据需要动态扩展。如果一次需要数据库连接的任务太多,则应为工作线程使用数据库连接池。