对象存储实战:从本地文件系统迁移到 S3 兼容存储

Object Storage in Practice: Migrating from Local Filesystem to S3-Compatible Storage

| Lisa | 2026-09-02T14:59:42

项目之前把用户上传的文件存在本地磁盘,随着数据量增长和多实例部署的需求,迁移到了 MinIO 对象存储。

Migrated user file uploads from local filesystem to MinIO object storage to support data growth and multi-instance deployment.

我们项目之前用户上传的图片、文件都存在应用服务器的本地磁盘上。一开始没什么问题,但随着功能增加遇到了两个问题: 磁盘快满了,扩容不方便 要做多实例部署了,本地文件各实例不共享 评估了几个方案之后选了 MinIO,因为它兼容 S3 API,以后切换到阿里云 OSS 或 AWS S3 成本很低。 MinIO 部署 Docker 一条命令就起来了: docker run -d -p 9000:9000 -p 9001:9001 -v /data/minio:/data -e MINIO_ROOT_USER=admin -e MINIO_ROOT_PASSWORD=password123 minio/minio server /data --console-address ":9001" Java SDK 集成 <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>8.5.7</version> </dependency> @Service public class StorageService { private final MinioClient minioClient; public String upload(MultipartFile file) { String objectName = generateObjectName(file); minioClient.putObject(PutObjectArgs.builder() .bucket("uploads") .object(objectName) .stream(file.getInputStream(), file.getSize(), -1) .contentType(file.getContentType()) .build()); return getPublicUrl(objectName); } private String generateObjectName(MultipartFile file) { String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")); String uuid = UUID.randomUUID().toString().replace("-", ""); String ext = getExtension(file.getOriginalFilename()); return date + "/" + uuid + "." + ext; } } 迁移策略 迁移不能一步到位,分了三步: 新上传的文件写 MinIO,旧文件暂时不动 写个脚本把旧文件批量上传到 MinIO 更新数据库中的文件 URL,指向新地址 整个过程做到了零停机。 注意事项 文件名用 UUID 而不是原始文件名,避免中文和特殊字符问题 按日期分目录,避免单目录文件过多 设置合理的 bucket policy,公开读的资源不要求认证 大文件用分片上传,小文件直接上传


Migrated from local filesystem to MinIO object storage for data growth and multi-instance deployment support. Why MinIO S3-compatible API means easy future migration to cloud providers (AWS S3, Aliyun OSS). Migration Strategy New uploads go to MinIO Batch migrate old files Update database URLs Zero downtime throughout the process. Key practices: UUID filenames, date-based directory structure, proper bucket policies.

← Back to News