【问题标题】:100 docker containers vs 100 small machines100 个 docker 容器 vs 100 个小型机器
【发布时间】:2016-05-22 14:24:20
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 是否存在可变负载,您可以在其中利用自动缩放微实例来根据负载需求进行扩展/缩减?如果是这样,您可能会获得节省成本的优势。
  • 它每天运行 1-2 小时。所以最小大小为 0。如果我们使用 100 个实例,我们可以在使用后完全关闭它们,如果我们只使用 1 个实例,我们也可以只关闭单个实例。所以成本不是问题。这个问题更注重性能而不是成本节约。
  • 您的选择实际上取决于您的应用程序保证在任何给定时间(例如每小时)服务的最小并发用户数。在节省成本方面,为不可预测的工作负载运行 t2.micro 按需实例比为 Docker 容器运行 c4.8xlarge 实例要好。
  • 并发也会被封顶100。节省成本的部分也是次要的。主要问题是哪一个会提供更好的性能。
  • 与在主机上相比,通过 docker 运行进程几乎没有 CPU 开销。

标签: linux amazon-ec2 concurrency parallel-processing docker


【解决方案1】:

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


也就是说,让我告诉你我在分析这种情况时会考虑什么。

  • docker 开销应该是绝对最小的。 “docker”工具本身并没有做任何事情——它只是使用常规的 Linux 内核功能为您的应用程序创建一个隔离的环境。

  • 操作系统启动后,会消耗一些内存,没错。但是操作系统本身的 CPU 消耗应该可以忽略不计(即使对于非常小的实例)。既然您提到您内存没有任何问题,我们似乎可以假设您同事提到的这种“操作系统开销”也可能可以忽略不计。

  • 如果您认为路由“有很多非常小的实例”,您还可以考虑使用最近发布的 t2.nano 实例类型。您需要测试它是否有足够的资源来实际运行您的应用程序。

  • 如果您考虑路由“一个非常大的实例”,您还应该考虑c4.8xl 实例。这应该比 c3.8xl 为您提供更多的 CPU 能力。

  • 成本分析(us-east-1 的价格):

    • 1x c3.8xlarge:1.68 美元/小时
    • 1x c4.8xlarge:1.675 美元/小时(与 c3.8xl 大致相同)
    • 100x t2.micro:1.30 $/h(即 100x 0.013$/h = 1.30$/h)
    • 100x 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:vCPU 的 100x 10% ~= "10 vCPU" 聚合
    • 100x t2.nano:vCPU 的 100x 5% ~= "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)
    • 100x t2.nano: 0.13 $ / (vCPU-h)

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

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

您可能还需要考虑网络利用率。应用程序网络密集吗?是延迟要求,带宽要求,还是每秒数据包数量?

  • 较小的实例具有较少的可用网络性能,较大的实例具有更多。但是每个较小实例的网络将由一个应用程序使用,而较大实例的强大网络将在所有容器之间共享。 8xl 实例带有 10Gbps 网卡。与此相比,t2 实例的网络性能非常低。

现在,弹性呢?这些工作的时间敏感性如何? “不及时完成它们的成本”是多少?您可能还需要考虑一些故障模式:

  • 如果“一个实例死亡”会发生什么?在 1x c3.8xl 或 1x c4.8xl 的情况下,您的整个机队将停机,您的工人将停止工作。他们能“康复”吗?他们是否需要“重新开始”他们的工作?在“很多小实例”的情况下,“单个实例死亡”的影响可能要小得多。

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

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

您还可以考虑 Spot Block,在其中说明您希望运行实例的小时数,您通常会比按需支付 30% - 45% 的费用,而且没有在您指定的时间段内被“出价”的风险。在此期限之后,您的实例将被终止。

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


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

也许是上述许多绩效指标的组合?他们将如何结合?总有一个权衡...

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

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

测试愉快!

【讨论】:

  • 好吧,我刚刚注意到您在问题中确实提到了 c4.8xl!出于某种原因,我以为我见过 c3.8xl。很抱歉造成混乱!
  • 综合分析!对 Amazon Web Services 的高级技术培训专家的期望不能少:)
  • 但问题更多的是针对性能而不是节省成本。如果 100 个容器在一个实例中,它们不会都在争夺 CPU 吗?
  • 我的意思是性能是哪种设置可以更快地完成所需的工作。可能我必须在我的问题中写下更多信息。
  • @Rowanto 关键是没有其他人可以回答对于您的应用程序和工作负载来说哪个更快,您需要对其进行测试。是的,对于 c4.8xl 上的 CPU 绑定任务,100 个进程的效率可能低于 36 个。另一方面,它可能会提高利用率。这取决于您正在运行的应用程序和工作负载。测试一下看看! =)
