linux - 100 个 docker 容器与 100 台小型机器

标签 linux amazon-ec2 concurrency parallel-processing docker

所以我们有一个不是线程安全的应用程序。
它使用的一些库正在文件系统级别上进行锁定。不幸的是,它不能正常工作,如果有一些库的并发使用,它会崩溃并抛出错误。我们也无法切换这个库。要实现并发,哪个更好?在一台强大的机器上运行 100 个容器还是将其拆分为 100 台小型机器?

由于我们使用的是 Amazon,我在考虑 100 X t2.micro 实例,每个实例运行一个容器 VS 一台带有 100 个 docker 容器的 c4.8xlarge 机器。我们没有任何内存问题。这些任务受 CPU 限制。但它也没有那么重,一个 t2.micro 实例足以处理它,只要它一次只处理一个。

我和一位同事讨论了哪个更好。我更喜欢 100 个实例,因为我认为 Docker 隔离将是一个很大的开销。这就像你只有一个资源,但它被分成了 100 个需要使用该资源的人。另一方面,我的同事提出了一个我认为可能有道理的观点。创建 Linux 命名空间比启动整个操作系统更轻松。所以如果我们有 100 台机器,我们有 100 个操作系统,而对于一台大机器,我们只有 1 个操作系统。

问题是,我不知道哪个是正确的。有这方面知识的人可以解释一下哪个更好并给我一个具体的理由吗?

由于我意识到我刚刚问了一个不好的问题,因此我将尝试在此处添加更多信息。为了使问题更准确,我并不是在问在我的特定用例中哪个更好,或者哪个更便宜。这只是一种好奇心,在 CPU 方面哪个会表现得更好。想象一下,我们有一个非常大的计算问题,我们必须做 100 个。我们想并行化它们,但它们不是线程安全的。在 100 台小型机器或 1 台具有 100 个容器的强大机器上执行它们更好吗?哪一个会更快完成,为什么?

如果我们只有 1 台强大的机器,这 100 个容器会不会都在争夺资源并减慢整个过程?而如果是100台小机器,可能因为操作系统或其他因素,整体性能会更慢?无论如何,我对此没有任何经验。当然我可以试试这个,但最终,由于它不是理想的环境(有很多因素),所以结果无论如何都不具有权威性。我一直在寻找知道这两种事物在低级别如何工作并且可以争论哪种环境可以更快地完成任务的人的答案。

最佳答案

对您的问题唯一“适当”的答案是:您必须测试这两种选择并找出哪个更好。这样做的原因是:您正在运行一个非常具体的应用程序,具有非常具体的工作负载和非常具体的要求。任何未经实际测试的建议都是猜测。也许是“有根据的猜测”,但仅此而已。

