S3 Lambda 在恰好 10 分钟后触发双重调用

S3 Lambda trigger double invocation after exactly 10 minutes

我们正在经历由 S3 ObjectCreated-Events 触发的 Lambda 的两次 Lambda 调用。这些双重调用发生在第一次调用后 正好 10 分钟,而不是第一次尝试完成后 10 分钟,而是第一次调用发生后 10 分钟。原始调用需要 0.1 到 5 秒之间的任何时间。没有调用导致错误,它们都成功完成。

我们知道这样一个事实,例如 SQS 不能保证消息的精确传递但至少一次传递,我们会接受一些 lambda 因分布式系统的结果而被第二次调用下。然而,延迟 10 分钟听起来很奇怪。

在大约 10k 条消息中,有 100-200 条消息导致双重调用。

AWS Support 基本上说 "the 10 minute wait time is by design but we cannot tell you why",这根本没有帮助。



示例日志:两次调用,相隔 10 分钟,相同的 RequestId

START RequestId: f9b76436-1489-11e7-8586-33e40817cb02 Version: 13
2017-03-29 14:14:09 INFO ImageProcessingLambda:104 - handle 1 records

START RequestId: f9b76436-1489-11e7-8586-33e40817cb02 Version: 13
2017-03-29 14:24:09 INFO ImageProcessingLambda:104 - handle 1 records

不想为了处理这个问题而启动像 Dynamo 这样的数据存储,我做了两件事来解决我们的用例

  • 将每个函数的锁定文件写入 S3(我们已经在这个函数中使用过)并在函数入口处检查它是否存在,如果存在则中止;对于这个函数,我们一次只需要其中一个 运行 。在我们调用错误或成功回调之前删除锁定文件。
  • 在初始事件负载中写入请求时间,并在函数入口检查请求时间;如果请求时间太旧则中止。我们不希望 Lambda 重试错误,除非它们很快完成,因此这处理了发送重复或重试而同一函数的另一个调用尚未 运行 的情况(这将被停止锁定文件),并且在这种情况下还避免了 S3 请求处理锁定文件的最小开销。

在与 AWS 支持人员和其他人进行了几轮和一些独立的试运行之后,这似乎只是 "by design"。不清楚 为什么 ,但它确实发生了。问题既不是 S3 也不是 SQS / SNS,而只是 lambda 调用以及 lambda 服务如何将调用分派给 lambda 实例。

两次调用发生在所有调用的 1% 到 3% 之间,发生在第一次调用后 10 分钟。令人惊讶的是,甚至有三次(可能是四次)调用,其频率为基本概率的幂,所以基本上是 0.09%,......三次调用发生在第一次调用之后 20 分钟。

如果您遇到这种情况,您只需使用您可以访问的任何内容来解决它。例如,我们现在将已处理的实体存储在 Cassandra 中,TTL 为 1 小时,并且仅在实体尚未处理时才响应来自 lambda 的消息。两次和三次调用都发生在这一小时的时间范围内。