将存储数据从一个Azure帐户复制到另一个Azure帐户

时间:2011-12-20 21:19:31

标签: azure azure-storage azure-storage-blobs

我想将一个非常大的存储容器从一个Azure存储帐户复制到另一个帐户(这也恰好在另一个订阅中)。

我想就以下选项发表意见:

  1. 编写一个工具,使用CloudBlob的DownloadToStream()和UploadFromStream()一次连接两个存储帐户并复制一个blob。这似乎是最糟糕的选择,因为它会在传输数据时产生成本,而且速度很慢,因为数据必须归结为运行该工具的机器,然后重新上传回Azure。

  2. 写一个工人角色来做同样的事情 - 理论上这应该更快,不会产生任何费用。但是,这是更多的工作。

  3. 将工具上传到正在运行的实例,绕过辅助角色部署,并在实例被回收/重置之前祈祷工具完成。

  4. 使用现有工具 - 未找到任何有趣的内容。

  5. 有关方法的任何建议吗?

    更新:我刚刚发现,2012年7月7日或之后创建的所有存储帐户最终都引入了此功能(目前仅为REST API):

    http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx

10 个答案:

答案 0 :(得分:11)

您还可以使用属于Azure SDK的AzCopy。

只需点击Windows Azure SDK的下载按钮,然后从列表中选择WindowsAzureStorageTools.msi即可下载AzCopy。

安装完成后,您会在此处找到AzCopy.exe%PROGRAMFILES(X86)%\Microsoft SDKs\Windows Azure\AzCopy

您可以在此博客文章中获取有关使用AzCopy的更多信息:AzCopy – Using Cross Account Copy Blob

同样,您可以将桌面远程安装到实例中并使用此实用程序进行传输。

<强>更新

您还可以使用 Microsoft Azure Storage Explorer 在存储帐户之间复制blob数据。参考link

答案 1 :(得分:9)

由于没有直接的方法将数据从一个存储帐户迁移到另一个存储帐户,因此您需要执行类似您的想法。如果这是在同一个数据中心内,选项#2是最好的选择,并且将是最快的(特别是如果您使用XL实例,为您提供更多的网络带宽)。

就复杂性而言,在工作者角色中创建此代码并不比使用本地应用程序更难。只需从您的worker角色的Run()方法运行此代码。

为了使功能更强大,您可以在容器中列出blob,然后将特定的文件移动请求消息放入Azure队列(并通过为每个消息放置多个对象名进行优化)。然后使用辅助角色线程从队列中读取并处理对象。即使您的角色被回收,最坏的情况下您也会重新处理一条消息。为了提高性能,您可以扩展到多个辅助角色实例。传输完成后,您只需拆除部署。

更新 - 2012年6月12日,Windows Azure存储API已更新,现在允许跨帐户blob复制。有关所有详细信息,请参阅this blog post

答案 2 :(得分:6)

这里有一些代码利用了http://www.windowsazure.com/en-us/develop/net

提供的.NET SDK for Azure
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using System.Net;

namespace benjguinAzureStorageTool
{
    class Program
    {
        private static Context context = new Context();

        static void Main(string[] args)
        {
            try
            {
                string usage = string.Format("Possible Usages:\n"
                + "benjguinAzureStorageTool CopyContainer account1SourceContainer account2SourceContainer account1Name account1Key account2Name account2Key\n"
                );


                if (args.Length < 1)
                    throw new ApplicationException(usage);

                int p = 1;

                switch (args[0])
                {
                    case "CopyContainer":
                        if (args.Length != 7) throw new ApplicationException(usage);
                        context.Storage1Container = args[p++];
                        context.Storage2Container = args[p++];
                        context.Storage1Name = args[p++];
                        context.Storage1Key = args[p++];
                        context.Storage2Name = args[p++];
                        context.Storage2Key = args[p++];

                        CopyContainer();
                        break;


                    default:
                        throw new ApplicationException(usage);
                }

                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("OK");
                Console.ResetColor();
            }
            catch (Exception ex)
            {
                Console.WriteLine();
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Exception: {0}", ex.Message);
                Console.ResetColor();
                Console.WriteLine("Details: {0}", ex);
            }
        }


        private static void CopyContainer()
        {
            CloudBlobContainer container1Reference = context.CloudBlobClient1.GetContainerReference(context.Storage1Container);
            CloudBlobContainer container2Reference = context.CloudBlobClient2.GetContainerReference(context.Storage2Container);
            if (container2Reference.CreateIfNotExist())
            {
                Console.WriteLine("Created destination container {0}. Permissions will also be copied.", context.Storage2Container);
                container2Reference.SetPermissions(container1Reference.GetPermissions());
            }
            else
            {
                Console.WriteLine("destination container {0} already exists. Permissions won't be changed.", context.Storage2Container);
            }


            foreach (var b in container1Reference.ListBlobs(
                new BlobRequestOptions(context.DefaultBlobRequestOptions)
                { UseFlatBlobListing = true, BlobListingDetails = BlobListingDetails.All }))
            {
                var sourceBlobReference = context.CloudBlobClient1.GetBlobReference(b.Uri.AbsoluteUri);
                var targetBlobReference = container2Reference.GetBlobReference(sourceBlobReference.Name);

                Console.WriteLine("Copying {0}\n to\n{1}",
                    sourceBlobReference.Uri.AbsoluteUri,
                    targetBlobReference.Uri.AbsoluteUri);

                using (Stream targetStream = targetBlobReference.OpenWrite(context.DefaultBlobRequestOptions))
                {
                    sourceBlobReference.DownloadToStream(targetStream, context.DefaultBlobRequestOptions);
                }
            }
        }
    }
}

