Falls jemand will versuchen: https://github.com/codependent/cluster-performanceNode.js Cluster nicht verbessert die Leistung erheblich
Ich teste Node.js (v0.11.13 - Windows 7) Anfrage pro Sekunde Grenzen mit einer einfachen Anwendung . Ich habe einen Service mit Express 4 implementiert, der eine E/A-Operation wie eine DB-Abfrage mit einem setTimeout-Callback simuliert.
Zuerst teste ich es mit nur einem Knoten-Prozess. Für den zweiten Test starte ich so viele Arbeiter wie die CPUs der Maschine hat.
ich loadtest bin mit dem Service mit den folgenden Parametern testen:
loadtest -n 50000 -c 220 -k http://localhost:5000/operations/timeout/20
Das heißt, 50k Gesamt Anfragen, 220 gleichzeitige Clients.
My Dienst setzt den timeout (die Dauer der Bearbeitungszeit) nach dem letzten URL-Parameter (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'));
});
- nur ein Knoten Prozess
These sind die Ergebnisse:
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 Anfragen pro Sekunde, nicht schlecht.
- n Arbeiter (n = NumCPUs)
In diesem Fall habe ich die Last gleichmäßig unter den Arbeitern mit der Politik Planung Round-Robin verteilen. Da es nun 8 Cores gibt, die Anfragen verarbeiten, erwartete ich eine signifikante Verbesserung (8 mal schneller?) In den Anfragen pro Sekunde, aber es stieg nur auf 2905 rps !!! (318 rps mehr) Wie können Sie das erklären? Mache ich etwas falsch?
Ergebnisse:
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)
Mein Cluster Initialisierungscode:
#!/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;
UPDATE:
ich habe endlich slebetman Antwort akzeptiert, da er recht über den Grund, warum in diesem Fall war Die Clusterleistung stieg mit bis zu 8 Prozessen nicht signifikant an. Ich möchte jedoch auf eine interessante Tatsache hinweisen: mit der aktuellen Version io.js (2.4.0), es hat sich wirklich auch für diese hohe I/O-Operation (SetTimeout) verbessert:
loadtest -n 50000 -c 220 -k http://localhost:5000/operations/timeout/20
Einfaden:
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 Kern Cluster:
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)
So ist es klar, dass mit den aktuellen io.js/node.js Releases, obwohl Sie nicht eine 8x rps erhöhen bekommen e, der Durchsatz ist fast 1,7 mal schneller.
Auf der anderen Seite, wie erwartet, die Verwendung einer For-Schleife für die in der Anfrage angegebene Anzahl von Millisekunden Iterieren (und damit den Thread blockieren), erhöht sich die RPS proportional zur Anzahl der Threads.
Amdahls Gesetz besagt, dass selbst im optimistischsten Szenario würden Sie nicht die 8-mal Verbesserung erhalten, die Sie suchen. Es gibt viele mögliche Antworten darauf, warum sich Ihre Ergebnisse nicht sehr verbessert haben. Ihre App skaliert entweder nicht gut oder der Server lief nicht wirklich 8 CPUs zur Verfügung usw. – user2717954
Hehe, ich wusste 8x war zu optimistisch. Mit 8 CPUSs, die für einige Arbeiten zur Verfügung stehen, sollte es tatsächlich die rps verbessern, während es die Leistung nicht einmal verdoppelt. Über "Ihre App skaliert nicht", nun können Sie sehen, der Code ist ziemlich einfach: eine Route mit einem SetTimeout(), wie kommt es würde nicht skalieren ... – codependent