使用Spark+Iceberg读取S3数据报错:需指定对应Endpoint
问题描述
使用PySpark结合Iceberg读取S3存储桶数据时触发301错误,已配置的Spark核心参数如下:
... conf.set("spark.jars.packages", "org.apache.iceberg:iceberg-spark-runtime-3.4_2.12:1.3.1,org.apache.iceberg:iceberg-spark-extensions-3.4_2.12:1.3.1,software.amazon.awssdk:bundle:2.20.145,software.amazon.awssdk:url-connection-client:2.20.145") conf.set("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") conf.set("spark.sql.catalog.spark_catalog", "org.apache.iceberg.spark.SparkSessionCatalog") conf.set("spark.sql.catalog.spark_catalog.type", "hive") conf.set("spark.sql.catalog.spark_catalog.io-impl", "org.apache.iceberg.aws.s3.S3FileIO") ...
收到的错误信息:
py4j.protocol.Py4JJavaError: An error occurred while calling o82.sql. : software.amazon.awssdk.services.s3.model.S3Exception: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint. (Service: S3, Status Code: 301, Request ID: ..., Extended Request ID: ...)
尝试过以下区域配置参数,但问题未解决:
conf.set("spark.hadoop.fs.s3.region", "eu-west-1") conf.set("spark.hadoop.fs.s3a.region", "eu-west-1") conf.set("spark.hadoop.fs.s3n.region", "eu-west-1") conf.set("spark.sql.catalog.spark_catalog.hadoop.fs.s3.region", "eu-west-1") conf.set("spark.sql.catalog.spark_catalog.hadoop.fs.s3a.region", "eu-west-1") conf.set("spark.sql.catalog.spark_catalog.hadoop.fs.s3n.region", "eu-west-1")
错误原因
这个301错误的核心是请求的S3端点与桶实际所在区域不匹配。当前使用的是Iceberg的S3FileIO,它直接调用AWS SDK而非Hadoop的S3A客户端,所以之前配置的Hadoop fs.s3*系列参数对Iceberg的文件IO层完全无效。
正确配置方案
针对Iceberg的S3FileIO,需要通过Iceberg catalog的专属前缀配置AWS相关参数:
1. 配置桶所在区域
添加以下Spark配置,直接为Iceberg catalog指定AWS区域:
conf.set("spark.sql.catalog.spark_catalog.aws.region", "eu-west-1")
2. 自定义S3兼容存储额外配置(可选)
如果是使用AWS S3之外的兼容存储(如MinIO、Ceph),还需显式指定端点,并开启路径风格访问:
# 指定自定义S3端点 conf.set("spark.sql.catalog.spark_catalog.s3.endpoint", "https://your-s3-compatible-endpoint.com") # 开启路径风格访问(非AWS S3通常需要这个) conf.set("spark.sql.catalog.spark_catalog.s3.path-style-access", "true")
3. 权限验证(可选)
确保Spark应用拥有访问目标桶的权限,可通过以下方式配置:
- IAM角色(推荐,适用于云环境):为Spark所在节点绑定具有S3访问权限的IAM角色
- Spark配置参数:直接在conf中设置密钥(仅测试环境使用)
conf.set("spark.sql.catalog.spark_catalog.aws.access-key-id", "your-access-key") conf.set("spark.sql.catalog.spark_catalog.aws.secret-access-key", "your-secret-key")
内容的提问来源于stack exchange,提问作者micmia
相关产品推荐
相关产品推荐

