GAE Python 标准:超过硬内存限制,而 RSS 小两倍

Posted

技术标签:

【中文标题】GAE Python 标准:超过硬内存限制,而 RSS 小两倍【英文标题】:GAE Python Standard: Exceeded hard memory limit while RSS is twice smaller 【发布时间】:2022-01-15 06:11:08 【问题描述】:

我在 App Engine Python3 标准环境(Flask)中有一个应用程序。该应用程序处理图像。它使用临时 (/tmp) 空间下载并调整它们的大小。对于图像处理,它使用 Pillow (PIL.Image) 将所有内容加载到内存中。因此,该应用程序非常消耗内存,因为图像可能很大(例如 6000x6000)。我开始在 F1/F2/B1/B2 实例上收到“超出硬内存限制”错误。这有点可以理解。所以我使用 Python 的 resource 模块添加了最大驻留集大小 RSS 的当前值的跟踪:

maxrss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

并将实例类增加到 B4(1GB RAM)。 但这没有帮助。以下是来自 Cloud Logging 的日志:

2021-12-09 18:17:49.352 MSK 291 - mem: 418,088
2021-12-09 18:17:49.476 MSK Exceeded hard memory limit of 1024 MB with 1075 MB after servicing 7 requests total. Consider setting a larger instance class in app.yaml.
2021-12-09 18:17:49.478 MSK [start] 2021/12/09 15:17:49.477740 Quitting on terminated signal
2021-12-09 18:17:49.483 MSK [10] [INFO] Handling signal: term
2021-12-09 18:17:49.616 MSK 292 - mem: 418,088

291和202是遍历所有图像的次数,mem是resource模块报告的max_rss。

我不明白为什么在 AppEngine 看到的服务器进程的 RSS 和 GAE 服务的内存之间存在如此大的差异。

我知道服务器代码在 OS 内部执行,OS 在 Docker 内部,GAE 从顶部测量内存,但对于 Linux 和 Docker,600MB 似乎太多了,不是吗?

第一个问题:如何了解我的代码在 GAE 上实际消耗了多少内存? 为什么GAE的内存和进程的RSS差别这么大?

【问题讨论】:

是否有可能 291 和 292 指的是 1 个请求中使用的内存,而 GAE 由于多个请求的累积而引发了问题(它说您的日志中总共有 7 个请求)。你能弄清楚你的应用是否触发了多个请求,是否可以将其缩小到 1 以便比较内存消耗? 当然,这是一个请求。 “在总共服务 7 个请求之后”是无关紧要的。实际上,我从客户端执行一个服务器控制器,它执行所有图像处理。大约需要10-15分钟。在此期间没有其他请求。 【参考方案1】:

好吧,我找到了占用内存的答案。 根据 https://cloud.google.com/appengine/docs/standard/python3/using-temp-files:

此目录中的所有文件(即 /tmp,由我添加)都存储在 实例的 RAM 中,因此写入 /tmp 会占用系统内存。此外,/tmp 目录中的文件仅对创建文件的应用实例可用。

就是这么简单。因此,基本上实例类的内存限制是进程的内存和您在 /tmp 文件夹中创建的所有文件的总和。

【讨论】:

以上是关于GAE Python 标准:超过硬内存限制,而 RSS 小两倍的主要内容,如果未能解决你的问题,请参考以下文章

AWS ECS 任务内存硬限制和软限制

GAE 中的“软私有内存限制”是啥?

GAE 标准 python 2.7 运行时何时消失?

文件系统之磁盘配额

GAE 上 Memcache 的回写策略

Docker 限制容器资源