也就是说,让我向您展示在对这种情况进行分析时我会考虑什么。

  • docker 开销应该绝对最小。工具“docker”本身并没有做任何事情——它只是使用常规的 Linux 内核功能为您的应用程序创建一个隔离的环境。
  • 操作系统启动后,它会消耗一些内存,真的。但是操作系统本身的 CPU 消耗应该可以忽略不计(即使对于非常小的实例)。由于您提到您的内存没有任何问题,因此我们似乎可以假设您的同事提到的这种“操作系统开销”也可能可以忽略不计。
  • 如果你考虑路由“很多非常小的实例”,你也可以考虑使用最近发布的 t2.nano实例类型 .您需要测试它是否有足够的资源来实际运行您的应用程序。
  • 如果您考虑路由“一个非常大的实例”,您还应该考虑 c4.8xl实例。这应该为您提供比 c3.8xl 多得多的 CPU 能力。
  • 成本分析(us-east-1 中的价格):
  • 1x c3.8xlarge:1.68 美元/小时
  • 1x c4.8xlarge:1.675 $/h(与 c3.8xl 大致相同)
  • 100x t2.micro:1.30 $/h(即 100x 0.013$/h = 1.30 $/h)
  • 100 倍 t2.nano:0.65 美元/小时。 (获胜者) (即 100x 0.0065$/h = 0.65$/h)
  • 现在让我们分析您在每个设置中拥有的资源量。我只关注 CPU 并忽略内存,因为您提到您的应用程序不占用内存:
  • 1x c3.8xlarge:32 个 vCPU
  • 1x c4.8xlarge:36 个 vCPU(每个 vCPU 通常比 c3.8xl 具有更好的性能;c4 的芯片是英特尔专门为 EC2 设计的) (获胜者)
  • 100x t2.micro:100x 10% 的 vCPU ~=“10 vCPU”聚合
  • 100x t2.nano:100x 5% 的 vCPU ~=“5 vCPU”聚合
  • 最后,让我们分析一下每个资源的成本
  • 1x c3.8xlarge:1.68$/h/32 vCPU = 0.0525 $/(vCPU-h)
  • 1x c4.8xlarge:0.0465 $/(vCPU-h) (获胜者)
  • 100x t2.micro: 0.13 $/(vCPU-h)
  • 100 倍 t2.nano:0.13 美元/(vCPU-h)

  • 如您所见,较大的实例通常提供更高的计算密度,而这通常更便宜。

    您还应该考虑这样一个事实,即 T2 实例是“突发的”,因为它们可以在一段时间内超出其基准性能(如上的 10% 和 5%),具体取决于它们拥有多少“CPU 积分”。但是,您应该知道,尽管它们以一些信用余额开始,但通常足以启动操作系统,而且仅此而已(如果您不将 CPU 超出基线,您会随着时间的推移积累更多的 CPU 信用) ,但似乎情况并非如此,因为我们正在优化性能......)。正如我们所见,“每个资源的成本”几乎是 8xl 实例的 3 倍,因此您获得的这个短暂爆发可能不会改变这个粗略估计。

    您可能还想考虑 网络利用率 .应用网络密集吗?是延迟要求还是带宽要求,还是每秒的数据包数量?
  • 较小的实例具有较少的可用网络性能,较大的实例具有更多的网络性能。但是每个较小实例的网络将由一个应用程序使用,而较大实例的强大网络将在所有容器之间共享。 8xl 实例带有 10Gbps 网卡。与此相比,t2 实例的网络性能非常低。

  • 现在, 怎么样?弹性 ?这些工作对时间有多敏感? “不及时完成它们的成本”是多少?您可能还需要考虑一些故障模式:
  • 如果“一个实例死亡”会发生什么?在 1x c3.8xl 或 1x c4.8xl 的情况下,您的整个车队将停机,您的 worker 将停止工作。他们能“康复”吗?他们需要“重新开始”他们的工作吗?在“很多小实例”的情况下,“一个实例死亡”的影响可能会小得多。

  • 为了减少“单个实例死亡”对您的工作负载的影响,并仍然从更高密度的计算(即大型 c3 或 c4 实例)中获得一些好处,您可以考虑其他选项,例如:2x c4.4xl 或 4x c4.2xl 等等。请注意,c4.8xl 的成本是 c4.4xl 的两倍,但它包含的 vCPU 数量多于两倍。所以上面的分析不会是“线性的”,你需要重新计算一些成本。

    假设您对“失败”的实例没有问题,并且您的应用程序可以以某种方式处理它——另一个需要考虑的有趣点是使用 竞价型实例 .使用 Spot 实例,您可以指定价格。如果“市场价格”(由报价 - 需求调节)低于您的出价,您将获得实例并只支付“市场价格”。如果价格波动高于您的出价,则您的实例将被终止。与 On Demand 相比,折扣高达 90% 的情况并不少见。截至目前,c3.8xl 在一个可用区中约为 0.28 美元/小时(比 On Demand 低 83%),而 c4.8xl 在一个可用区中大致相同(也低 83%)。 Spot 定价不适用于 t2 实例。

    您也可以考虑现货座 ,在其中您说要运行实例的小时数,您支付的费用通常比按需少 30% - 45%,并且在您指定的时间段内没有“出价”的风险。期限过后,您的实例将终止。

    最后,我会尝试调整我的服务器队列的大小,以便它们需要几乎“完整的小时数”(但不超过该数字)(除非我需要尽快完成执行)。也就是说,拥有一个能够在 50 分钟内完成工作的较小车队比能够在 10 分钟内完成工作的较大车队要好得多。原因是:您按小时付费,在小时开始时。此外,通常情况下,拥有一个可在 50 分钟内完成工作的大型车队比需要 1 小时 05 分钟的小型车队要好得多——同样,因为您是按小时付费的,在一小时开始时。

    最后,您提到您正在寻找“最佳性能”。你到底是什么意思?你的关键绩效指标是什么?您想进行优化以减少总时间吗?也许减少“每单位”/“每项工作”的时间?您是否正在努力降低成本?您是否想提高“能源效率”并减少碳足迹?或者可能优化所需的维护量?或者专注于简化以减少其他知识较少的同事在他们能够维护解决方案之前需要的准备时间?

    也许是上述许多性能指标的组合?他们将如何结合?总有一个取舍...

    如您所见,没有明显的赢家。至少不是没有关于您的应用程序和优化目标的更多具体信息。这就是为什么大多数情况下,任何类型的性能优化的最佳选择都是真正地对其进行测试。测试通常也很便宜:设置环境可能需要几个小时的工作,然后可能不到 2 美元/小时的测试。

    所以,这应该给你足够的信息来开始你的调查。

    测试愉快!

    关于linux - 100 个 docker 容器与 100 台小型机器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35345618/

    相关文章:

    java - 'synchronized'与ReentrantLock有何关系?

    linux - 如何组合shell命令

    c - 如何模拟内存 I/O 设备以在 Linux 上进行单元测试?

    php - 如何在 Amazon EC2 上配置 PHP + Apache?

    amazon-web-services - EC2 的 AWS 免费套餐限制

    java - 添加 JFrame 事件处理程序之前滞后?

    java - 如何将 cURL 放入 Java 中

    linux - 如果不存在,如何将文本行添加到文件

    python - IAM 凭证错误 404

    networking - 编写示例服务器应用程序 - forkIO 是不可避免的吗?