Firebase 的 Cloud Functions 因超出内存限制而被终止

Posted

技术标签:

【中文标题】Firebase 的 Cloud Functions 因超出内存限制而被终止【英文标题】:Cloud Functions for Firebase killed due to memory limit exceeded 【发布时间】:2017-09-04 21:53:08 【问题描述】:

在转换相对较小的图像 (2mb) 时,我不断收到来自 Cloud Functions for Firebase 的零星错误。成功后,该功能只需要大约 2000 毫秒或更短的时间即可完成,根据 Image Magick 文档,我应该不会看到任何问题。

我尝试增加命令的缓冲区大小,这在 Firebase 中是不允许的,我尝试找到 .spawn() 的替代方案,因为这可能会因垃圾而超载并减慢速度。没有任何效果。

【问题讨论】:

所有信息都在这里:manage-functions. 更具体地说,这里:#set_timeout_and_memory_allocation 轻松增加内存的说明 - ***.com/a/69653948/1205871 【参考方案1】:

您可以在 Firebase 上的 Cloud Function 文件中进行设置。

const runtimeOpts = 
  timeoutSeconds: 300,
  memory: '1GB'


exports.myStorageFunction = functions
  .runWith(runtimeOpts)
  .storage
  .object()
  .onFinalize((object) = > 
    // do some complicated things that take a lot of memory and time
  );

取自此处的文档: https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation

不要忘记从终端运行firebase deploy

【讨论】:

应该是一致性的公认答案。人们用命令行回答,如果你在一个小组项目中或者项目发生变化,那就不好了。 从 'firebase-functions' 导入 VALID_MEMORY_OPTIONS ; VALID_MEMORY_OPTIONS['1GB'] 用于打字稿 这应该是最好的答案,这是最简单的,面向未来的,不需要维护,做和忘记的方法 对我不起作用,除非我也遵循@p3sn 给出的答案【参考方案2】:

从 UI 中弄清楚有点棘手,所以这里有一些指导性的屏幕截图: 转到网址https://console.cloud.google.com/functions/list


您还可以增加 60 秒的默认超时时间

【讨论】:

这不再起作用,因为它要求再次上传源代码! 是的,为什么它要求并需要另一个源代码只是为了改变内存使用;它不是已经从firebase deploy上传了源代码吗???这毫无意义!【参考方案3】:

您可以在 Firebase 函数定义中添加配置,例如:

functions.runWith(memory: '2GB', timeoutSeconds: '360')

【讨论】:

【参考方案4】:

你可以在这里调整你的记忆:

【讨论】:

这是唯一有效的解决方案! UI 不再允许您更改内存。看起来确实如此,但它需要您点击“下一步”按钮而不是“保存”按钮。 “保存”您的内存更改的唯一方法是为您的函数上传新的源代码,这当然没有意义,因为您的函数的源代码已经存在,否则该函数首先不会在表中. 这是 2020 年迄今为止唯一也是最好的解决方案。【参考方案5】:

我迷失在UI中,找不到任何更改内存的选项,但终于找到了:

    转到 Google Cloud Platform Console(不是 Firebase 控制台) 在菜单中选择Cloud Functions 现在您可以在此处看到您的 firebase 函数(如果正确)。否则检查您是否选择了正确的项目。 忽略所有复选框、按钮和菜单项,只需点击函数名称。 点击编辑(顶部菜单),只更改分配的内存并点击保存。

【讨论】:

哪个“***菜单”?我只看到“创建函数”、“刷新”、“删除”和“复制”。也许它必须是付费帐户? 你是救生员!谷歌云中的功能控制台太棒了! 请注意,这些设置将在您每次部署函数时重置。使用函数.runWith()。 firebase.google.com/docs/functions/… 然后它强迫我点击“下一步”,然后我必须指定一个“源代码”。这对我来说没有意义。我已经上传了这个函数的源代码。为什么我必须指定另一个,而哪个告诉它只使用原来的?【参考方案6】:

最新的 firebase deploy 命令确实会将内存分配覆盖为默认的 256MB,超时时间最长为 60 秒。

另外,为了指定所需的内存分配和最大超时,我使用 gcloud 命令,例如:

gcloud beta 函数部署 YourFunctionName --memory=2048MB --timeout=540s

