【发布时间】:2017-05-04 14:50:44
【问题描述】:
我们遇到了由 S3 ObjectCreated-Events 触发的 Lambda 的两次 Lambda 调用。这些双重调用恰好在第一次调用后 10 分钟发生,而不是在第一次尝试完成后 10 分钟,而是在第一次调用发生后 10 分钟。原始调用需要 0.1 到 5 秒之间的任何时间。没有调用导致错误,它们都成功完成。
我们知道,例如,SQS 不能保证只传递一次但至少传递一次消息,并且由于底层分布式系统的结果,我们会接受一些 lambdas 被第二次调用。然而,延迟 10 分钟听起来很奇怪。
在大约 10k 条消息中,100-200 条会导致两次调用。
AWS Support 基本上说“10 分钟的等待时间是设计使然,但我们无法告诉你原因”,这根本没有帮助。
- 以前有没有其他人经历过这种行为?
- 您是如何解决问题的,或者您只是忽略了它(我们可以这样做)?
- 一种建议的解决方案是不使用直接 S3-lambda-triggers,而是让 S3 将其事件放在 SNS 上并订阅 Lambda。有使用这种方法的经验吗?
示例日志:两次调用,相隔 10 分钟,相同的 RequestId
START 请求 ID:f9b76436-1489-11e7-8586-33e40817cb02 版本:13
2017-03-29 14:14:09 INFO ImageProcessingLambda:104 - 处理 1 条记录
和
START 请求 ID:f9b76436-1489-11e7-8586-33e40817cb02 版本:13
2017-03-29 14:24:09 INFO ImageProcessingLambda:104 - 处理 1 条记录
【问题讨论】:
-
正如您在问题中很好地描述的那样,“不保证完全一次但至少一次传递消息”,如果这不会破坏功能,那么您的第二个解决方案是最好的这点。我认为第三种解决方案没有任何区别,因为重复事件将再次提交给 SNS,因为订阅 Lambda 将简单地执行。如果您确实需要避免重复处理,您可以在 ElasticCache 或其他系统中的某个位置缓存“RequestIds”并添加签入 Lambda 以确保请求已被处理。
-
“AWS Support 基本上说...” 而不是解释一些对您来说没有意义的东西...他们实际上说了什么?
-
@Michael-sqlbot “我无法详细说明 S3 事件是如何在幕后实现的,但服务的行为符合预期,对于 S3 事件,10 分钟的延迟是设计使然” ,这样更有帮助吗??
-
@Nambari 在 lambda 中使用任何类型的缓存或逻辑来防止双重调用完全是矫枉过正。我们通常可以处理双重调用没有问题,请注意,在我们现在发送的几百万条 sqs 消息中,没有双重传递(如果真的发生的话)曾经引起过问题。两次调用之间的 10 分钟是个问题。我们可以将应用程序更改为能够处理延迟十分钟的消息,但这感觉不对,而且对理解这里发生的事情没有帮助。
-
我明白了。谢谢你的澄清。这确实很奇怪,但似乎您已经正确诊断出真正的双重调用。在我的环境中,我使用 S3 > SNS > Lambda 而不是 S3 > Lambda,因为 (a) 有(或可能有)未来的目标想要相同的 S3 事件 (b) 它在某种程度上感觉更正确,我想知道这是否会改变动力学。我的过程是写入数据库,因此是有状态的和幂等的,所以重复调用实际上只是验证工作已经完成。但我会检查日志,因为我可能有一些有趣的事情......或者没有。
标签: amazon-web-services amazon-s3 aws-lambda eventtrigger