NodeJS 可写流 writev 在 1 和 highWaterMark 块之间交替

Posted

技术标签:

【中文标题】NodeJS 可写流 writev 在 1 和 highWaterMark 块之间交替【英文标题】:NodeJS Writable streams writev alternating between 1 and highWaterMark chunks 【发布时间】:2021-07-29 18:39:18 【问题描述】:

所以我有一个生成数据的流和一个将它们写入数据库的流。写入数据库很慢。我使用writev函数一次写入一批3000块。

const generator = new DataGenerator(); // extends Readable
const dbWriter = new DBWriter( highWaterMark: 3000 ); // extends Writable, implements _writev method

pipeline(
  generator,
  dbWriter 
)

但是当我在 _writev 方法中记录块计数时,我得到以下输出:

1
2031
969
1
1635
1365
1
1728
1272
1
...

我知道第一行是 1。一个块来了,DB 开始写入。 2031 个区块同时出现。

然后 DB 开始写入 2031 个块,同时又有 969 个块进入,而不是 3000 个。然后在下一步中,再次只写入 1 个。就像接收到缓冲区的块只会在所有内容都写入时才会重置,而不是在 3000 缓冲区未满时重置。

我的期望:

1
2031
3000
3000
3000
...
3000
123

为什么?

【问题讨论】:

【参考方案1】:

好吧,因为没有保证您将获得3000 数据块,它确实告诉了您的可写流具有的内部缓冲区的限制。您可以接收任意数量的数据是可以的,因为读取流对您的缓冲区大小一无所知。 最好的问候。

【讨论】:

但是写969个数据块肯定要花更多的时间才能生成一个块,也就是稍后处理,为什么不同时缓冲更多的块呢?每三个循环写入 1 个块实际上会大大降低写入速度。 这是您正在使用的可读流的实现细节的问题。如果你正在使用一些 NPM 包,你最好在他们的 GitHub 存储库中提交问题。 它实际上是一个HTTP流,它似乎随时提供数据,所以它必须被背压停止。但是看起来 DDBWriter 仅在所有内容都已写入时才重新开始接收数据,而不是在缓冲区不再满时。例如。当它开始写入数据库时​​,它应该开始接受数据到缓冲区,而是等待所有内容都被写入。然后,从逻辑上讲,它会尝试写入收到的第一个块,因此写入的第一个块。

以上是关于NodeJS 可写流 writev 在 1 和 highWaterMark 块之间交替的主要内容,如果未能解决你的问题,请参考以下文章

将数据管道传输到尚未准备好接收数据的可写流

nodejs的流总结

nodejs fs 读取文件流一次读取多少数据

如何在具有可写流的循环中按顺序在 Node 中写入流?

管道传输到可写流时暂停可读流

深入node4 可写流的实现 转化流