【解决方案2】:

仅基于 EC2 实例 CPU

  • 100 t2.micro 的 CPU 能力不到 c4.8xl 的 1/3
  • 100 个t2.small 少于 2/3
  • 50 t2.large 可能正在接近。

c4.8xl 很可能会快很多,但没有人可以权威地这么说。作为Bruno starts with,您需要通过您的应用程序在两种实例类型上运行您的工作负载才能看到。有 1000 个变量可能会影响结果。没有直接的理由不能在 linux 主机上运行 100 个容器/进程,它一直在做多核、多进程很长一段时间。可能有一些简单的系统限制需要随时调整(ulimit -asysctl -a)。另一方面,您的应用程序中的某些内容在此设置中可能表现得非常糟糕。

当您在单实例和多实例设置中运行容器时,几乎可以抵消任何 Docker 开销。您在这方面可以改进的任何事情都将有助于限制您在共享主机上遇到的问题。 IBM 发布了一份出色的报告 An Updated Performance Comparison of Virtual Machines and Linux Containers,详细介绍了 Docker 开销。

  • CPU/内存的容器开销可以忽略不计。
  • NAT 网络包含一些开销,因此请使用net=host
  • AUFS 磁盘会产生开销。对于任何需要密集写入的内容,将您的主机 EBS/SSD 直接安装到容器中。

与许多 Docker 容器的一大区别是 VM 进程调度程序上的工作负载将完全不同。运行更多容器时不一定会变得更糟,但您正在进入“测试较少”的领域。您较少依赖在硬件上运行的 Xen 虚拟机管理程序,而更多地依赖在 VM 内运行的 linux 内核进行调度,它们使用两种完全不同的算法。同样,Linux 能够运行许多进程并处理争用,但您只能通过测试为您的应用程序找到答案。

因此,完全猜测,不以任何方式考虑您的应用程序,纯粹基于一般机器规格和 CPU 繁重的工作负载。

  • c4.8xl 应该比 t2.nanot2.micro 设置更快。
  • t2.smalls 可能会接近。
  • 50 x t2.larges 与 2 个容器可能相当。
  • 100 x m3.mediums 会闪电战。
  • 3 x c4.8xl 将为您提供专用于应用程序每个进程/线程的最快处理器超线程。

tl;dr 全部测试。使用最快。

【讨论】:

  • 我的问题更多地针对测试较少的领域。运行 100 个虚拟机是否比运行 100 个容器更糟糕?我想我的问题很糟糕。
  • 这样还不错,只是其他人很难回答,因为您的应用程序和您的工作量起着很大的作用。没有直接原因不能在 linux 主机上运行 100 个容器/进程,它一直在做多进程多核。可能有一些简单的系统限制需要随时调整。
【解决方案3】:

一般情况下,我会使用 docker。仅仅是因为添加/更改/删除节点和进行负载平衡更容易和更快。我在这里假设您不需要正好 100 个节点,而是需要不断变化的节点数。

设置起来也快得多。有一个叫做 docker swarm https://docs.docker.com/swarm/overview/ 的东西,我相信它值得研究。此外,如果您不能将 100 或 1000 或 10000 个容器放在一台物理机(甚至是 VM?)上,您还可以使用覆盖网络 https://docs.docker.com/engine/userguide/networking/dockernetworks/#an-overlay-network

分发它

编辑:在重新阅读问题后,您似乎想要一个更多性能方面的答案。没有测试真的很难说(如果不是不可能的话)。对于性能,总是有一些警告和您无法想到的事情(仅仅因为是人类:))。 再次设置 100 或 3 或 999999 台机器比设置相同数量的 docker 容器要多得多。我知道容器/图像术语仍然混淆,所以澄清一下 - 您将创建一个 docker 图像,这是一些工作,然后在 N 个实例(它们是容器)中运行它。如果我错了,请有人纠正我的术语问题 - 这是我经常与同事讨论的问题:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    相关资源
    最近更新 更多