将所有文件从Amazon S3存储桶复制到Microsoft Azure容器的最佳方法

时间:2015-04-21 01:30:17

标签: azure amazon-s3 migration backup

我需要将所有文件(例如100.000+视频文件)从Amazon S3存储桶复制(用于备份)到空的Azure Blob容器。 我们不是从亚马逊迁移到Azure,但我们想要备份,以防万一...

哪种方法最快?

我读过Azure能够从Amazon S3下载文件而无需传递本地计算机。这将是很好的,因为我们将节省大量的带宽和时间......

我也读过这个项目: https://github.com/kpfaulkner/azurecopy 但是我现在没有配备Windows操作系统的计算机(如果必须的话,我会考虑用它来设置虚拟机)。 有没有办法用MAC做到这一点? 或者从bash命令行?还是用PHP?

非常感谢

2 个答案:

答案 0 :(得分:0)

我有一个Java 8程序,为此...

该项目将使用Java 8在Netbeans 8.0.1中构建。首先,我们将创建一个新的Maven Java应用程序。 Maven将用于导入AWS和Azure SDK。

enter image description here

将您的项目命名为AWStoAzure,并将mycompany替换为典型的包系统。

enter image description here

打开Pom.xml和下面给出的pom。

我的程序的关键步骤涉及更多Amazon SDK功能,然后是Azure SDK。使用Amazon SDK我首先使用提供的公钥和私钥连接到我的Amazon帐户。

enter image description here

接下来,我检索位于给定存储桶中的所有文件的列表,并检索每个文件的元数据。

enter image description here

然后,我使用Java 8的新流功能启动多个线程,每个线程负责连接到Azure并启动文件传输过程。

enter image description here

Azure提供SDK作为SDK的一部分提供http(s)URL并将该URL中的数据加载到blob中。此SDK功能将大部分工作负载放在Azure上,并允许我的工具在将数据加载到blob时不必保持连接到任何云服务。

enter image description here

Amazon S3使用类似命名约定的文件夹,但是blob存储没有这个,所以我为S3中的每个文件夹创建包含。

enter image description here

亚马逊的SDK提供了生成URL的功能,该URL包含嵌入其中的帐户的用户名和密码。这允许我们将文件公开给Azure,但不必担心文件被打开到公共互联网。

enter image description here

包括我使用的POM文件。

Java Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.microsoft.azure.aws;

import com.amazonaws.HttpMethod;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.OperationContext;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Dan
 */
public class AzuretoAWSDriver {

    private static String connectionString = "";

    public static void run(String accessKey, String secretKey, String bucketName) {

        AmazonS3Client amazonS3Client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));

        amazonS3Client.listObjects(bucketName)
                .getObjectSummaries()
                .stream()
                .forEach(s3ObjectSummary
                        -> S3toBlob(amazonS3Client, s3ObjectSummary));
    }

    public static void S3toBlob(AmazonS3Client amazonS3Client, S3ObjectSummary s3ObjectSummary) {
        try {
            String[] split = s3ObjectSummary.getKey().split("/");
            GetContainer(s3ObjectSummary)
                    .getBlockBlobReference(split[split.length - 1])
                    .startCopyFromBlob(GetURL(amazonS3Client, s3ObjectSummary), null, null, null, new OperationContext());
        } catch (URISyntaxException | StorageException | InvalidKeyException ex) {
            Logger.getLogger(AzuretoAWSDriver.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private static CloudBlobContainer GetContainer(S3ObjectSummary s3ObjectSummary) throws URISyntaxException, InvalidKeyException, StorageException {
        String[] split = s3ObjectSummary.getKey().split("/");
        String folders = "";
        for (int i = 0; i < split.length - 2; i++) {
            folders += split[i];
        }
        CloudBlobContainer containerReference = CloudStorageAccount
                .parse(connectionString)
                .createCloudBlobClient()
                .getContainerReference(s3ObjectSummary.getBucketName() + folders);
        containerReference.createIfNotExists();
        return containerReference;
    }

    private static URI GetURL(AmazonS3Client amazonS3Client, S3ObjectSummary s3ObjectSummary) throws URISyntaxException {
        return amazonS3Client.generatePresignedUrl(
                new GeneratePresignedUrlRequest(s3ObjectSummary.getBucketName(), s3ObjectSummary.getKey())
                .withMethod(HttpMethod.GET)
                .withExpiration(GetExperation())).toURI();
    }

    private static Date GetExperation() {                     
        return new Date((new Date().getTime()) + 60 * 60 * 1000);
    }
}

的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.microsoft</groupId>
  <artifactId>AWStoAzure2</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>AWS SDK for Java Sample</name>
  <url>http://aws.amazon.com/sdkforjava</url>

  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk</artifactId>
      <version>[1.7.2,2.0.0)</version>
    </dependency>
    <dependency>  
     <groupId>com.microsoft.windowsazure.storage</groupId>
     <artifactId>microsoft-windowsazure-storage-sdk</artifactId>
     <version>1.1.0</version>
</dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
          <execution>
            <goals>
              <goal>java</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <mainClass>AwsSdkSample</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
</project>

答案 1 :(得分:-3)

有些工具可以做你想做的事。谷歌的Cloud Data Migration

您可能需要考虑的另一件事是增量复制。例如,当您第二次启动复制任务时,您不希望再次复制所有对象,只需要添加/更新/删除对象。