【问题标题】:AWS Lambda initialization code (Python) mysteryAWS Lambda 初始化代码(Python)之谜
【发布时间】:2019-06-05 23:02:28
【问题描述】:

我有一个 Python 3.6 Lambda 函数,需要将依赖项下载到 /tmp(我也使用层,但由于大小限制需要 /tmp)并导入它们。我有在处理程序之前执行下载压缩和提取到临时部分的代码,期望它只需要在冷启动时下载。说它看起来像下面(伪代码):

log('Cold start')
download_deps() # has some log statements of its own
log('init end')

def handler(event, context):
...

大多数时候它工作正常。但是,在初始化过程中,日志时不时会停止显示在某处。 (例如,它说“冷启动”,但不是“初始化结束”;它在 download_deps 的某处“死”)。我在那里进行异常处理并记录所有内容,但没有显示任何内容。当处理程序下次运行时,它会遇到 ImportError。

在尝试解决此问题时,我注意到了一些奇怪的事情。初始化代码在 Lambda 的一次调用中运行两次。鉴于上述伪代码,日志如下所示:

Cold start
<logs from download_deps that indicate it downloaded things into /tmp>
START <RequestId> ...

<RequestId> Cold start
<logs from download_deps that indicate it skipped download because /tmp was already populated by deps>
init end
END <RequestId>

“init end”部分第一次没有出现,所以日志又一次消失了。由于它第二次跳过下载(/tmp 被保留),我知道这不是 2 次实际的冷启动发生。第二次记录“冷启动”时,它包含 RequestId,但不是第一次;几乎就好像第一次初始化不是由请求引起的,即使 API 网关上的请求时间与第一次“冷启动”的时间相匹配。这是怎么回事?

【问题讨论】:

  • 下载到 /tmp 文件夹的大小是多少?
  • 所以有 2 个 zip,每个我下载并解压缩然后删除 zip。提取后,它们的总大小略小于 250 MB。
  • 这很有趣,我们已经看到了由于 tmp 文件夹内存不足而导致日志停止显示的情况,这造成了一些棘手的问题,但看起来你并不反对该限制,尽管您确实提到您正在使用图层,但并不能 100% 确定这不会影响该限制。 lambda 必须使用多少内存?你有没有把它调高,看看是否会导致这种情况?
  • download_deps()中是否使用了异步机制?例如,multithreadinggreenletgeventasyncio
  • @JosephKing 是的,我怀疑某种磁盘空间问题,但根据我的理解,我在限制范围内。我之前曾看到 Lambda 磁盘空间不足,但已记录错误。 Lambda 目前有 1024 MB 的内存。

标签: python aws-lambda


【解决方案1】:

我注意到两个“冷启动”总是相隔约 10 秒。看起来如果初始化代码花费的时间超过 ~10 秒,它就会重新启动。此外,根据日志中报告的持续时间,第二次初始化所用的时间包含在计费持续时间中。

为了解决我的问题,我将 download_deps() 移到处理程序中,确保它只在需要时执行任何操作。

【讨论】:

  • 可能是第二次冷启动来自并发 Lambda 实例。一旦 AWS Lambda 注意到请求太多而无法由现有的已分配实例池处理,它就会将实例添加到池中(最多 1000 个,IIRC)。
猜你喜欢
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多