Spark用Magic Committer写S3遇AccessDeniedException求助
Spark Magic Committer写入S3触发AccessDenied(缺少listMultipartUploads权限)问题排查与解决
问题场景
在Spark作业中配置Magic Committer直接写入AWS S3,Spark参数配置如下:
val spark = SparkSession.builder .config("spark.master", "local[*]") .config("spark.hadoop.fs.s3a.committer.name", "magic") .config("spark.hadoop.fs.s3a.bucket.all.committer.magic.enabled", true) .getOrCreate
写入时触发403 AccessDenied异常,报错核心信息:
listMultipartUploads on test/xxxx/xxxxx com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: HJDADSZ7ESJBKD0Z; S3 Extended Request ID: K4AXY=; Proxy: null), S3 Extended Request ID: Ob0K4AXY=:AccessDenied at org.apache.hadoop.fs.s3a.S3AUtils.translateException(S3AUtils.java:249)
已配置的IAM权限策略:
{ "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*", "s3:PutObject", "s3:DeleteObject", "s3:ListMultipartUploads", "s3:ListMultipartUploadParts", "s3:ListBucketMultipartUploads", "s3:AbortMultipartUpload" ], "Resource": [ "arn:aws:s3:::artifacts/test", "arn:aws:s3:::artifacts/test/*" ] }
排查方向与解决建议
1. 核心问题:Bucket权限资源不匹配
从报错信息看,作业实际写入的是名为test的S3桶(路径test/xxxx/xxxxx),但IAM权限策略中配置的资源是artifacts/test及子路径,两者完全不匹配,导致权限校验失败。
2. 修正IAM权限策略
- 调整Resource范围:将权限指向实际写入的
test桶,注意s3:ListBucketMultipartUploads是Bucket级动作,必须包含Bucket的完整ARN(不能仅指定前缀),修正后的策略示例:
{ "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*", "s3:PutObject", "s3:DeleteObject", "s3:ListMultipartUploads", "s3:ListMultipartUploadParts", "s3:ListBucketMultipartUploads", "s3:AbortMultipartUpload" ], "Resource": [ "arn:aws:s3:::test", "arn:aws:s3:::test/*" ] }
3. 验证凭证有效性
- 如果是本地运行Spark作业,直接用AWS CLI测试当前凭证是否具备目标桶的权限:
aws s3api list-multipart-uploads --bucket test
如果返回AccessDenied,说明当前使用的凭证不是配置了上述权限的IAM角色,需检查本地凭证文件(~/.aws/credentials)或环境变量是否正确。
4. 版本兼容性检查
Magic Committer要求Hadoop版本≥3.1,Spark需适配对应Hadoop版本。如果使用的Hadoop版本过低,可能存在权限逻辑的兼容性问题,建议升级到符合要求的版本。
内容的提问来源于stack exchange,提问作者Ashit_Kumar
相关产品推荐
相关产品推荐

