将数百万件物品从一个存储帐户转移到另一个存储帐户

本文关键字:存储 一个 转移 另一个 数百万 | 更新日期: 2023-09-27 18:02:07

我有大约420万张图片需要从美国中北部迁移到美国西部,作为利用Azure VM支持的大规模迁移的一部分(对于那些不知道的人来说,美国中北部不支持它们)。所有图像都在一个容器中,分成大约119,000个目录。

我使用下面的Copy Blob API:

public static void CopyBlobDirectory(
        CloudBlobDirectory srcDirectory,
        CloudBlobContainer destContainer)
{
    // get the SAS token to use for all blobs
    string blobToken = srcDirectory.Container.GetSharedAccessSignature(
        new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read |
                            SharedAccessBlobPermissions.Write,
            SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromDays(14)
        });
    var srcBlobList = srcDirectory.ListBlobs(
        useFlatBlobListing: true,
        blobListingDetails: BlobListingDetails.None).ToList();
    foreach (var src in srcBlobList)
    {
        var srcBlob = src as ICloudBlob;
        // Create appropriate destination blob type to match the source blob
        ICloudBlob destBlob;
        if (srcBlob.Properties.BlobType == BlobType.BlockBlob)
            destBlob = destContainer.GetBlockBlobReference(srcBlob.Name);
        else
            destBlob = destContainer.GetPageBlobReference(srcBlob.Name);
        // copy using src blob as SAS
        destBlob.BeginStartCopyFromBlob(new Uri(srcBlob.Uri.AbsoluteUri + blobToken), null, null);          
    }
}

问题是它太慢了。走得太慢了。按照发出命令复制所有这些东西的速度,大概需要四天左右的时间。我不太确定瓶颈是什么(客户端的连接限制,Azure端的速率限制,多线程等等)。

所以,我想知道我有什么选择。有没有什么办法可以加快速度,还是说我只是被一项需要四天才能完成的工作困住了?

编辑:我如何分发工作来复制所有内容

//set up tracing
InitTracer();
//grab a set of photos to benchmark this
var photos = PhotoHelper.GetAllPhotos().Take(500).ToList();
//account to copy from
var from = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(
    "oldAccount",
    "oldAccountKey");
var fromAcct = new CloudStorageAccount(from, true);
var fromClient = fromAcct.CreateCloudBlobClient();
var fromContainer = fromClient.GetContainerReference("userphotos");
//account to copy to
var to = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(
    "newAccount",
    "newAccountKey");
var toAcct = new CloudStorageAccount(to, true);
var toClient = toAcct.CreateCloudBlobClient();
Trace.WriteLine("Starting Copy: " + DateTime.UtcNow.ToString());
//enumerate sub directories, then move them to blob storage
//note: it doesn't care how high I set the Parallelism to,
//console output indicates it won't run more than five or so at a time
var plo = new ParallelOptions { MaxDegreeOfParallelism = 10 };
Parallel.ForEach(photos, plo, (info) =>
{
    CloudBlobDirectory fromDir = fromContainer.GetDirectoryReference(info.BuildingId.ToString());
    var toContainer = toClient.GetContainerReference(info.Id.ToString());
    toContainer.CreateIfNotExists();
    Trace.WriteLine(info.BuildingId + ": Starting copy, " + info.Photos.Length + " photos...");
    BlobHelper.CopyBlobDirectory(fromDir, toContainer, info);
    //this monitors the container, so I can restart any failed
    //copies if something goes wrong
    BlobHelper.MonitorCopy(toContainer);
});
Trace.WriteLine("Done: " + DateTime.UtcNow.ToString());

将数百万件物品从一个存储帐户转移到另一个存储帐户

异步blob复制操作将在同一个数据中心内非常快(最近我在大约1-2秒内将30GB vhd复制到另一个blob)。跨数据中心,操作是排队的,并且在没有SLA的备用容量上发生(请参阅本文,其中特别指出了这一点)

换个角度看:我在多个数据中心复制了同样的30GB VHD,花了大约1个小时。

我不知道您的图像大小,但假设平均图像大小为500K,您将看到大约2,000 GB。在我的示例中,我在大约一个小时内看到了30GB的吞吐量。外推,这将在大约(2000/30)= 60小时内估计您的2000 GB数据。同样,没有SLA。这只是一个最好的猜测。

还有人建议禁用Nagle的算法。这应该有助于更快地输出400万份拷贝命令,并使它们更快地排队。我不认为这对拷贝时间有任何影响。

这是一个很长的镜头,但我有一个类似的问题与表存储,其中小请求(我认为BeginStartCopyFromBlob应该)开始运行非常慢。这是内格尔算法(Nagle’s Algorithm)和延迟TCP ack(两种网络流量优化)的问题。更多详细信息,请参阅MSDN或这个家伙。

结果-关闭Nagle的算法-在执行任何Azure存储操作之前调用以下

ServicePointManager.UseNagleAlgorithm = false;

或者对于blob:

var storageAccount = CloudStorageAccount.Parse(connectionString);
ServicePoint blobServicePoint = ServicePointManager.FindServicePoint(account.BlobEndpoint);
blobServicePoint.UseNagleAlgorithm = false;

如果这是你的问题,我会很高兴知道!