为啥多线程 python 程序在 ec2 微实例上运行缓慢?

Posted

技术标签:

【中文标题】为啥多线程 python 程序在 ec2 微实例上运行缓慢?【英文标题】:Why multi-threaded python program slow on ec2 micro-instance?为什么多线程 python 程序在 ec2 微实例上运行缓慢? 【发布时间】:2013-07-02 19:40:58 【问题描述】:

我正在开发 Online Judge 代码检查器。我的代码在 python 2.7 中使用多线程。我本地机器上的相同程序(i core 3 RAM 4GB)在 1 分 10 秒内评估了大约 1000 个提交。但是当我在 ec2 微型实例(大约 600 MB RAM)上运行它时,大约需要 40 分钟(随机数秒变慢)。要知道我把事情搞砸的原因。

    首先这是我的评估器的工作方式:

    我有一个主程序worker.py,它创建了多个线程 主线程从文件(暂时)拉取提交(一次 10 个)并将它们放入全局队列中 侧线程从队列中获取提交(一个提交仅由一个线程评估) 侧线程接受提交后,会将其发送到函数compile,该函数 将提交的可执行文件返回给该线程 然后线程将这个可执行文件发送给一个运行可执行文件的函数run (使用具有定义的内存和时间限制的沙箱)并将可执行文件的输出写入文件,然后检查它 针对标准输出 队列变空后,主线程再次拉取 10 个提交并将它们放入队列

    函数compilerun

    compile 函数和 run 函数将可执行文件和输出保存在文件中(分别)命名为 像<thread_Name>.exe<thread_Name>.txt 这样每个线程都有自己的文件 并且不存在覆盖问题。 仅当编译函数的状态为 OK(文件已编译)时,线程才会运行函数,否则会引发编译错误 那次提交

    现在我有疑问:

    ec2 上执行慢的问题是因为它拥有的资源还是由于 到python的多线程。在我的脚本中,线程访问全局变量 比如队列(我放了锁)和test.py(I dont put lock on it)在运行 函数用标准输出逐个字符检查输出(类似vimdiff), 和mysandbox.py(libsandbox the sandbox) 和其他一些全局变量。由于 python 的 GIL 导致工作缓慢。如果它 是这样,那为什么它在我的本地机器上运行得很快。 我也暂时提供相同的文件test.cpp(adds two numbers and prints result) 1000 次。所以当我故意在这个文件中出现编译错误并运行我的 main ec2 上的程序运行速度非常快。据此我推断编译和 我的程序的运行(编译和运行函数)主要时间,而不是线程 创建和管理。

我知道这是一个很大的问题,但任何帮助都非常感谢(否则我将不得不赌上我所有的名誉来继续赏金:))。

【问题讨论】:

【参考方案1】:

对于持续的计算任务,微型实例变得极其缓慢(根据设计)。

您将代码编写为多线程,以利用整个“机器”的 CPU 资源执行文件检索和编译等任务,这是提高性能的良好做法。

虽然这在您保证预置硬件资源的物理机或虚拟机上是有意义的,但由于 Amazon 分配资源的方式,它在微型实例上没有意义.

Per Amazon's documentation,微型实例仅针对短突发 CPU 操作而设计,因此如果您尝试使用占用 CPU 使用率的多个线程,则会遇到 Amazon 自身施加的巨大瓶颈:

如果应用程序消耗的 CPU 资源超过您的实例分配的 CPU 资源,我们会暂时限制该实例,使其以较低的 CPU 级别运行。如果您的实例继续使用其分配的所有资源,其性能将会下降。我们将增加限制其 CPU 级别的时间,从而增加允许实例再次爆发之前的时间。

查看我刚刚链接到的文档中的 CPU 使用率图表以获取更多详细信息。

为了证明这是问题所在,您可以简单地启动一个小实例并在其中运行您的裁判软件 - 您应该会体验到类似于您的台式机的显着改进。

TL;DR 当尝试在微型实例上使用持续 CPU 时,它可能会变得不如旧款 Palm Treo 强大。

【讨论】:

是的!升级到中等确实有很大的不同,谢谢:) 很高兴听到这个消息。如果您想节省一些钱,您可以使用小型而不是中型 - 仍然应该很快并且价格只有一半。

以上是关于为啥多线程 python 程序在 ec2 微实例上运行缓慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在python里推荐使用多进程而不是多线程

我的 python-flask 应用程序源存储在使用弹性 beantalk 部署的 ec2 实例上在哪里?

为啥所有 EC2 实例都在同一个可用区启动?

为啥我无法在对等互连后从另一个 VPC 中的 EC2 实例连接 AWS RDS 实例

Amazon EC2 上 Node.js 的 CPU 利用率

如果我的安全组在端口 22 上允许 TCP 并且没有网络访问控制列表,为啥我不能通过 SSH 连接到我的 EC2 实例?