I have somewhere around 4.2 million images that I need to move from the North Central USA to the Western USA, as part of a large migration, to take advantage of Azure VM support (for those who don’t know, North Central US does not support them ) Images all in one container, divided into approximately 119,000 directories.
I use the following from the Copy Blob API:
public static void CopyBlobDirectory(
CloudBlobDirectory srcDirectory,
CloudBlobContainer destContainer)
{
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;
ICloudBlob destBlob;
if (srcBlob.Properties.BlobType == BlobType.BlockBlob)
destBlob = destContainer.GetBlockBlobReference(srcBlob.Name);
else
destBlob = destContainer.GetPageBlobReference(srcBlob.Name);
destBlob.BeginStartCopyFromBlob(new Uri(srcBlob.Uri.AbsoluteUri + blobToken), null, null);
}
}
The problem is that it is too slow. Wahhhh too slow. At the speed that he takes to issue commands to copy all these things, He will go somewhere around four days. I'm not quite sure what the bottleneck is (limiting the client side of the connection, limiting the speed at the end of Azure, multithreading, etc.).
, , . , , ?
:
InitTracer();
var photos = PhotoHelper.GetAllPhotos().Take(500).ToList();
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");
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());
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);
BlobHelper.MonitorCopy(toContainer);
});
Trace.WriteLine("Done: " + DateTime.UtcNow.ToString());