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);

6 回复

疑惑?!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);

分析

  1. Node vs Apache: Node.js的表现优于Apache,这主要是因为Node.js采用事件驱动、非阻塞I/O模型,能够更好地处理并发请求。

  2. Node+cache vs Node: 使用内存缓存可以显著提高性能,因为减少了磁盘I/O操作。

  3. 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 的响应时间明显比纯 NodeNode+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);

问题分析

  1. 网络延迟:每次从 Redis 获取数据时,需要通过网络进行一次请求,增加了额外的延迟。
  2. Redis 存储开销:每次写入 Redis 都会增加额外的 I/O 操作和处理时间。
  3. 内存使用:Redis 存储的额外开销可能会影响性能,尤其是当 Redis 实例本身也有其他操作时。

结论

虽然 Redis 可以提供高效率的缓存,但在这种场景下由于频繁的网络通信和额外的 I/O 操作,导致了性能下降。如果希望提高性能,可以考虑本地内存缓存(如 Node+cache)或者优化 Redis 的使用方式,例如批量读写或使用更高效的序列化方法。

回到顶部