使用 "big" 数据在 node.js 中启动 webworker 时内存快速增加

Fast rising memory when starting webworker in node.js with "big" data

我有在节点中启动 webworker 的典型代码:

var Threads = require('webworker-threads');    
var worker = new Threads.Worker(__dirname + '/workers/myworker.js');

worker.onmessage = function (event) {
    // 1.
    // ... create and execute cypher query ...
};

// Start the worker.
worker.postMessage({
    'data' : data
});

在 1. 我将经过处理的小块数据发送到 Neo4J 数据库。 对于小 data 这工作得很好,但是当数据变得稍微大一点时 node/the worker 开始挣扎。

我要处理的实际 data 是一个 csv,我用 BabyParse 解析了一个对象,该对象具有 149000 个属性,每个属性都有另外 17 个属性。 (149000 行乘以 17 列 = 2533000 个属性)。文件大小为 17MB。

执行此操作时,节点将分配大量内存并最终在大约 53% 的内存分配时崩溃。机器有4GB.

工人大概长这样:

self.onmessage = function (event) {
    process(event.data.data);
};

function process(data) {
    for (var i = 0; i < data.length; i++) {
        self.postMessage({
            'properties' : data[i]
        });
    }
}

我尝试对数据进行分块,并在 worker 中分块处理它,这也能正常工作。但是我想生成一个图形并处理我需要完整数据的边,因为我需要对照所有其他行检查每一行(顶点)。

有没有办法将数据流式传输到工作程序中?或者有人知道为什么节点在发送 17MB 数据时分配这么多内存吗?

除了在主线程中解析数据之外,您还可以将文件名作为消息传递给工作人员并让工作人员从磁盘加载它。否则,您将所有数据都存储在内存中两次,一次在主机中,一次在工作程序中。

另一种选择是将 csv npm 包与流式解析器一起使用。 postMessage 线路进入并缓冲它们直到 worker 中的最终结果。

我不知道为什么您的解决方案会尝试分配大量内存。我知道 postMessage 是为了传递小消息。