Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying storage data from one Azure account to another

I would like to copy a very large storage container from one Azure storage account into another (which also happens to be in another subscription).

I would like an opinion on the following options:

  1. Write a tool that would connect to both storage accounts and copy blobs one at a time using CloudBlob's DownloadToStream() and UploadFromStream(). This seems to be the worst option because it will incur costs when transferring the data and also be quite slow because data will have to come down to the machine running the tool and then get re-uploaded back to Azure.

  2. Write a worker role to do the same - this should theoretically be faster and not incur any cost. However, this is more work.

  3. Upload the tool to a running instance bypassing the worker role deployment and pray the tool finishes before the instance gets recycled/reset.

  4. Use an existing tool - have not found anything interesting.

Any suggestions on the approach?

Update: I just found out that this functionality has finally been introduced (REST APIs only for now) for all storage accounts created on July 7th, 2012 or later:

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

like image 955
David Airapetyan Avatar asked Dec 20 '11 21:12

David Airapetyan


People also ask

How do I transfer data from one storage account to another in Azure?

Copy and move blobs from one container or storage account to another from the command line and in code. Use . NET, AzCopy, and Azure CLI to migrate files between Azure storage accounts.

Can we clone storage account in Azure?

You can copy blobs, directories, and containers between storage accounts by using the AzCopy v10 command-line utility.

Which tool can be used to move data between storage accounts in Azure?

AzCopy is a command-line tool for copying data to or from Azure Blob storage, Azure Files, and Azure Table storage, by using simple commands. The commands are designed for optimal performance. Using AzCopy, you can either copy data between a file system and a storage account, or between storage accounts.


5 Answers

You can also use AzCopy that is part of the Azure SDK.

Just click the download button for Windows Azure SDK and choose WindowsAzureStorageTools.msi from the list to download AzCopy.

After installing, you'll find AzCopy.exe here: %PROGRAMFILES(X86)%\Microsoft SDKs\Windows Azure\AzCopy

You can get more information on using AzCopy in this blog post: AzCopy – Using Cross Account Copy Blob

As well, you could remote desktop into an instance and use this utility for the transfer.

Update:

You can also copy blob data between storage accounts using Microsoft Azure Storage Explorer as well. Reference link

like image 178
Dreamwalker Avatar answered Sep 22 '22 16:09

Dreamwalker


Since there's no direct way to migrate data from one storage account to another, you'd need to do something like what you were thinking. If this is within the same data center, option #2 is the best bet, and will be the fastest (especially if you use an XL instance, giving you more network bandwidth).

As far as complexity, it's no more difficult to create this code in a worker role than it would be with a local application. Just run this code from your worker role's Run() method.

To make things more robust, you could list the blobs in your containers, then place specific file-move request messages into an Azure queue (and optimize by putting more than one object name per message). Then use a worker role thread to read from the queue and process objects. Even if your role is recycled, at worst you'd reprocess one message. For performance increase, you could then scale to multiple worker role instances. Once the transfer is complete, you simply tear down the deployment.

UPDATE - On June 12, 2012, the Windows Azure Storage API was updated, and now allows cross-account blob copy. See this blog post for all the details.

like image 35
David Makogon Avatar answered Sep 22 '22 16:09

David Makogon


here is some code that leverages the .NET SDK for Azure available at 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);
                }
            }
        }
    }
}
like image 23
benjguin Avatar answered Sep 20 '22 16:09

benjguin


Its very simple with AzCopy. Download latest version from https://azure.microsoft.com/en-us/documentation/articles/storage-use-azcopy/ and in azcopy type: Copy a blob within a storage account:

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

Copy a blob across storage accounts:

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

Copy a blob from the secondary region

If your storage account has read-access geo-redundant storage enabled, then you can copy data from the secondary region.

Copy a blob to the primary account from the secondary:

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
like image 32
Hafiz Arslan Avatar answered Sep 24 '22 16:09

Hafiz Arslan


I'm a Microsoft Technical Evangelist and I have developed a sample and free tool (no support/no guarantee) to help in these scenarios.

The binaries and source-code are available here: https://blobtransferutility.codeplex.com/

The Blob Transfer Utility is a GUI tool to upload and download thousands of small/large files to/from Windows Azure Blob Storage.

Features:

  • Create batches to upload/download
  • Set the Content-Type
  • Transfer files in parallel
  • Split large files in smaller parts that are transferred in parallel

The 1st and 3rd feature is the answer to your problem.

You can learn from the sample code how I did it, or you can simply run the tool and do what you need to do.

like image 34
Vitor Ciaramella Avatar answered Sep 23 '22 16:09

Vitor Ciaramella