将存储数据从一个 Azure 帐户复制到另一个
Posted
技术标签:
【中文标题】将存储数据从一个 Azure 帐户复制到另一个【英文标题】:Copying storage data from one Azure account to another 【发布时间】:2012-01-24 19:29:07 【问题描述】:我想将一个非常大的存储容器从一个 Azure 存储帐户复制到另一个帐户(恰好也在另一个订阅中)。
我想对以下选项发表意见:
编写一个工具,使用 CloudBlob 的 DownloadToStream() 和 UploadFromStream() 连接两个存储帐户并一次复制一个 Blob。这似乎是最糟糕的选择,因为它会在传输数据时产生成本,而且速度很慢,因为数据必须下降到运行该工具的机器上,然后重新上传回 Azure。
李>写一个工人角色来做同样的事情 - 理论上这应该更快并且不会产生任何成本。然而,这是更多的工作。
将工具上传到正在运行的实例,绕过辅助角色部署,并祈祷工具在实例被回收/重置之前完成。
使用现有工具 - 没有发现任何有趣的东西。
对方法有什么建议吗?
更新:我刚刚发现终于为 2012 年 7 月 7 日或之后创建的所有存储帐户引入了此功能(目前仅限 REST API):
http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx
【问题讨论】:
试试Azure Storage Synctool。 Azure Storage Synctool 有点原始 - 仅支持 Storage-to-local(这意味着我需要分两步完成,首先下载我的整个容器,然后重新上传它,这没什么大不了的),而且大多数情况下,它不会恢复-这可能有点问题。我们最终构建的自主解决方案(非常简单)支持恢复、存储到存储并在同一帐户上使用 CopyFromBlob。 【参考方案1】:由于没有直接的方法可以将数据从一个存储帐户迁移到另一个,因此您需要按照您的想法进行操作。如果这是在同一个数据中心内,选项 #2 是最好的选择,而且速度最快(特别是如果您使用 XL 实例,可以为您提供更多的网络带宽)。
就复杂性而言,以工作者角色创建此代码并不比使用本地应用程序更难。只需从您的辅助角色的 Run() 方法运行此代码即可。
为了使事情变得更加健壮,您可以列出容器中的 blob,然后将特定的文件移动请求消息放入 Azure 队列(并通过在每条消息中放置多个对象名称进行优化)。然后使用工作者角色线程从队列中读取并处理对象。即使您的角色被回收,最坏的情况是您会重新处理一条消息。为了提高性能,您可以扩展到多个工作角色实例。传输完成后,您只需拆除部署即可。
更新 - 2012 年 6 月 12 日,更新了 Windows Azure 存储 API,现在允许跨帐户 blob 复制。详情请见this blog post。
【讨论】:
要注意的一件有趣的事情是,如果容器在同一个存储帐户上(不幸的是,我不是这种情况),那么有一种方法可以在不经过客户端的情况下复制 blob - 不是确定是哪个 API 执行此操作,但在使用 Azure 存储资源管理器进行复制时运行 Fiddler 会显示 x-ms-copy-source 标头。 好的,它叫做“CopyFromBlob”。可以检查源帐户是否与目标帐户匹配并使用该方法,否则使用 DownloadToStream/UploadToStream 组合。【参考方案2】:将您的工具编写为简单的 .NET 命令行或 Win Forms 应用程序。
在启用 RDP 的情况下创建和部署一个虚拟的 we/worker 角色
通过 RDP 登录机器
通过 RDP 连接复制您的工具
在远程机器上运行该工具
删除已部署的角色。
和你一样,我不知道有任何现成的工具支持功能之间的复制。 您可能想考虑将 Cloud Storage Studio 安装到角色中,然后转储到磁盘然后重新上传。 http://cerebrata.com/Products/CloudStorageStudiov2/Details.aspx?t1=0&t2=7
【讨论】:
不确定您为什么要提出 RDP。除了需要手动操作之外,您还需要使用您的部署部署您的 WinForms 应用程序。运行简单任务的简单工作者角色更简单,并且可以扩展到多个实例以获得更快的性能。 原始发帖人特别指出,他发现写一个“工具”比写一个工人角色更快。同意我通常会写一个工人来做这件事,但在这种情况下,我试图提供一个注意这个约束的答案。您不需要部署 WInForms 应用程序;从字面上看,您只需将其拖过 RDP 链接,就像您连接并使用本地服务器一样。 实际上,我最终做了很多事情 - 将我的 WinForm 复制粘贴到一个正在运行的 Web 角色中,然后从那里运行它。即使它在那里运行,它仍然不是闪电般快:复制大约 400,000 个项目(主要是中型 jpeg)需要大约 22 小时 - 价值 46.5GB 的数据 - 我本来预计它会快得多(不再超过 5 小时)。【参考方案3】:这里有一些利用 .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\n1",
sourceBlobReference.Uri.AbsoluteUri,
targetBlobReference.Uri.AbsoluteUri);
using (Stream targetStream = targetBlobReference.OpenWrite(context.DefaultBlobRequestOptions))
sourceBlobReference.DownloadToStream(targetStream, context.DefaultBlobRequestOptions);
【讨论】:
谢谢!我已经编写了解决方案,但是看到一些代码共享出来总是很高兴。另外,我正在创建一个 MemoryStream - 在目标 blob 上执行 OpenWrite() 更简洁(也更高效)。【参考方案4】:可以使用“Azure 存储资源管理器”(免费)或其他类似工具。这些工具提供了一种下载和上传内容的方法。您将需要手动创建容器和表格 - 当然这会产生转移成本 - 但如果您时间紧迫且内容大小合理,那么这是一个可行的选择。
【讨论】:
如最初所述,我必须复制的容器非常大 - Azure 存储资源管理器在这种情况下表现不佳。我最终编写了一个自定义工具 - 它非常简单 - 我从 Azure Web 角色运行它以避免转移成本。【参考方案5】:我不得不做一些类似的事情,将 600 GB 的内容从本地文件系统移动到 Azure 存储。经过几次代码迭代后,我最终采用了“Azure 存储资源管理器”并将其扩展为选择文件夹而不仅仅是文件的能力,然后让它递归地钻入多个选定的文件夹,加载源/目标副本列表将项目语句放入 Azure 队列。然后在“Azure 存储资源管理器”的上传部分,在队列部分从队列中拉取并执行复制操作。
然后我启动了大约 10 个“Azure 存储资源管理器”工具实例,每个实例都从队列中拉出并执行复制操作。我能够在短短 2 天内移动 600 GB 的物品。添加了智能以利用文件上修改后的时间戳,并让它跳过已经从队列中复制的文件,如果同步则不添加到队列中。现在,我可以在一两个小时内跨整个内容库运行“更新”或同步。
【讨论】:
【参考方案6】:我是 Microsoft 技术布道者,我开发了一个示例和免费工具(不支持/不保证)来帮助解决这些情况。
二进制文件和源代码可在此处获得:https://blobtransferutility.codeplex.com/
Blob 传输实用程序是一个 GUI 工具,用于向/从 Windows Azure Blob 存储上传和下载数千个小/大文件。
特点:
创建要上传/下载的批次 设置内容类型 并行传输文件 将大文件拆分为并行传输的较小部分第一个和第三个功能是您问题的答案。
您可以从示例代码中了解我是如何做到的,或者您可以简单地运行该工具并做您需要做的事情。
【讨论】:
【参考方案7】:您还可以使用 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 存储资源管理器 在存储帐户之间复制 blob 数据。参考link
【讨论】:
【参考方案8】:使用 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
【讨论】:
【参考方案9】:试试CloudBerry Explorer。它在订阅内和订阅之间复制 blob。
要在订阅之间进行复制,请将存储帐户容器的访问权限从 Private
编辑为 Public Blob
。
复制过程需要几个小时才能完成。如果您选择重新启动计算机,该过程将继续。通过检查时间戳刷新 Azure 管理 UI 中的目标存储帐户容器来检查状态,直到复制过程完成,值才会更新。
【讨论】:
【参考方案10】:我推荐使用azcopy,你可以复制所有的存储帐户、一个容器、一个目录或单个blob。以下是克隆所有存储帐户的示例:
azcopy copy 'https://SOURCE_ACCOUNT.blob.core.windows.netSOURCE_SAS_TOKEN' 'https://DESTINATION_ACCOUNT.blob.core.windows.netDESTINATION_SAS_TOKEN' --recursive
您可以从 Azure 门户获取 SAS 令牌。导航到存储帐户概述(源和目标),然后在 sidenav 中单击“共享访问信号”并生成您自己的。
更多例子here
【讨论】:
以上是关于将存储数据从一个 Azure 帐户复制到另一个的主要内容,如果未能解决你的问题,请参考以下文章
Azure Blob 存储:防止 Blob 复制到另一个存储帐户的最佳方法?
如何将 Azure 存储帐户内容(表、队列、blob)复制到其他存储帐户
将 VHD 从 azure 磁盘复制到 azure 存储帐户