Node.js 集群 - 最佳工人数

Node.js cluster - optimal number of workers

我有 4 个内核和 运行 根据 this example 的代码:

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

var id = 0;
if (cluster.isWorker) {
    id = cluster.worker.id;
}

var iterations = 1000000000;
console.time('Function #' + id);
for (var i = 0; i < iterations; i++) {
    var test = 0;
}
console.timeEnd('Function #' + id);

if (cluster.isMaster) {
    // Fork workers.
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
}

用 4 个 fork(上面的代码),我得到了:

Function #0: 1698.801ms

Function #1: 3282.679ms

Function #4: 3290.384ms

Function #3: 3425.090ms

Function #2: 3424.922ms

用 3 个 fork,我得到了:

Function #0: 1695.155ms

Function #2: 1822.867ms

Function #3: 2444.156ms

Function #1: 2606.680ms

用 2 个 fork,我得到了:

Function #0: 1684.929ms

Function #1: 1682.897ms

Function #2: 1686.123ms

我不明白这些结果。 1 fork/core 不是 最佳 数字吗?在这里我看到4叉并不比2叉好。

我的猜测是您的硬件实际上只有 2 个 物理 核心。但是,由于 hyper-threading (HT),OS 会说存在 4 个(逻辑)核心。

您代码中的工作人员保持一个(物理)核心完全被占用,这是 HT 无法很好处理的事情,因此保持所有 4 个逻辑核心忙碌时的性能会比仅保持时更差2 个物理核心忙。

我的硬件(四核,所以 4 个物理内核和 8 个逻辑内核)显示相同的模式:

  • 8 名工人:

    Function #5: 926ms
    Function #3: 916ms
    Function #1: 928ms
    Function #4: 895ms
    Function #7: 934ms
    Function #6: 905ms
    Function #8: 928ms
    Function #2: 928ms
    
  • 4 名工人:

    Function #3: 467ms
    Function #2: 467ms
    Function #1: 473ms
    Function #4: 472ms
    

就是说,如果您的工作人员受到 I/O 限制(大多数 Node 应用程序都是如此),则使工作人员数量等于硬件中逻辑核心数量的经验法则仍然有意义。 =13=]

如果您真的想执行繁重的阻塞计算,请为每个工作人员计算一个 物理 个核心。