Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Node.js写入磁盘的速度会随着时间的推移而变慢_Javascript_Node.js_Io_Disk_File Writing - Fatal编程技术网

Javascript 使用Node.js写入磁盘的速度会随着时间的推移而变慢

Javascript 使用Node.js写入磁盘的速度会随着时间的推移而变慢,javascript,node.js,io,disk,file-writing,Javascript,Node.js,Io,Disk,File Writing,我正在尝试使用Node.js将大文件(500 MB)写入磁盘。我发现,虽然前几个文件在几秒钟内(通常是3到5秒钟)就被写入,但从第10个文件开始,速度往往会变慢(而且不会恢复) 该设置由一台服务器组成,该服务器通过TCP/IP套接字接受文件并将其通过管道传输到磁盘: var fs = require('fs'), net = require('net'), path = require('path'); var counter = 0; net.createServer(fu

我正在尝试使用Node.js将大文件(500 MB)写入磁盘。我发现,虽然前几个文件在几秒钟内(通常是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 GB)运行相同的测试,那么大约需要一半的时间,直到写入速度变慢

更新

我已将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);
现在这个问题已经解决了,所以很明显,它与在一行中写入多个文件有关。至少我看不到我在哪里同时写多个文件(是吗?),所以我想不出发生这种情况的原因。特别是
sleep5
的使用应该确保操作系统已经将所有内容写入磁盘

更新2

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


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

我不久前也遇到过类似的问题。并发I/O操作的数量最多,因此节点将在同一时间开始写入尽可能多的文件,其余文件将排队等待,直到有一个插槽空闲

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

以上只是一个示例,但它显示了原理,在这种情况下,编写4个文件所需的时间是只编写3个文件所需时间的两倍。

您能在没有node.js的情况下对其进行测试吗?你很有可能观察到同样的模式。OS的construct castles为了抽象HDD I/O的痛苦,涉及到很多因素,让我们确保它实际上是Node.js,而不是OS、缓存或其他任何东西。这里有一些如何用NC替换节点的示例:您是否100%确定没有泄漏资源?而且,所有文件句柄都被关闭?@jfriend00如果句柄保持打开状态,那么一旦操作系统没有剩余插槽,它就会完全停止写入文件,某些类型的泄漏可能会导致内存消耗过多,从而导致某种交换或内存波动。我提到文件句柄是因为我并不完全清楚node.js示例中的所有内容是如何正确关闭的。我非常确定没有泄漏资源,但我不能保证这一点。换句话说:可能有泄漏的东西,但至少我没有看到任何明显的地方会发生这种情况<代码>管道应该很干净,对于我使用过一次的任何其他东西.Hmmm,我不太确定这是否有帮助,因为我是按顺序而不是并行发送输入文件的。或者我在构建测试设置的过程中遗漏了什么?也不确定;)有一件事我很有信心,那就是这很可能不是Node.js的问题,您的代码对我来说很好。您是否尝试过使用评论中建议的netcat来验证“操作系统问题”理论?是的,我尝试过。不幸的是,没有对这一点进行任何补充说明:-()显然在0.11之前,某种错误在完成事件后使可写流“徘徊”,这可能与此有关,也可能与此无关。感谢您的提示:-)