首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在AWS Lambda中缓存多个AWS参数存储值?

如何在AWS Lambda中缓存多个AWS参数存储值?
EN

Stack Overflow用户
提问于 2020-01-03 20:18:11
回答 2查看 2.2K关注 0票数 2

背景

我希望限制AWS参数存储在我的AWS中被调用的次数。使用全局变量,我在第一次调用Parameter时缓存一个Parameter值。

main.py

代码语言:javascript
复制
import os

import boto3


redis_password = None

def get_redis_password():
    global redis_password
    if not redis_password:
        client = boto3.client("ssm")
        redis_password = client.get_parameter(
            Name=f"{os.environ["ENV"]}.redis-cache.password",
            WithDecryption=True
        )
    return redis_password["Parameter"]["Value"]

def lambda_handler(event, context):
    get_redis_password()

但是,如果要缓存多个参数存储值,则必须创建多个全局变量和if not [INSERT_GLOBAL_VARIABLE]检查。例如:

main.py

代码语言:javascript
复制
import os

import boto3


redis_password = None
another_parameter_store_value = None

def get_redis_password():
    global redis_password
    if not redis_password:
        client = boto3.client("ssm")
        redis_password = client.get_parameter(
            Name=f"{os.environ["ENV"]}.redis-cache.password",
            WithDecryption=True
        )
    return redis_password["Parameter"]["Value"]

def get_another_parameter_store_value():
    global another_parameter_store_value
    if not another_parameter_store_value:
        client = boto3.client("ssm")
        another_parameter_store_value = client.get_parameter(
            Name=f"{os.environ["ENV"]}.another.parameter.store.key",
            WithDecryption=True
        )
    return redis_password["Parameter"]["Value"]

def lambda_handler(event, context):
    get_redis_password()
    get_another_parameter_store_value()

尝试解决方案

为了解决这个问题,我创建了一个Parameter实用程序。

parameter_util.py

代码语言:javascript
复制
import os
import boto3


class ParameterUtil:
    def __init__(self):
        self.boto_client = boto3.client("ssm")

    def get_parameter(self, parameter_path):
        response = self.boto_client.get_parameter(
            Name=f"{os.environ['ENV']}.{parameter_path}", WithDecryption=True
        )

        return response["Parameter"]["Value"]

我的理论是,通过实例化AWS Boto客户端作为实例变量,它将缓存整个Boto客户端对象。然后将使用缓存的Boto客户端调用get_parameter。例如:

main.py

代码语言:javascript
复制
import os

import boto3

from parameter_util import ParameterUtil


redis_password = None

def get_redis_password():
    global redis_password
    if not redis_password:
        client = boto3.client("ssm")
        redis_password = client.get_parameter(
            Name=f"{os.environ["ENV"]}.redis-cache.password",
            WithDecryption=True
        )
    return redis_password["Parameter"]["Value"]

def lambda_handler(event, context):
    param_util = ParameterUtil()
    param_util.get_parameter(".redis-cache.password")
    param_util.get_parameter(".another.parameter.store.key")

然而,我不太确定这是否解决了这个问题。

问题

当调用get_parameter时,缓存Boto客户端是否只导致每个参数对parameter的一个调用?还是我在错误的地方优化?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-03 21:15:57

您的原始代码无法工作,因为param_util是一个局部变量,它将超出每个Lambda调用的范围。

您可以使用内置的@functools.lru_cache创建一个处理任何参数的简单函数。它将根据函数的输入(Python )缓存返回值。

使用可调用的回忆录封装一个函数,该函数保存到maxsize最近的调用。当周期性地使用相同的参数调用昂贵的或I/O绑定函数时,它可以节省时间。

示例:

代码语言:javascript
复制
ssm_client = boto3.client("ssm")

@lru_cache(maxsize=None)
def get_param(name):
    return ssm_client.get_parameter(
        Name=f"{os.environ['ENV']}.{name}",
        WithDecryption=True
    )["Parameter"]["Value"]

def lambda_handler(event, context):
  redis_password = get_param("redis-cache.password")
  another_parameter_store_key = get_param("another.parameter.store.key")
票数 3
EN

Stack Overflow用户

发布于 2020-01-03 20:39:53

我喜欢这种方法。我可能会建议把它抽象成这样的东西:

main.py

代码语言:javascript
复制
parameter_store_values = {}
client = boto3.client("ssm")

def lookup_function(key):
    global parameter_store_values
    global client
    if parameter_store_values.get(key) is None:
        value = client.get_parameter(
            Name=key,
            WithDecryption=True)["Parameter"]["Value"]
        parameter_store_values[key] = value
    return value

def lambda_handler(event, context):
    redis_password = lookup_function(f"{os.environ["ENV"]}.redis-cache.password")
    another_parameter_store_key = lookup_function(f"{os.environ["ENV"]}.another.parameter.store.key")
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59584849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档