我需要从美国中北部移动到美国西部的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);
}
}
问题是,它太慢了。 Waaaay太慢了。按照发布命令复制所有这些东西的速度,它将需要在四天左右的某个地方。我不确定瓶颈是什么(连接限制客户端,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());
答案 0 :(得分:2)
异步blob复制操作在同一个数据中心内会非常快(最近我在大约1-2秒内将30GB vhd复制到另一个blob)。在数据中心之间,操作排队并在没有SLA的情况下在备用容量中进行(请参阅this article,具体说明这一点)
为了说明这一点:我在数据中心内复制了相同的30GB VHD,花了大约1个小时。
我不知道您的图像尺寸,但假设平均图像尺寸为500K,那么您需要大约2,000 GB。在我的例子中,我看到大约一个小时的吞吐量为30GB。外推,估计大约(2000/30)= 60小时内的2000 GB数据。再一次,没有SLA。只是一个最好的猜测。
其他人建议禁用Nagle的算法。这应该有助于更快地推出400万个拷贝命令并使它们排队更快。我不认为它会对复制时间产生任何影响。
答案 1 :(得分:1)
这是一个很长的镜头,但我有一个类似的表存储问题,小的请求(我认为BeginStartCopyFromBlob
应该)开始运行非常缓慢。这是Nagle's Algorithm和delayed TCP acks的问题,这是对网络流量的两种优化。有关详细信息,请参阅MSDN或this guy。
Upshot - 关闭Nagle算法 - 在执行任何Azure存储操作之前调用以下 。
ServicePointManager.UseNagleAlgorithm = false;
或者只是blob:
var storageAccount = CloudStorageAccount.Parse(connectionString);
ServicePoint blobServicePoint = ServicePointManager.FindServicePoint(account.BlobEndpoint);
blobServicePoint.UseNagleAlgorithm = false;
很高兴知道这是不是你的问题!