我们可以在docker中运行多进程程序吗?

2024-04-23 20:50:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些使用多进程的代码,如下所示:

import multiprocessing
from multiprocessing import Pool

pool = Pool(processes=100)
result = []

for job in job_list:        
    result.append( 
        pool.apply_async(
            handle_job, (job)
            )
        )
pool.close()
pool.join()

这个程序在非常大的数据集上进行大量计算。因此,我们需要多个进程来并行处理作业,以提高性能

有人告诉我,对于托管系统来说,一个docker容器只是一个进程。所以我想知道我的多进程将如何在Docker中处理

以下是我关注的问题:

  1. 由于容器只是一个进程,我的多进程代码会在进程中变成多线程吗

  2. 演出会下降吗?因为我使用多进程的原因是为了同时完成任务以获得更好的性能


Tags: 代码infromimportfor进程jobresult
2条回答

我怀疑大部分混淆来自于将容器看作轻量级VM。相反,可以将Linux容器看作是运行进程的一种方式,其中包含一些名称空间和cgroup的设置

其中一个名称空间是pid名称空间。当您配置它时,您会看到名称空间中的第一个进程是名称空间中的pid 1。从另一个pid名称空间中,您无法看到其他名称空间或主机名称空间。在主机上,在任何名称空间之外,您将看到所有进程,包括任何名称空间中的进程

当您分叉一个新进程时,您将继承相同的名称空间和cgroup,因此您将在pid名称空间中获得一个新的pid,从而允许您像任何其他Linux环境一样运行多个进程。在容器内部,您可以运行ps命令(假设它包含在映像中),并看到多个进程正在运行:

$ docker run -it  rm busybox /bin/sh
/ # sleep 30s &
/ # ps -ef
PID   USER     TIME  COMMAND
    1 root      0:00 /bin/sh
    7 root      0:00 sleep 30s
    8 root      0:00 ps -ef

建议只运行一个进程不是来自多线程应用程序,而是来自将容器视为轻量级VM的人。它们将产生多个相互之间没有硬依赖关系的应用程序,如web服务器、数据库和邮件服务器。完成此操作后,有两个关键问题:

  • 容器日志无法使用。它们要么被多个进程弄得乱七八糟,所有进程都写入同一个stdout/stderr。或者它们是空的,日志被写入到容器文件系统,在那里它们经常丢失
  • 错误处理是有问题的。如果邮件服务器出现错误,是否应关闭并重新启动数据库以尝试更正该问题?如果你不杀死整个容器,你怎么知道邮件服务器坏了

简言之,管理容器的设计假设每个容器有一个应用程序,如果您打破了这个假设,那么当工具不支持您的用例时,您可以保留这两个部分

请注意:

  • 一旦pid 1退出,您的容器将结束,而不管您的分叉进程是否仍在运行。这意味着所有进程都被终止并收获
  • 通常在Linux上,当父进程在不等待其子pid的情况下死亡时,一个僵尸进程最终会被作为pid 1运行的init进程捕获。此收获进程不通过pid命名空间边界,因此如果您分叉子进程,请确保容器中的pid 1正在等待这些子进程清理它们。此任务的常见pid 1进程是tini(init拼写向后)。甚至还有一个标志让docker为您运行这个( init

是的,请参阅有关主管的文件 https://docs.docker.com/engine/admin/using_supervisord/

您还可以使用守护程序工具 http://cr.yp.to/daemontools.html

或中六 http://skarnet.org/software/s6/

相关问题 更多 >