Nodejs搭建静态文件[缓存]服务器与Apache性能比较
Nodejs搭建静态文件[缓存]服务器与Apache性能比较
疑惑?!node.js搭建静态文件[缓存]服务器与Apache性能比较
关于始终访问一个文件的时候,并不是每次都从磁盘中读取的问题,希望大家推荐一个随机访问的性能测试评估工具:)
这里的性能测试工具是Apache自带的ab工具
ab -c 50 -n 10000 127.0.0.1:8080/a.jpg
Apache是默认配置,Node代码见文章末尾
50线程同时发送10000个请求,80%的请求响应时间为:
Apache 176ms
Node 145ms
Node+cache 131ms
Node+Redis 210ms
Apache的响应速度作为参考! Node+cache速度最快,是可以理解的。因为从磁盘读取要比直接从内存读取速度慢。 疑惑是:为什么Node+Redis要比纯Node速度慢呢?并且是最慢!?
详细数据
Apache
Server Software: Apache/2.0.65
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 32.269846 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1922230000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 309.89 [#/sec] (mean)
Time per request: 161.349 [ms] (mean)
Time per request: 3.227 [ms] (mean, across all concurrent requests)
Transfer rate: 58171.24 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.8 1 10
Processing: 122 159 27.6 153 290
Waiting: 30 58 15.8 57 137
Total: 123 160 27.7 153 290
WARNING: The median and mean for the initial connection time are not within a no
rmal deviation
These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
50% 153
66% 163
75% 171
80% 176
90% 196
95% 216
98% 246
99% 267
100% 290 (longest request)
Node
Server Software: Node_v0.10.25
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 25.898481 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1920940000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 386.12 [#/sec] (mean)
Time per request: 129.492 [ms] (mean)
Time per request: 2.590 [ms] (mean, across all concurrent requests)
Transfer rate: 72433.47 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.0 1 15
Processing: 26 127 32.2 117 355
Waiting: 2 15 14.1 11 150
Total: 27 128 32.4 118 356
Percentage of the requests served within a certain time (ms)
50% 118
66% 128
75% 137
80% 145
90% 172
95% 192
98% 222
99% 253
100% 356 (longest request)
Node+cache
Server Software: Node_v0.10.25
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 24.616408 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1920940000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 406.23 [#/sec] (mean)
Time per request: 123.082 [ms] (mean)
Time per request: 2.462 [ms] (mean, across all concurrent requests)
Transfer rate: 76205.96 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.0 1 12
Processing: 32 121 27.4 115 244
Waiting: 1 8 6.0 7 95
Total: 33 122 27.6 116 252
Percentage of the requests served within a certain time (ms)
50% 116
66% 122
75% 127
80% 131
90% 153
95% 190
98% 215
99% 226
100% 252 (longest request)
Node+Redis
Server Software: Node_v0.10.25
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 34.663983 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1920940000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 288.48 [#/sec] (mean)
Time per request: 173.320 [ms] (mean)
Time per request: 3.466 [ms] (mean, across all concurrent requests)
Transfer rate: 54117.18 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.5 1 27
Processing: 34 170 46.8 163 379
Waiting: 4 62 60.6 34 271
Total: 35 171 46.8 164 380
Percentage of the requests served within a certain time (ms)
50% 164
66% 187
75% 202
80% 210
90% 233
95% 249
98% 276
99% 317
100% 380 (longest request)
Node.js代码
var http = require('http'),
fs = require('fs');
var redis = require("redis"),
client = redis.createClient(6379, '127.0.0.1', {/*parser: 'javascript', */return_buffers: true});
server = http.createServer(function(req, res) {
res.setHeader("Server", "Node_v0.10.25");
var realPath = './assets/a.jpg',
contentType = 'image/jpeg';
res.writeHead(200, {'Content-Type' : contentType});
/* Node start */
// var raw = fs.createReadStream(realPath);
// raw.pipe(res);
/* Node end */
/* Node+cache start */
// if(undefined === server.cache[realPath]) {
// fs.readFile(realPath, function(err, data) {
// res.end(data);
// server.cache[realPath] = data;
// });
// } else {
// res.end(server.cache[realPath]);
// }
/* Node+cache end */
/* Node+Redis start */
client.get(realPath, function(err, data) {
if(null != data) {
res.end(data);
} else {
fs.readFile(realPath, function(err, data) {
res.end(data);
client.exists(realPath, function(err, is) {
if(0 == is) {
client.set(realPath, data, redis.print);
}
});
});
}
});
/* Node+Redis end */
});
server.cache = {};
server.listen(8080);
疑惑?!Node.js搭建静态文件[缓存]服务器与Apache性能比较
关于始终访问一个文件的时候,并不是每次都从磁盘中读取的问题
这里使用了Apache自带的ab
工具进行性能测试:
ab -c 50 -n 10000 127.0.0.1:8080/a.jpg
Apache是默认配置,而Node.js代码见文章末尾。
50线程同时发送10000个请求,80%的请求响应时间为:
环境 | 响应时间(ms) |
---|---|
Apache | 176ms |
Node | 145ms |
Node+cache | 131ms |
Node+Redis | 210ms |
Apache的响应速度作为参考!Node+cache速度最快,是可以理解的。因为从磁盘读取要比直接从内存读取速度慢。
疑惑是:为什么Node+Redis要比纯Node速度慢呢?并且是最慢!?
详细数据
Apache
Server Software: Apache/2.0.65
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 32.269846 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1922230000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 309.89 [#/sec] (mean)
Time per request: 161.349 [ms] (mean)
Time per request: 3.227 [ms] (mean, across all concurrent requests)
Transfer rate: 58171.24 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.8 1 10
Processing: 122 159 27.6 153 290
Waiting: 30 58 15.8 57 137
Total: 123 160 27.7 153 290
...
Node
Server Software: Node_v0.10.25
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 25.898481 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1920940000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 386.12 [#/sec] (mean)
Time per request: 129.492 [ms] (mean)
Time per request: 2.590 [ms] (mean, across all concurrent requests)
Transfer rate: 72433.47 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.0 1 15
Processing: 26 127 32.2 117 355
Waiting: 2 15 14.1 11 150
Total: 27 128 32.4 118 356
...
Node+cache
Server Software: Node_v0.10.25
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 24.616408 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1920940000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 406.23 [#/sec] (mean)
Time per request: 123.082 [ms] (mean)
Time per request: 2.462 [ms] (mean, across all concurrent requests)
Transfer rate: 76205.96 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.0 1 12
Processing: 32 121 27.4 115 244
Waiting: 1 8 6.0 7 95
Total: 33 122 27.6 116 252
...
Node+Redis
Server Software: Node_v0.10.25
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /a.jpg
Document Length: 191970 bytes
Concurrency Level: 50
Time taken for tests: 34.663983 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1920940000 bytes
HTML transferred: 1919700000 bytes
Requests per second: 288.48 [#/sec] (mean)
Time per request: 173.320 [ms] (mean)
Time per request: 3.466 [ms] (mean, across all concurrent requests)
Transfer rate: 54117.18 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 1.5 1 27
Processing: 34 170 46.8 163 379
Waiting: 4 62 60.6 34 271
Total: 35 171 46.8 164 380
...
Node.js代码
var http = require('http');
var fs = require('fs');
var redis = require("redis"),
client = redis.createClient(6379, '127.0.0.1', { return_buffers: true });
var server = http.createServer(function(req, res) {
res.setHeader("Server", "Node_v0.10.25");
var realPath = './assets/a.jpg';
var contentType = 'image/jpeg';
res.writeHead(200, { 'Content-Type': contentType });
// 使用缓存
if (undefined === server.cache[realPath]) {
fs.readFile(realPath, function(err, data) {
res.end(data);
server.cache[realPath] = data;
});
} else {
res.end(server.cache[realPath]);
}
// 使用Redis缓存
client.get(realPath, function(err, data) {
if (null !== data) {
res.end(data);
} else {
fs.readFile(realPath, function(err, data) {
res.end(data);
client.set(realPath, data, redis.print);
});
}
});
});
server.cache = {};
server.listen(8080);
分析
-
Node vs Apache: Node.js的表现优于Apache,这主要是因为Node.js采用事件驱动、非阻塞I/O模型,能够更好地处理并发请求。
-
Node+cache vs Node: 使用内存缓存可以显著提高性能,因为减少了磁盘I/O操作。
-
Node+Redis vs Node: 使用Redis缓存虽然理论上可以提高性能,但在实际测试中却表现不佳。原因可能是Redis的网络通信开销和序列化/反序列化的成本较高,导致整体性能下降。此外,Redis缓存的命中率可能不高,尤其是在测试环境中。
希望这些信息能帮助你更好地理解Node.js和Apache在静态文件服务器中的性能差异。
你认为无cache的apache和纯node都用到了系统本身的IO buffer cache. 用redis的多走了一道socket输出+接收.
个人认为这个测试,除了redis,别的都是在缓存中处理,不会每次读取物理设备 所以加了redis一个环节,应该就比其他的慢了。 哪个和缓存联系的最直接,哪个最快,应该是这个路子吧?
系统本身的IO buffer cache 是指操作系统吗?
“缓存” 是哪里的缓存?
解释为什么 Node+Redis
性能最差
在上述测试结果中,Node+Redis
的响应时间明显比纯 Node
和 Node+cache
要长。主要原因是 Redis 在每次请求时都需要进行网络通信,这引入了额外的延迟。
示例代码解析:
var http = require('http');
var fs = require('fs');
var redis = require("redis");
var client = redis.createClient(6379, '127.0.0.1', {return_buffers: true});
var server = http.createServer(function(req, res) {
var realPath = './assets/a.jpg';
var contentType = 'image/jpeg';
res.writeHead(200, {'Content-Type': contentType});
// 使用 Redis 进行缓存
client.get(realPath, function(err, data) {
if (data !== null) {
res.end(data);
} else {
fs.readFile(realPath, function(err, data) {
res.end(data);
client.set(realPath, data, redis.print); // 将文件内容存储到 Redis
});
}
});
});
server.listen(8080);
问题分析
- 网络延迟:每次从 Redis 获取数据时,需要通过网络进行一次请求,增加了额外的延迟。
- Redis 存储开销:每次写入 Redis 都会增加额外的 I/O 操作和处理时间。
- 内存使用:Redis 存储的额外开销可能会影响性能,尤其是当 Redis 实例本身也有其他操作时。
结论
虽然 Redis 可以提供高效率的缓存,但在这种场景下由于频繁的网络通信和额外的 I/O 操作,导致了性能下降。如果希望提高性能,可以考虑本地内存缓存(如 Node+cache
)或者优化 Redis 的使用方式,例如批量读写或使用更高效的序列化方法。