Bug 报告:Python Lambda 环境隔离的失败?

0

【以下的问题经过翻译处理】 我在 python 3.6 lambda 中实现了单例设计模式,发现之前的 lambda 执行影响了当前的执行。具体来说,单例类的实例在多个 lambda 环境中是相同的。我很好奇这些对于如何隔离 python lambda 意味着什么?

我遵循了这个流行的堆栈溢出帖子的“方法 3”中描述的单例实现:https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python

这是一个例子。

lambda代码:

import json

class Singleton(type): _instances = {}

def __call__(cls, *args, **kwargs):  
    if cls not in cls._instances:  
        cls._instances\[cls] = super(Singleton, cls).__call__(*args, **kwargs)  
    return cls._instances\[cls]
  

class Foo(metaclass=Singleton): def init(self): self.bar = [] print(f"'bar' attribute is {self.bar}")

def lambda_handler(event, context):

foo = Foo()  
  
print(f"after instantiating 'foo', bar attribute is {foo.bar}")  
foo.bar.append(0)  
print(f"after append, bar attribute is {foo.bar}")

连续多次手动触发 lamba 后产生的 Cloudwatch 日志。我相信新实例没有在第一个之后的 lambda 中实例化,因为“bar”属性包含来自前一个 lambda 的数据。


01:57:14 START RequestId: 69e78a31-4a5e-4e84-abd9-44108f390838 Version: $LATEST 01:57:14 'bar' attribute is [] 01:57:14 after instantiating 'foo', bar attribute is [] 01:57:14 after append, bar attribute is [0] 01:57:14 END RequestId: 69e78a31-4a5e-4e84-abd9-44108f390838 01:57:14 REPORT RequestId: 69e78a31-4a5e-4e84-abd9-44108f390838 Duration: 1.49 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 56 MB Init Duration: 114.96 ms 01:57:21 START RequestId: adacf02b-39b8-468e-a7a5-f4c09bda5758 Version: $LATEST 01:57:21 after instantiating 'foo', bar attribute is [0] 01:57:21 after append, bar attribute is [0, 0] 01:57:21 END RequestId: adacf02b-39b8-468e-a7a5-f4c09bda5758 01:57:21 REPORT RequestId: adacf02b-39b8-468e-a7a5-f4c09bda5758 Duration: 1.38 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 56 MB 01:57:22 START RequestId: d66468cd-f09d-4c28-9343-0eeb52b316e9 Version: $LATEST 01:57:22 after instantiating 'foo', bar attribute is [0, 0] 01:57:22 after append, bar attribute is [0, 0, 0] 01:57:22 END RequestId: d66468cd-f09d-4c28-9343-0eeb52b316e9 01:57:22 REPORT RequestId: d66468cd-f09d-4c28-9343-0eeb52b316e9 Duration: 1.62 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 56 MB 01:57:23 START RequestId: 89813b23-9cb1-4284-ab11-472b84151666 Version: $LATEST 01:57:23 after instantiating 'foo', bar attribute is [0, 0, 0] 01:57:23 after append, bar attribute is [0, 0, 0, 0] 01:57:23 END RequestId: 89813b23-9cb1-4284-ab11-472b84151666 01:57:23 REPORT RequestId: 89813b23-9cb1-4284-ab11-472b84151666 Duration: 1.39 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 56 MB


profile picture
EXPERTE
gefragt vor 5 Monaten35 Aufrufe
1 Antwort
0

【以下的回答经过翻译处理】 嗨 Lookatthisgraph,

看起来你正在尝试使用Lambda运行时环境!

== 一个简短的答案以及为什么这不是一个错误而是一个特性 ==

根据强大的互联网:

可能最简单的设计模式是单例模式,它是一种提供特定类型的一个且仅一个对象的方式...... https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Singleton.html

并且由于你是在句柄之外创建的,还根据以下文章(它使用node作为示例,但此行为在不同运行时中相同):

在被创建或代码或资源配置更新后首次执行函数时,将创建一个具有适当资源的新容器来执行它,并将函数代码加载到容器中。在nodejs中,初始化代码在首次调用处理程序之前每次容器创建时都会执行一次。 https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/

因此,这是Lambda容器的正常行为,并且事实上,我们的许多客户积极利用了这个特性。

== 如何使用这个特性 ==

因此,从最佳实践中可以得出以下结论:

利用执行环境重用来提高函数的性能。在函数处理程序之外初始化SDK客户端和数据库连接,并将静态资产缓存在/tmp目录中。由同一实例处理的后续调用可以重用这些资源。这可以节省执行时间和成本。 为避免跨调用的潜在数据泄漏,请勿使用执行环境存储用户数据、事件或具有安全影响的其他信息。如果您的函数依赖于无法在处理程序内存储的可变状态,请考虑为每个用户创建单独的函数或单独

profile picture
EXPERTE
beantwortet vor 5 Monaten

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen