【发布时间】:2020-07-04 03:40:27
【问题描述】:
我正在 AWS Lambda 函数中运行 Python 脚本。它由 SQS 消息触发,该消息告诉脚本某些对象从 S3 存储桶加载以进行进一步处理。
权限似乎设置正确,存储桶策略允许 Lambda 的执行角色对存储桶中的任何对象执行任何操作。并且 Lambda 可以在大多数时间访问所有内容。正在通过pandas 和s3fs 加载对象:pandas.read_csv(f's3://{s3_bucket}/{object_key}')。
但是,当新对象上传到 S3 存储桶时,Lambda 一开始无法访问它。 botocore SDK 在尝试访问对象时抛出 An error occurred (403) when calling the HeadObject operation: Forbidden。在几分钟内(通过 SQS)重复调用 Lambda(甚至超过 50 次)会产生相同的错误。但是,当使用不同的 SQS 消息(从 S3 加载不同的对象)调用 Lambda,然后使用原始消息重新调用时,Lambda 可以突然访问 S3 对象(以前每次都失败)。随后从 Lambda 访问此对象的所有尝试都会成功。
我不知道是什么原因造成的。这个可重复的 3 步过程 (1) 在新上传的对象上失败,2) 与其他对象一起运行 3) 在原始对象上成功)可以全部发生在一个 Lambda 容器上(它们都在一个 CloudWatch 日志流中,这似乎与 Lambda 容器相关联)。所以,这似乎不是因为需要一个新的 Lambda 容器/实例。
关于如何进一步调试的想法或想法?
【问题讨论】:
-
我不确定是什么导致了这个问题,但我会推荐一种不同的方式来设置访问权限。您应该直接在分配给 AWS Lambda 函数的 IAM 角色中授予 S3 权限,而不是使用存储桶策略授予对 IAM 角色的访问权限。存储桶策略应该不参与此过程。存储桶策略通常用于授予公共或广泛的访问权限,而不是授予特定用户/角色的访问权限。
-
@JohnRotenstein 谢谢,这有助于了解。我检查了 IAM 角色(原来它已经拥有 S3 访问权限)并删除了存储桶策略。行为与以前相同(包括不一致的禁止错误),但这简化了我的设置。
-
这听起来有点像eventual consistency 问题,但这不应该发生在新对象上。您能否向我们展示一些最少的代码,以便我们尝试重现该问题?
-
在尝试创建一个最小的可重现示例时,当我直接使用
boto3时,我没有得到问题。主要代码库使用s3fs来获取对象,所以这可能是问题 -
哦!你没有提到你正在使用
s3fs。 Amazon S3 是对象存储系统,而不是文件系统。不建议使用s3fs之类的工具将 S3 作为文件系统“挂载”,尤其是用于生产用途。最好直接调用AWS API。
标签: python amazon-s3 aws-lambda python-s3fs