使用 EC2 时的实例与核心

数据挖掘 平行线 聚类 aws
2021-09-24 03:48:58

从事通常被称为“中等数据”项目的工作,我已经能够在 4 到 32 个内核的单个系统上并行化我的代码(主要用于 Python 中的建模和预测)。现在我正在考虑扩展到 EC2 上的集群(可能使用 StarCluster/IPython,但也对其他建议持开放态度),并且对如何协调在实例上的核心与集群上的实例之间分配工作感到困惑。

跨实例以及每个实例的内核并行化是否可行?如果是这样,任何人都可以快速概述运行多个具有少量内核的实例与运行具有多个内核的几个实例的优缺点吗?选择正确的实例与每个实例的核心比率是否有经验法则?

带宽和 RAM 在我的项目中是非常重要的问题,但很容易发现这些是瓶颈并重新调整。我想,在没有重复测试的情况下对实例的正确核心组合进行基准测试要困难得多,而且我的项目差异太大,以至于任何单一测试都无法适用于所有情况。在此先感谢,如果我只是未能正确地用谷歌搜索这个,请随时将我指向其他地方的正确答案!

3个回答

使用 IPython 时,您几乎不必担心它(以牺牲一些效率/更大的通信开销为代价)。StarCluster 中的并行 IPython 插件默认情况下会在每个节点上为每个物理内核启动一个引擎(我相信这是可配置的,但不确定在哪里)。您只需使用 DirectView api(map_sync、apply_sync、...)或 %px 魔术命令在所有引擎上运行您想要的任何内容。如果您已经在一台机器上并行使用 IPython,那么在集群上使用它也不例外。

解决您的一些具体问题:

“如何协调在实例上的核心与集群上的实例之间分配工作” - 每个核心(至少)有一个引擎;工作会自动分布在所有核心和所有实例中。

“跨实例并行化以及每个实例上的跨内核并行化是否可行?” - 是 :) 如果您正在运行的代码是令人尴尬的并行(在多个数据集上完全相同的算法),那么您几乎可以忽略特定引擎的运行位置。如果核心需要在引擎之间进行大量通信,那么您当然需要对其进行结构化,以便引擎主要与同一物理机器上的其他引擎进行通信;但我认为这种问题并不适合 IPython。

“如果是这样,任何人都可以快速概括一下运行多个每个内核很少的实例与运行几个内核多个实例的优缺点吗?是否有经验法则来选择每个实例的正确实例与内核的比率? " - 使用最大的 c3 实例来解决计算受限问题,使用最小的 c3 实例来解决内存带宽受限问题;对于消息传递绑定问题,也使用最大的实例,但尝试对问题进行分区,以便每个分区在一台物理机器上运行,并且大多数消息传递都在同一个分区内。在 N 个四倍 c3 实例上比在 2N 个双倍 c3 上运行明显慢的问题很少见(一个人为的例子可能是在大量图像上运行多个简单的过滤器,您遍历每个过滤器的所有图像而不是所有过滤器相同的图像)。

一般的经验法则是在您必须分发之前不要分发。拥有 N 个具有一定容量的服务器通常比 2N 个具有该容量一半的服务器更有效。更多的数据访问将是本地的,因此在内存中速度较快,而在网络上速度较慢。

在某一点上,扩大一台机器变得不经济,因为额外资源的成本比线性增加更多。然而,这一点仍然高得惊人。

但是,特别是在 Amazon 上,如果您使用的是现货市场实例,每种实例类型的经济性可能会有很大差异。默认定价或多或少意味着无论实例类型如何,相同数量的资源成本大致相同,这可能会有很大差异;大型实例可能比小型实例便宜,或者 N 个小型实例可能比一台具有同等资源的大型机器便宜得多。

这里的一个重要考虑因素是,当您从一台机器转移到多台机器时,计算范式可能会发生很大变化。例如,通信开销带来的权衡可能会迫使您采用数据并行范式来扩展。这意味着工具和算法的不同选择。例如,SGD 在内存和 Python 中看起来与在 MapReduce 上完全不同。因此,您必须在并行化之前考虑这一点。

您可以选择跨集群分布工作,即使单个节点和非分布式范式为您工作,以提高可靠性。如果单个节点发生故障,您将丢失所有计算;分布式计算可能会恢复并完成丢失的部分计算。

所有考虑相同的因素(成本、CPU 性能等),您可以选择可以将我的所有数据集保存在内存中并横向扩展的最小实例。那样

  • 您确保不会因网络通信而导致不必要的延迟,并且
  • 您倾向于最大化您的进程的整体可用内存带宽。

假设您正在运行某种交叉验证方案来优化模型的某些元参数,请为每个核心分配一个值以进行测试,并根据需要选择多个实例,以在您认为合适的几轮内覆盖所有参数空间。

如果您的数据不适合一个系统的内存,那么您当然需要跨实例分布。然后是平衡内存延迟(对许多实例更好)与网络延迟(对更少实例更好)的问题,但考虑到 EC2 的性质,我敢打赌,您通常更喜欢使用少数胖实例。