Node.js 在googlecloud函数中运行node js export

Node.js 在googlecloud函数中运行node js export,node.js,garbage-collection,google-cloud-functions,google-cloud-storage,Node.js,Garbage Collection,Google Cloud Functions,Google Cloud Storage,我们需要导出一个包含大量数据(几gb)的zip文件。zip存档需要包含大约50-100个indesign文件(每个大约100mb)和一些其他较小的文件。我们尝试使用谷歌云功能来实现它(降低成本等)。该功能通过上传到bucket中的配置文件触发。配置文件包含需要放入zip的文件的所有信息。不幸的是,总是达到2gb的内存限制,因此该功能永远不会成功 我们尝试了不同的方法: 第一个解决方案是循环文件,创建下载承诺,循环完成后,我们尝试一次解决所有承诺。(文件通过流媒体直接下载到文件中)。 第二次尝试是

我们需要导出一个包含大量数据(几gb)的zip文件。zip存档需要包含大约50-100个indesign文件(每个大约100mb)和一些其他较小的文件。我们尝试使用谷歌云功能来实现它(降低成本等)。该功能通过上传到bucket中的配置文件触发。配置文件包含需要放入zip的文件的所有信息。不幸的是,总是达到2gb的内存限制,因此该功能永远不会成功

我们尝试了不同的方法: 第一个解决方案是循环文件,创建下载承诺,循环完成后,我们尝试一次解决所有承诺。(文件通过流媒体直接下载到文件中)。 第二次尝试是等待for循环内的每次下载,但再次达到内存限制

所以我的问题是: 为什么node js不清除流?节点似乎将每个流文件都保存在内存中,最终崩溃。我已经尝试将readStream和writeStream设置为null,如下所示:

但是没有变化

注意:我们从来没有达到这样的地步,所有文件都是下载来创建zip文件的。它总是在第一个文件之后失败。

请参见下面的代码片段:

// first try via promises all:
const promises = []
for (const file of files) {
    promises.push(downloadIndesignToExternal(file, 'xxx', dir));
}

await Promise.all(promises)


// second try via await every step (not performant in terms of execution time, but we wanted to know if memory limit is also reached:
for (const file of files) {
    await downloadIndesignToExternal(file, 'xxx', dir);
}


// code to download indesign file
function downloadIndesignToExternal(activeId, externalId, dir) {
  return new Promise((resolve, reject) => {
    let readStream = storage.bucket(INDESIGN_BUCKET).file(`${activeId}.indd`).createReadStream()
    let writeStream = fs.createWriteStream(`${dir}/${externalId}.indd`);
    readStream.pipe(writeStream);
    writeStream.on('finish', () => {
      resolve();
    });
    writeStream.on('error', (err) => {
      reject('Could not write file');
    })
  })
}

重要的是要知道/tmp(os.tmpdir())是一个。当您将文件下载到/tmp时,它会占用内存,就像您将其保存到内存缓冲区中一样

如果您的函数需要的内存超过了为函数配置的内存,那么云函数可能不是解决此问题的最佳解决方案

如果仍然要使用云函数,则必须找到一种方法,将输入文件直接流式传输到输出文件,但不在函数中保存任何中间状态。我相信这是可能的,但您可能需要为此编写大量额外的代码。

对于任何感兴趣的人:
我们通过将文件流式传输到zip中,并将其直接流式传输到google云存储中,使其正常工作。内存使用量现在约为150-300mb,因此这对我们来说非常适合

这里的
dir
是什么?它是通过os.tmpdir()生成的dir。代码本身可以在我们的开发平台上运行,但是只有一些小文件。在暂存(真实数据)时,我们达到2gb内存限制。这很有意义!我认为在这种情况下它对我们不起作用,因为我们想将zip文件上传到一个存储桶中。谢谢您当然可以在内存中输入和输出zip。我看到npm中有一个模块可以做到这一点。