阿里云服务器上的文件迁移到阿里云OSS

时间:2024-04-17 08:50:10

一个图片采集的项目,每天会有差不多2-5G的文件上传到服务器,项目初期直接把上传的图片存在服务器本地。

经过差不多3个月后发现购买的数据盘已经满了,不得不重新扩容和添加数据盘,比较麻烦而且服务器带宽不大,用户查看图片比较慢。

重新改了系统架构,把图片存储迁移到了阿里云OSS。好处就是不用担心数据盘不够用,带宽也足够,只是费用高了一点。

云服务器上的存储路径为:/data/日期/文件这种结构,迁移到Oss后基本路径保持不变。

因为服务器上centos的,使用官方推荐的ossimport2进行迁移,ossimport2使用教程参考官方教程即可。

迁移完成之后,用户需要进行对比一下看是否全部完成。对比试了两种方案,

1.使用本地文件组合成object key一个一个去对比

这种方式比较慢,而且容易出现网络错误,

// 创建OSSClient实例
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
// Object是否存在
boolean found = ossClient.doesObjectExist("<bucketName>", "<key>")

2.把OSS服务器上的文件数据同步下来,在本地进行比较(推荐)

 这种方式就是稍微麻烦,需要建立一个数据库来存储同步下来的数据。

  •  创建数据库表
CREATE TABLE `dcs` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `path` varchar(255) DEFAULT NULL,
  `dates` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  •  编写数据库操作代码
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.sql2o</groupId>
    <artifactId>sql2o</artifactId>
    <version>1.5.4</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.29</version>
</dependency>
public class DbUtils {
    private static Sql2o SQL = new Sql2o("jdbc:mysql://127.0.0.1:3306/oss", "root", "root");;
    public static void bachInsert(List<OSSObjectSummary> sums) {
        String insertSql = "insert into dcs(path,dates) values (:path,:dates)";
        try (Connection con = SQL.beginTransaction()) {
            Query query = con.createQuery(insertSql);
            for (OSSObjectSummary s : sums) {
                String path = s.getKey();
                if (path.length() < 20){
                  System.out.println(path);
                  continue;
                }
                query.addParameter("dates",path.substring(11, 19));
                query.addParameter("path", path.substring(20)).addToBatch();
            }
            query.executeBatch(); // executes entire batch
            con.commit();
        }
    }
}
  • 编写同步代码
public class OssSynchClient {
    // log
    private static final Logger LOG = LoggerFactory.getLogger(OssSynchClient.class);
    // 阿里云API的内或外网域名
    private static String ENDPOINT = "<ENDPOINT>";
    // 阿里云API的密钥Access Key ID
    private static String ACCESS_KEY_ID = "<ACCESS_KEY_ID>";
    // 阿里云API的密钥Access Key Secret
    private static String ACCESS_KEY_SECRET = "<ACCESS_KEY_SECRET>";
    private static String BUCKET_NAME = "<BUCKET_NAME>";
    private OSSClient client;
    public OssSynchClient() {
        client = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }
    public void synchFromOssServer() {
        final int maxKeys = 200;
        final String keyPrefix = "<keyPrefix>";
        String nextMarker = null;
        ObjectListing objectListing;
        do {
            objectListing = client.listObjects(new ListObjectsRequest(BUCKET_NAME).withPrefix(keyPrefix)
                    .withMarker(nextMarker).withMaxKeys(maxKeys));
            List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
            DbUtils.bachInsert(sums);
            nextMarker = objectListing.getNextMarker();
        } while (objectListing.isTruncated());
    }
    
    public static void main(String[] args) {
        OssSynchClient osc = new OssSynchClient();
        osc.synchFromOssServer();
    }
}
  • 数据库对比
###dcs为同步下来的数据
###pic_mdf 为本地服务器数据
SELECT p.md,p.path FROM pic_mdf p WHERE NOT EXISTS(SELECT 1 FROM dcs d WHERE d.path = p.md)

由此可以过滤出没有同步到OSS的图片,然后调用oss上传api单独处理下即可。