不同机器上的单个进程与单台机器上的多线程,核心等于单 CPU 机器的数量

Posted

技术标签:

【中文标题】不同机器上的单个进程与单台机器上的多线程,核心等于单 CPU 机器的数量【英文标题】:Single processes on separate machines vs multithreading on a single machine with cores equal to number of single CPU machines 【发布时间】:2020-04-17 08:43:43 【问题描述】:

让我们假设有一个创建图像缩略图的 Java 程序。所有云提供商都提供具有 1 到 N 个 vCPU 虚拟机节点 (VM) 的 VM。

在单个 1 个 vCPU 节点上运行多个单线程 JVM 进程与在多 vCPU 机器上运行一个多线程 JVM 进程(单个 vCPU 上的进程数相等)有什么优点和/或缺点到在单个 JVM 进程中运行的线程?

举个更准确的例子:

4 个 VM 节点每个都有一个 1-vCPU 并运行单线程 JVM 进程来处理图像(这可能是其他任何东西)

VS

1 个具有 4 个 vCPU 并运行多线程 JVM 进程的 VM 节点,每个进程有 4 个线程,每个线程执行与上述单线程进程完全相同的任务。

【问题讨论】:

听起来您是在比较集群计算与 SMP architecture,但不要忽视中间路径:NUMA architecture。跨度> 【参考方案1】:

有趣的问题。

首先,让我们假设各个线程不共享任何 Java 资源,即,并非所有线程都在某个锁上同步。它们是完全独立的。

其次,让我们假设您没有使用虚拟 CPU,而是使用 1 个 CPU 或 4 个 CPU 的实际专用服务器。

这两种方法将如何竞争资源?

4 x 1 CPU,1 个线程

每个节点都有自己的专用 IO 硬件,因此实质上是 4 倍的 IO 容量 每个节点只有一个进程使用自己的内存和自己的垃圾收集器 因为我们只有一个线程,所以几乎没有任何上下文切换

1 x 4 CPU,4 个线程

4 个线程共享 IO 硬件,这可能会导致意外事件(与其他解决方案相比),即 IO 等待时间 内存是共享的,所以如果垃圾收集器遇到 stop the world 事件(他们现在很少这样做),所有线程都会被阻塞。根据 GC,这可能是一个瓶颈 因为我们有四个线程,所以我们一直都有上下文切换。这对性能的影响程度取决于 JVM 将所有数据保留在 CPU 本地的能力,即将线程固定到 CPU。

现在使用虚拟 CPU,其中一些差异可能会消失。例如。 IO 容量可能相同,因为所有四个虚拟节点可能都在一台物理机器上,就像使用 4 个虚拟 CPU 的单节点场景一样。在 4 个 vCPU 方案中,垃圾收集器争用可能仍然较低。关于上下文切换,问题可能是,VM 之间的切换是否与线程之间的切换一样便宜。同样,将进程/线程固定到给定物理 CPU 的能力可能是决定因素。

总而言之,我认为您无法绕过基准测试。所以我的建议是尽可能多地了解你的基础设施(这样你就知道你在测量什么),然后进行一些实验。

此外,这也是您没有提出的问题,但运行这两种解决方案都会产生一定的成本。运行多线程解决方案时,管理开销/成本肯定会更低。另一方面,运行多个 VM 更加稳健,因为当一个 VM 死机时它不是致命的——你仍然有 3 个在运行。

【讨论】:

谢谢,确实是一个很好的答案!我会等待其他答案,尽管我认为这是最好的,但仍然如此。 酷。我其实也很好奇其他人的想法。

以上是关于不同机器上的单个进程与单台机器上的多线程,核心等于单 CPU 机器的数量的主要内容,如果未能解决你的问题,请参考以下文章

单核中的多线程与异步编程

java多线程 线程的基本概念

ZABBIX监控一台机器上的多tomcat实例落地经验步骤

对于大型多核机器上的数据密集型任务,多线程性能影响是啥? [关闭]

在多线程应用程序表单上使用while循环锁定c#阻塞单核机器上的所有线程

单线程机器上的异步方法