Spark集成MLflow保存模型到S3报No FileSystem for scheme s3异常
问题根因
报错由两个版本兼容问题共同导致:
- MLflow 1.26.1客户端存在固定逻辑:拉取服务端返回的S3类型artifact路径时,会自动将
s3a://、s3n://前缀强制重写为s3://,哪怕服务端启动时配置的默认artifact根路径是s3a://开头也会触发这个重写。 - Hadoop 3.x版本已经完全移除了原生
s3://scheme对应的FileSystem实现,你当前的Spark配置只绑定了s3ascheme到S3AFileSystem,Spark的MLWriter拿到s3://开头的模型存储路径后找不到对应文件系统实现,直接抛出UnsupportedFileSystemException。
解决方案
按以下步骤操作即可解决,不需要升级现有组件版本:
- 补全Spark侧的scheme兼容配置:在你现有的spark-submit参数基础上,新增一条配置把
s3scheme直接映射到已经配置好的S3AFileSystem实现,从Spark层兜底路径兼容:
--conf spark.hadoop.fs.s3.impl=org.apache.hadoop.fs.s3a.S3AFileSystem
加完这条后,不管传入的路径是s3://还是s3a://开头,Spark都会走S3A逻辑访问存储,不会再去找已经被移除的原生s3文件系统实现。
这个配置是Hadoop官方支持的S3兼容方案,不需要引入额外旧版依赖,没有兼容性风险。
- 补全MLflow客户端侧配置,不要只在MLflow服务端设置默认artifact根路径:
- 在提交Spark作业前,配置S3访问对应的环境变量——MLflow自身上传小体积artifact(比如指标、参数文件)走boto3客户端,不会读取Spark的Hadoop配置链,必须单独给凭证:
export AWS_ACCESS_KEY_ID=<你的S3 AK> export AWS_SECRET_ACCESS_KEY=<你的S3 SK> # 如果你用的是私有S3兼容存储(比如MinIO、云厂商自建对象存储),额外加这行 export MLFLOW_S3_ENDPOINT_URL=<你的S3服务访问地址> - 新建MLflow实验时,显式指定
s3a://开头的artifact存储路径,不要依赖服务端默认值,进一步减少路径被重写的概率:import mlflow mlflow.create_experiment( name="你的实验名", artifact_location="s3a://<你的S3桶名>/<实验 artifact 存储前缀>" )
- 在提交Spark作业前,配置S3访问对应的环境变量——MLflow自身上传小体积artifact(比如指标、参数文件)走boto3客户端,不会读取Spark的Hadoop配置链,必须单独给凭证:
- 校验依赖包:你当前引入的
hadoop-aws-3.2.2.jar、aws-java-sdk-bundle-1.11.375.jar和Spark 3.2.1自带的Hadoop 3.2.x版本完全匹配,不需要替换。如果使用私有S3兼容存储,额外加一条Spark配置即可:--conf spark.hadoop.fs.s3a.path.style.access=true
验证说明
配置完成后重跑作业:
- 哪怕
mlflow.get_artifact_uri()返回的路径还是s3://前缀也属于正常现象,因为Spark侧已经做了scheme映射,会正常写入S3。 - 作业运行成功后,可以直接在S3存储的对应路径下看到模型文件,MLflow UI也能正常加载模型和artifact列表。
内容的提问来源于stack exchange,提问作者Peanut
相关产品推荐
相关产品推荐