其他选项,请参考:

https://cloud.google.com/sdk/gcloud/reference/beta/functions/deploy

【讨论】:

【参考方案7】:

这里的另一个选择是完全避免使用.spawn()

有一个很棒的节点图像处理包Sharp,它使用低内存占用库libvips。您可以在 Github 上查看 Cloud Function 示例。

另外,ImageMagick(和 GraphicsMagick)有一个 Node 包装器,名为 gm。它甚至支持-limit 选项向 IM 报告您的资源限制。

【讨论】:

有趣。会给锋利的一枪。谷歌云的问题是你不能真正在本地测试任何东西,并且需要通过一段云代码推动每一个变化。因此,即使是更好的解决方案,转换成本也很高。 您应该检查一下刚刚添加的一些新的本地测试功能。现在您在本地测试触发的函数并对其运行单元测试。 firebase.google.com/docs/functions/… 模拟器还不支持存储接口【参考方案8】:

Firebase Cloud Functions 中的默认 ImageMagick 资源配置似乎与分配给该函数的实际内存不匹配。

在 Firebase 云函数的上下文中运行 identify -list resource 会产生:

File       Area         Memory        Map       Disk   Thread  Throttle       Time
--------------------------------------------------------------------------------
 18750    4.295GB       2GiB       4GiB  unlimited        8         0   unlimited  

分配给 FCF 的默认内存为 256MB - 默认 ImageMagick 实例认为它有 2GB,因此不会从磁盘分配缓冲区,并且很容易尝试过度分配内存,从而导致函数在 Error: memory limit exceeded. Function killed. 上失败

一种方法是按照上面的建议增加所需的内存 - 尽管 IM 仍然存在根据您的用例和异常值尝试过度分配的风险。

更安全的方法是使用-limit memory [your limit] 在图像处理过程中为 IM 设置正确的内存限制。您可以通过使用“-debug Cache”运行您的 IM 逻辑来计算您的大约内存使用量 - 它会显示所有分配的缓冲区、它们的大小以及它们是内存还是磁盘。

如果 IM 达到内存限制,它将开始在磁盘上分配缓冲区(内存映射,然后是常规磁盘缓冲区。您必须考虑 I/O 性能与内存成本之间的具体平衡。每增加一个内存字节的价格您分配给 FCF 的时间乘以 100 毫秒的使用量 - 这样可以快速增长。

【讨论】:

【参考方案9】:

[更新] 正如一位评论者所建议的那样,这应该不再是问题,因为 firebase 功能现在会在重新部署时保持其设置。感谢火力基地!

事实证明,这并不明显或没有记录,您可以在 Google Functions Console 中为您的函数增加内存分配。您还可以增加长时间运行的函数的超时时间。它解决了内存过载的问题,现在一切正常。

编辑:请注意,Firebase 会在部署时重置您的默认值,因此您应该记住登录控制台并立即更新它们。我仍在寻找通过 CLI 更新这些设置的方法,当我找到它时会更新。

【讨论】:

我找不到为我的函数增加内存分配的地方。我应该在功能控制台中去哪里? tks! @Walucas Cloud Functions > name of your function > 点击“编辑” > 然后编辑“内存分配”中的数字 功能设置再次为我重置。 增加更多内存对价格有何影响? 还可以设置超时和内存programmatically。【参考方案10】:

更新:看起来他们现在保留了重新部署的设置,因此您可以在云控制台中安全地更改内存分配!

【讨论】:

哦,好消息!我有一段时间没有重新部署,以避免任何事情发生故障。将在测试项目上尝试一下。如果它再次工作,那就太好了! 更新:它每次都为我重置它们(并且由于在部署时超过内存限制而无法部署,这会造成尴尬的鸡和蛋问题)。 截至 2020 年 1 月,这些设置在重新部署时仍会保留

以上是关于Firebase 的 Cloud Functions 因超出内存限制而被终止的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Cloud Function 调用其他 Cloud Firebase Functions

在 Cloud Function for Firebase 中设置 Firebase 消息的优先级

是否可以检索 Firebase Cloud Function 源代码?

Firebase Cloud Function 部署 tslint 错误

Firebase:Firestore 未在 Cloud Function 的计划函数中更新数据

从请求中获取用户信息到 Firebase 中的 Cloud Function