【问题标题】:How to delete files in tmpfs or /tmp directory for Google Cloud Functions?如何为 Google Cloud Functions 删除 tmpfs 或 /tmp 目录中的文件?
【发布时间】:2019-06-26 19:31:21
【问题描述】:

我有一个用 Node.js 编写的谷歌云函数,我已经设置为使用云调度程序每 4 小时执行一次。基本上,该函数填充了我在 BigQuery 中的一个表。我的函数没有向 tmp 目录显式写入任何内容,它只是将内容存储在本地变量中,以便像这样流式插入 BigQuery:

var rows = []

// code which fills the rows array

await bigqueryClient
      .dataset(datasetId)
      .table(tableId)
      .insert(rows)

我注意到(查看内存使用情况图表)每次调用使用的内存都会上升,直到达到为函数设置的限制(我有 512MB 用于此功能),然后我记录了一个错误- “错误:超出内存限制。函数调用被中断。”

我尝试了下面的代码来尝试删除 tmp 目录中的所有文件,但似乎没有要删除的文件:

const directory = '/tmp';

fs.readdir(directory, (err, files) => {
  if (err) throw err
  console.log(files)

  for (const file of files) {
    fs.unlink(path.join(directory, file), err => {
      if (err) throw err
    })
  }
})

记录的只是一个空数组“[]”。

我在这里缺少什么?是其他问题吗?

【问题讨论】:

  • 我很好奇,如果你没有在 /tmp 中放一些东西,你为什么会期待任何东西在里面。此外,如果您的函数仅每 4 小时执行一次,则基本上不可能保留上一次运行的状态以供下一次运行。 Cloud Functions 不会让空闲的服务器实例存活那么久。如果您的内存不足,那几乎肯定是由于单次运行中发生的事情。
  • 嗯,就是这样,我没想到 /tmp 中有任何内容,但是随着时间的推移查看图表,它看起来像是保留了一些东西,因为有一种模式,每次调用占用更多内存比上次失败,然后看起来它“重置”了文件夹。这是内存使用标准模式的截图i.imgur.com/zbolNHG.png 我的函数在技术上应该在每次调用时占用相似的内存,所以这种模式不是预期的。
  • 随着时间的推移,内存使用对我来说看起来有点随机。我没有看到一个既定的模式。我怀疑你什么都不担心。
  • 感谢您的回复。也许我的内存使用问题与 /tmp 文件夹内容完全无关,可能与我的功能有关。话虽如此,删除 tmpfs 或 /tmp 目录中的文件的最佳做法是什么?最佳实践页面说总是删除临时文件 - cloud.google.com/functions/docs/bestpractices/tips - 但没有任何严格的指导。我使用 fs.unlink() 的方法是否足够?什么是最佳做法?
  • 也许@DougStevenson 再次回答的this other post 可能会对云函数的临时文件有所帮助。

标签: node.js google-cloud-platform google-bigquery google-cloud-functions


【解决方案1】:

您的代码将在下一次运行时删除所有文件,但如果您使用const ws = fs.createWriteStream('/tmp/${fileName}'); 之类的内容创建文件,则在下一次运行之前不会删除该文件。

如果您想删除所有文件作为当前进程的一部分,那么您可以将创建文件的部分与文件清理分开,并将两者包装在 Promise 中。

这将删除/tmp中的所有文件。

const directory = '/tmp';
const fileName  = `test_file_1.gz`;
 
function doSomething() {
  return new Promise((resolve) => {   
    const ws = fs.createWriteStream(`/tmp/${fileName}`);
    resolve();
  });
}

function fileCleanup() {
  return new Promise((resolve) => {   
    fs.readdir(directory, (err, files) => {
      if (err) throw err;
      console.log(files);

      for (const file of files) {
        fs.unlink(path.join(directory, file), err => {
          if (err) throw err;
          console.log(`${file} was deleted`);
        });
      }
    });
    resolve();
  });
}

doSomething().then(() => { fileCleanup(); }).then(() => { res.status(200).send('OK'); }).catch((err) => { throw new Error(err); });

如果res.status(200).send('OK'); 不是 HTTP 触发器,则删除它。此外,对于本地测试,我创建了一个名为 tmp 的目录。云函数使用/tmp,但在本地使用./tmp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 2018-12-31
    • 2017-09-23
    • 2019-05-03
    • 2018-08-02
    • 1970-01-01
    • 2012-03-01
    相关资源
    最近更新 更多