如果有人想尝试: https://github.com/codependent/cluster-performanceNode.js的群集不显著提高性能
我测试的Node.js(v0.11.13 - Windows 7的)请求每秒限制用一个简单的应用程序。我已经使用Express 4实施了一项服务,该服务使用setTimeout回调来模拟I/O操作,例如数据库查询。
首先,我只用一个节点进程对它进行测试。对于第二次测试,我启动尽可能多的工人作为机器的CPU。
我使用loadtest以下参数测试服务:
loadtest -n 50000 -c 220 -k http://localhost:5000/operations/timeout/20
也就是说,50K总要求,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'));
});
- 只有一个节点处理
这些是结果:
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个请求,不错。
- Ñ工人(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;
UPDATE:
我终于接受了slebetman的答案,因为他是在这种情况下,正确的关于原因集群性能不会因多达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发行版,尽管您没有获得8x rps增量e,吞吐量几乎快了1.7倍。另一方面,如预期的那样,使用for循环迭代请求中指示的毫秒数(并因此阻塞线程),rps将与线程数成比例地增加。
Amdahl定律指出,即使在最乐观的情况下,您将无法获得8次改良效果,你要寻找的。可能有很多可能的答案,为什么你的结果没有多大改善。你的应用程序要么不能很好地扩展,要么运行的服务器并没有真正的8 CPU可用等。 – user2717954 2014-11-07 08:05:28
呵呵,我知道8x太乐观了。无论如何,有8个CPUS可以做一些工作,但实际上它应该改善rps,但它甚至不会使性能提高一倍。关于“你的应用程序不缩放”,以及你可以看到代码非常简单:带setTimeout()的路线,它怎么会不会缩放... – codependent 2014-11-07 12:04:18