javascript - 성능테스트 - typescript cluster



Node.js 클러스터가 성능을 크게 향상시키지 않음 (3)

I / O 작업은 Node.js가 설계되고 최적화 된 응용 프로그램의 일종입니다. I / O 작업 (및 setTimeout)은 기본적으로 하드웨어 (네트워크, 디스크, PCI 브리지, DMA 컨트롤러 등)가 허용하는 한 병렬로 실행됩니다.

일단 이것을 이해하면 단일 프로세스에서 많은 병렬 I / O 작업을 실행하는 것이 많은 프로세스 / 스레드에서 많은 병렬 I / O 작업을 실행하는 것과 대략 동일한 시간이 걸리는 이유를 쉽게 이해할 수 있습니다. 사실, 직접 아날로그는 많은 병렬 I / O 연산을 하나의 프로세스에서 실행하게 될 것이며, 많은 병렬 프로세스에서 단일 I / O 연산을 실행하는 것과 동일합니다.

클러스터링을 사용하면 여러 개의 CPU / 코어를 사용할 수 있습니다. 그러나 프로세스는 CPU주기를 사용하지 않습니다. 따라서 클러스터링은 이점을 거의 제공하지 않습니다 (있는 경우).

https://code.i-harness.com

누군가가 시도하고자하는 경우 : https://github.com/codependent/cluster-performance

간단한 응용 프로그램으로 초당 제한 Node.js (v0.11.13 - Windows 7) 요청을 테스트하고 있습니다. 필자는 setTimeout 콜백을 사용하여 DB 쿼리와 같은 I / O 연산을 시뮬레이트하는 Express 4로 서비스를 구현했습니다.

먼저 하나의 노드 프로세스로 테스트합니다. 두 번째 테스트에서는 시스템에있는 CPU만큼의 작업자를 시작합니다.

loadtest 를 사용하여 다음 매개 변수를 사용하여 서비스를 테스트하고 있습니다.

loadtest -n 50000 -c 220 -k http://localhost:5000/operations/timeout/20

즉 총 요청 수는 50,000 개이며 동시 클라이언트 수는 220 개입니다.

내 서비스는 마지막 url 매개 변수 (20 mseg)에 따라 제한 시간 (처리 시간의 지속 시간)을 설정합니다.

router.route('/timeout/:time')
.get(function(req, res) {
    setTimeout(function(){
        appLog.debug("Timeout completed %d", process.pid);
        res.json(200,{result:process.pid});
    },req.param('time'));
});    
  1. 하나의 노드 프로세스 만

결과는 다음과 같습니다.

INFO Max requests:        50000
INFO Concurrency level:   200
INFO Agent:               keepalive
INFO
INFO Completed requests:  50000
INFO Total errors:        0
INFO Total time:          19.326443741 s
INFO Requests per second: 2587
INFO Total time:          19.326443741 s
INFO
INFO Percentage of the requests served within a certain time
INFO   50%      75 ms
INFO   90%      92 ms
INFO   95%      100 ms
INFO   99%      117 ms
INFO  100%      238 ms (longest request)

초 당 2580 개의 요청, 나쁘지 않습니다.

  1. n 노동자 (n = numCPUs)

이 경우 라운드 로빈 스케줄링 정책을 사용하여 작업자간에로드를 균등하게 분배합니다. 지금부터는 8 개의 코어 처리 요청이 있었는데, 초당 요청 수에 상당한 향상 (8 배 빨라짐)이 예상되었지만 2905 rps로 증가했습니다 !!! (318 rps 더) 어떻게 설명 할 수 있니? 내가 뭔가 잘못하고 있는거야?

결과 :

Max requests:        50000
Concurrency level:   220
Agent:               keepalive

Completed requests:  50000
Total errors:        0
Total time:          17.209989764000003 s
Requests per second: 2905
Total time:          17.209989764000003 s

Percentage of the requests served within a certain time
  50%      69 ms
  90%      103 ms
  95%      112 ms
  99%      143 ms
 100%      284 ms (longest request)

내 클러스터 초기화 코드 :

#!/usr/bin/env node
var nconf = require('../lib/config');
var app = require('express')();
var debug = require('debug')('mma-nodevents');
var http = require("http")
var appConfigurer = require('../app');
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

if('v0.11.13'.localeCompare(process.version)>=0){
    cluster.schedulingPolicy = cluster.SCHED_RR;
}

if (cluster.isMaster) {
    // Fork workers.
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
    cluster.on('exit', function(worker, code, signal) {
        console.log('worker ' + worker.process.pid + ' died');
        cluster.fork();
    });
}else{
    console.log("starting worker [%d]",process.pid);
    appConfigurer(app);
    var server = http.createServer(app);
    server.listen(nconf.get('port'), function(){
        debug('Express server listening on port ' + nconf.get('port'));
    });

}

module.exports = app;

최신 정보:

마지막으로 슬레벳 맨의 대답을 받아 들였습니다.이 경우 클러스터 성능이 최대 8 개의 프로세스로 크게 증가하지 않은 이유에 대해 그가 맞았 기 때문입니다. 그러나 흥미로운 사실을 지적하고 싶습니다 : 현재의 io.js 버전 (2.4.0) 에서는이 높은 I / O 작업 (setTimeout)에서도 실제로 향상되었습니다 :

loadtest -n 50000 -c 220 -k http://localhost:5000/operations/timeout/20

단일 스레드 :

Max requests:        50000
Concurrency level:   220
Agent:               keepalive

Completed requests:  50000
Total errors:        0
Total time:          13.391324847 s
Requests per second: 3734
Total time:          13.391324847 s

Percentage of the requests served within a certain time
  50%      57 ms
  90%      67 ms
  95%      74 ms
  99%      118 ms
 100%      230 ms (longest request)

8 코어 클러스터 :

Max requests:        50000
Concurrency level:   220
Agent:               keepalive

Completed requests:  50000
Total errors:        0
Total time:          8.253544166 s
Requests per second: 6058
Total time:          8.253544166 s

Percentage of the requests served within a certain time
  50%      35 ms
  90%      47 ms
  95%      52 ms
  99%      68 ms
 100%      178 ms (longest request)

따라서 현재의 io.js / node.js 릴리즈에서는 8 배속 증가가 없지만 1.7 배 빠릅니다.

반면에 예상대로 요청에 표시된 밀리 초 동안 반복되는 for 루프를 사용하면 스레드가 차단되므로 rps는 스레드 수에 비례하여 증가합니다.


간단한 계산 :

1000/20*220 = 11000   // theoretically max request per second

localhost에서 테스트합니다. 이것은 네트워크 시간이 작기 때문에 로그 출력이 블록이라고 생각합니다.

appLog.debug("Timeout completed %d", process.pid);

댓글을 달고 다시 시도하십시오.


cluster.SCHED_RR 사용하지 말고 cluster.SCHED+





cluster-computing