答案 3 :(得分:3)

使用AzCopy非常简单。从https://azure.microsoft.com/en-us/documentation/articles/storage-use-azcopy/下载最新版本  并在azcopy类型: 在存储帐户中复制blob:

AzCopy /Source:https://myaccount.blob.core.windows.net/mycontainer1 /Dest:https://myaccount.blob.core.windows.net/mycontainer2 /SourceKey:key /DestKey:key /Pattern:abc.txt

将blob复制到存储帐户:

AzCopy /Source:https://sourceaccount.blob.core.windows.net/mycontainer1 /Dest:https://destaccount.blob.core.windows.net/mycontainer2 /SourceKey:key1 /DestKey:key2 /Pattern:abc.txt

从辅助区域复制blob

如果您的存储帐户启用了读访问地理冗余存储,则可以从辅助区域复制数据。

将blob从辅助帐户复制到主帐户:

AzCopy /Source:https://myaccount1-secondary.blob.core.windows.net/mynewcontainer1 /Dest:https://myaccount2.blob.core.windows.net/mynewcontainer2 /SourceKey:key1 /DestKey:key2 /Pattern:abc.txt

答案 4 :(得分:2)

我是微软技术推广人员,我开发了一个示例和免费工具(无支持/不保证)来帮助解决这些问题。

二进制文件和源代码可在此处获取:https://blobtransferutility.codeplex.com/

Blob Transfer Utility是一个GUI工具,用于向/从Windows Azure Blob存储上载和下载数千个小/大文件。

功能

  • 创建上传/下载批次
  • 设置内容类型
  • 并行传输文件
  • 将大型文件拆分为并行传输的较小部分

第一和第三个功能是您的问题的答案。

您可以从示例代码中了解我是如何做到的,或者您只需运行该工具并执行您需要执行的操作。

答案 5 :(得分:1)

将您的工具编写为简单的.NET命令行或Win Forms应用程序。

创建并部署启用了RDP的虚拟我/工作者角色

通过RDP登录本机

通过RDP连接复制工具

在远程计算机上运行该工具

删除已部署的角色。

和你一样,我不知道支持功能之间副本的任何现成工具。 您可能会考虑将Cloud Storage Studio安装到角色中,然后转储到磁盘然后重新上传。 http://cerebrata.com/Products/CloudStorageStudiov2/Details.aspx?t1=0&t2=7

答案 6 :(得分:1)

使用'Azure Storage Explorer'(免费)或其他一些此类工具。这些工具提供了下载和上传内容的方法。您将需要手动创建容器和表格 - 当然这将产生转移成本 - 但如果您的时间很短且内容的大小合理,那么这是一个可行的选择。

答案 7 :(得分:0)

我必须做一些类似的工作,将600 GB的内容从本地文件系统移动到Azure存储。经过几次代码迭代后,我最终选择了“Azure存储资源管理器”并将其扩展为能够选择文件夹而不仅仅是文件,然后让它递归地钻入多个选定的文件夹,加载源/目标副本列表将项目语句放入Azure队列。然后在“Azure存储资源管理器”的上传部分中,在“队列”部分中从队列中提取并执行复制操作。

然后,我启动了10个“Azure存储资源管理器”工具实例,并从队列中拉出并执行复制操作。我能够在2天内移动600 GB的物品。在智能中添加以在文件上使用修改的时间戳,并使其跳过已从队列中复制的文件,如果它同步则不会添加到队列中。现在,我可以在整个内容库中的一两个小时内运行“更新”或同步。

答案 8 :(得分:0)

试试CloudBerry Explorer。它在订阅内和订阅之间复制blob。

要在订阅之间进行复制,请修改存储帐户容器从PrivatePublic Blob的访问权限。

复制过程需要几个小时才能完成。如果您选择重新启动计算机,则该过程将继续。通过检查时间戳刷新Azure管理UI中的目标存储帐户容器来检查状态,该值将更新,直到复制过程完成。

enter image description here

答案 9 :(得分:0)

我推荐使用 azcopy,您可以复制所有存储帐户、一个容器、一个目录或单个 blob。这是克隆所有存储帐户的示例:

azcopy copy 'https://{SOURCE_ACCOUNT}.blob.core.windows.net{SOURCE_SAS_TOKEN}' 'https://{DESTINATION_ACCOUNT}.blob.core.windows.net{DESTINATION_SAS_TOKEN}' --recursive

您可以从 Azure 门户获取 SAS 令牌。导航到存储帐户概览(源和目标),然后在侧导航中单击“共享访问 sigantura”并生成您自己的。

更多示例here