[英]Moving Millions of items from one Storage Account to Another
我需要從美國中北部移動到美國西部的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());
異步blob復制操作在同一數據中心內將非常快(最近我在大約1-2秒內將30GB vhd復制到另一個blob)。 在數據中心之間,操作排隊並在沒有SLA的情況下在備用容量中進行(請參閱此文章 ,具體說明了這一點)
為了說明這一點:我在數據中心復制了相同的30GB VHD,花了大約1個小時。
我不知道你的圖像大小,但假設平均圖像尺寸為500K,你看大約2000 GB。 在我的例子中,我看到大約一個小時的吞吐量為30GB。 外推,估計大約(2000/30)= 60小時內的2000 GB數據。 再一次,沒有SLA。 只是一個最好的猜測。
其他人建議禁用Nagle的算法。 這應該有助於更快地推出400萬個拷貝命令並使它們排隊更快。 我不認為它會對復制時間產生任何影響。
這是一個很長的鏡頭,但我有一個類似的表存儲問題,小的請求(我認為BeginStartCopyFromBlob
應該是)開始運行非常緩慢。 這是Nagle算法和延遲TCP acks的問題 ,這是網絡流量的兩個優化。 有關詳細信息,請參閱MSDN或此人 。
Upshot - 關閉Nagle的算法 - 在執行任何Azure存儲操作之前調用以下內容。
ServicePointManager.UseNagleAlgorithm = false;
或者只是blob:
var storageAccount = CloudStorageAccount.Parse(connectionString);
ServicePoint blobServicePoint = ServicePointManager.FindServicePoint(account.BlobEndpoint);
blobServicePoint.UseNagleAlgorithm = false;
很高興知道這是不是你的問題!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.