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

Dav*_*yan 21 azure azure-storage azure-storage-blobs

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

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

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

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

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

  4. 使用现有工具 - 没有发现任何有趣的东西.

关于这种方法的任何建议?

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

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

Dre*_*ker 11

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

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

安装完成后,你会在AzCopy.exe这里找到:%PROGRAMFILES(X86)%\Microsoft SDKs\Windows Azure\AzCopy

您可以在此博客文章中获得有关使用AzCopy的更多信息:AzCopy - 使用跨帐户复制Blob

同样,您可以远程桌面到实例并使用此实用程序进行传输.

更新:

您也可以使用Microsoft Azure Storage Explorer在存储帐户之间复制blob数据.参考链接

  • @MarcCliment感谢您使用当前信息进行更新 (2认同)

Dav*_*gon 9

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

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

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

更新 - 2012年6月12日,Windows Azure存储API已更新,现在允许跨帐户blob复制.有关所有详细信息,请参阅此博客文章.


ben*_*uin 6

以下是一些利用.NET SDK for Azure的代码,可从http://www.windowsazure.com/en-us/develop/net获取

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);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)