【问题标题】:Results of S3 function call are being cached by my Lambda function我的 Lambda 函数正在缓存 S3 函数调用的结果
【发布时间】:2018-07-20 12:00:45
【问题描述】:

我有一个 lambda 函数,它使用 S3.listObjects 返回目录列表。列表有时(并非总是!)过时 - 它不包含最近上传的对象,并且它拥有的对象具有旧的修改日期。

当我在本地运行相同的代码时,它总是可以正常工作。

显然是某种缓存,但我不明白在哪里......

以下是相关代码:

function listFiles() {
    return new Promise(function (resolve, reject) {
        const params = {
            Bucket: "XXXXX",
            Prefix: "YYYYY"
        };
        s3.listObjects(params, function (err, data) {
            if (err) reject(err);
            else resolve(data.Contents);            
        });
    })
}

【问题讨论】:

  • 虽然最终一致性确实适用于对象列表,但长时间延迟并不典型,并且不应有来自任何其他来源的缓存。您是否通过存储桶日志验证了您的函数实际上是在函数运行时发出列表对象请求?长时间的延迟表明,在调用此函数的任何内容中都可能存在错误,导致结果被重用,直到容器被销毁并且下一次调用得到一个新容器。
  • 要观察容器生命周期,定义一个全局变量,例如var container_id。然后在处理程序内部,container_id = container_id ? container_id : context.invokeid;console.log('this container is ' + container_id);(context.invokeid 没有实际意义,它恰好是 UUID 的一个很好的来源。我们仅在未设置时将其设置在变量中。变量是全局的,因此它在调用过程中保持其价值。在本地,可能没有像这样的重用。)您应该会在几分钟内看到相同的 ID(假设流量较低),然后它最终会改变。

标签: amazon-s3 lambda aws-lambda aws-sdk


【解决方案1】:

这是由于Amazon S3 Data Consistency Model。 S3 为 PUT 提供写后读一致性,但其他请求(包括 listObjects)最终是一致的,这意味着传播可能会有延迟。

【讨论】:

  • 谢谢,但延迟肯定最多只有几秒钟?我可能会在 10 分钟后,有时是半小时后收到过期的列表。
【解决方案2】:

实践中的先读后写一致性在几秒钟内就确定下来了。但是,这不是保证。亚马逊在几分钟后返回陈旧数据的可能性不大,但并非不可能,尤其是跨区域时。但是,您的客户端更有可能正在缓存对同一 URL 的先前响应。

您可能会遇到重复使用 lambda 容器的副作用。这在高级别 here 中进行了解释。容器重用的一个后果是,当重新调用 lambda 时,后台进程、临时文件和全局变量修改仍然存在。另一个article talking about how to guard

如果您将日志发送到 cloudwatch 日志,如果 lambda 的日志似乎附加到前一个日志流的末尾,您可以确认容器正在被重复使用,而不是创建新的日志流。

当您的 lambda 容器被重用时,处理函数外部的全局变量将被重用。例如,如果您在处理程序结束时将日志调用的日志级别更改为 DEBUG,如果您的容器被重用,它将在处理程序的顶部以相同的日志级别开始。

如果您使用的是默认的 s3 客户端会话(您似乎是这样),那么此连接将保持在全局(单例)中。如果您的 s3 客户端连接被重用,它可能会提前拉取调用的缓存结果,我希望在以后的调用中重用该连接。

避免这种情况的一种方法是指定 If-None-Match 请求标头。如果您正在访问的对象的 ETag 在远程端不匹配,您将获得新数据。您可以将其设置为您获得的最后一个 Etag(您将存储在全局中),或者您可以尝试设置一个完全随机的值——它应该充当缓存破坏器。但是,list_objects() 似乎不接受 If-None-Match 标头。您可以尝试为当前调用创建一个新的客户端会话。

article on recursive lambdas 讨论了这个问题。

【讨论】:

    猜你喜欢
    • 2017-10-20
    • 2010-11-13
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2019-01-21
    相关资源
    最近更新 更多