javascript - 随着时间的推移,使用 Node.js 写入磁盘会变慢

标签 javascript node.js io disk file-writing

我正在尝试使用 Node.js 将大文件 (500 MByte) 写入磁盘。我发现虽然前几个文件是在几秒钟内写入的(通常是 3 到 5 秒),但从大约第 10 个文件开始,事情往往会变慢(并且不会恢复)。

设置包括一个服务器,该服务器通过 TCP/IP 套接字接受文件并将它们通过管道传输到磁盘:

var fs = require('fs'),
    net = require('net'),
    path = require('path');

var counter = 0;

net.createServer(function (socket) {
  console.time('received');
  console.time('written');

  counter++;

  var filename = path.join(__dirname, 'temp' + counter + '.tmp');
  var file = fs.createWriteStream(filename, { encoding: 'utf8' });

  socket.pipe(file);

  socket.once('end', function () {
    console.timeEnd('written');
  });

  file.once('finish', function () {
    console.timeEnd('received');
  });
}).listen(3000);

我按以下方式使用 nc 从终端发送数据:

$ while [ true ]; do `cat input.tmp | nc localhost 3000`; done

运行

$ time cat input.tmp > /dev/null

表明 cat 总是同时读取文件。如果我将 Node.js 脚本的输出路径替换为 /dev/null,写入也总是同时发生。

所以问题显然与实际写入磁盘有关。

我一开始以为可能是并发读写的问题,结果运行起来还是不行

$ while [ true ]; do `cat input.tmp | nc localhost 3000; sleep 5`; done

如果我使用更大的文件(两倍大,即 1 GByte)运行相同的测试,那么它需要大约一半的时间,直到写入速度变慢。

更新

我已经更改了我的 Node.js 应用程序,将所有内容写入一个单个文件,该文件被不断地附加……服务器现在看起来像这样:

var fs = require('fs'),
    net = require('net'),
    path = require('path');

var filename = path.join(__dirname, 'temp.tmp');
var file = fs.createWriteStream(filename, { encoding: 'utf8' });

net.createServer(function (socket) {
  console.time('received');
  console.time('written');

  socket.pipe(file, { end: false });

  socket.once('end', function () {
    console.timeEnd('written');
  });
}).listen(3000);

现在问题解决了,很明显它与连续写入多个文件有关。至少看不到我在哪里同时写入多个文件(是吗?),所以我想不出为什么会发生这种情况。特别是 sleep 5 的使用应该确保操作系统确实将所有内容写入磁盘。

更新 2

我最初使用 Node.js 0.10.32 进行测试。当我切换到 0.11.13 时,效果并没有完全消失,但需要 way 更多时间才能发生。在最初的设置中,问题出现在大约 10 个周期,对于 Node.js 0.11.13,它最早发生在第 30 个周期。

知道是什么导致了这种行为吗?

最佳答案

我前段时间遇到过类似的问题。存在最大可能的并发 I/O 操作,因此 Node 将开始同时写入尽可能多的文件,其余的将排队直到有空槽为止。

file 1 |-----------------------------------|
file 2  |-----------------------------------|
file 3   |-----------------------------------|
file 4                                      |-------------------------------------|

上面只是一个例子,但它说明了原理,在这种情况下写4个文件比只写3个文件要花两倍的时间。

关于javascript - 随着时间的推移,使用 Node.js 写入磁盘会变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26355300/

相关文章:

javascript - 使用 jquery 查找最后一个 html 元素的特殊属性

javascript - Flot 不适用于 node.js

javascript - $locationProvider html5mode 导致刷新时出现 "cannot GET"错误 - AngularJS Node 应用程序

java - 直接从字节数组播放声音 - Java

python - 将两个 float 写入常规 txt 的正确方法

linux - 从脚本中运行命令时的 Bash 进度条

javascript - Ajax成功函数

javascript - 如何使用 Javascript 逐渐更改属性值?例如。缓入缓出

javascript - 如何在 JavaScript 中向 ContextualWeb 图像搜索 API 发出 GET 请求?

node.js - 如何在 Windows 10 上构建 node-gyp?