5

Tôi có một nơi nào đó trong khu phố có 4,2 triệu hình ảnh tôi cần chuyển từ Bắc Trung Hoa sang Tây Hoa Kỳ, như một phần của di chuyển lớn để tận dụng hỗ trợ Azure VM (những người không biết, Bắc Trung Mỹ không ủng hộ họ). Các hình ảnh này đều nằm trong một thùng chứa, được chia thành khoảng 119.000 thư mục.Di chuyển hàng triệu mặt hàng từ một tài khoản lưu trữ sang một số khác

Tôi đang sử dụng sau đây từ API Sao chép Blob:

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);   
    } 
} 

Vấn đề là, đó là quá chậm. Waaaay quá chậm. Với tốc độ, nó sẽ đưa ra các lệnh để sao chép tất cả những thứ này, Nó sẽ diễn ra ở đâu đó trong khu phố bốn ngày. Tôi không thực sự chắc chắn những gì nút cổ chai là (kết nối giới hạn phía khách hàng, tỷ lệ hạn chế về kết thúc của Azure, đa luồng, vv).

Vì vậy, tôi tự hỏi tùy chọn của tôi là gì. Có cách nào để tăng tốc độ, hay tôi chỉ bị mắc kẹt với một công việc sẽ mất bốn ngày để hoàn thành?

Chỉnh sửa: Làm thế nào tôi đang phân phối các công việc sao chép tất cả mọi thứ

//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

Bạn đang sử dụng rất nhiều chủ đề để làm điều đó? Hầu hết thời gian là trong việc sao chép. Bạn có thể song song nó rất nhiều tôi nghĩ. Có lẽ với một loạt các vai trò công nhân trên azure. –

+0

Tôi cũng có suy nghĩ tương tự; ban đầu tôi đã chạy tất cả đồng bộ. Sau một số thử nghiệm, nó sẽ mất gần hai tuần, vì vậy tôi viết lại nó để sử dụng BeginStartCopyFromBlob(), và gói các cuộc gọi đến CopyBlobDirectory() trong một Parallel.ForEach.Tuy nhiên, khung công tác song song từ chối cho phép tôi chạy hơn 5 hoặc nhiều công việc cùng một lúc (ngay cả khi tôi đặt mức độ cao hơn); Tôi không chắc làm thế nào để buộc nó chạy nhiều hơn. – Dusda

+0

Bạn có thể chỉ sinh ra rất nhiều chủ đề như thế này: http://stackoverflow.com/questions/5041153/how-to-create-multiple-threads-in-windows-azure-worker-role, nói 1000 cho mỗi trường hợp công nhân và sau đó quay lên vài chục vai trò công nhân? –

Trả lời

1

Đây là một chút một shot dài, nhưng tôi đã có một vấn đề tương tự với lưu trữ bảng theo đó yêu cầu nhỏ (mà tôi nghĩ BeginStartCopyFromBlob nên) bắt đầu chạy rất chậm. Đó là sự cố với Nagle's Algorithmdelayed TCP acks, hai tối ưu hóa cho lưu lượng truy cập mạng. Xem MSDN hoặc this guy để biết thêm chi tiết.

Upshot - tắt thuật toán của Nagle off - gọi sau trước khi thực hiện bất kỳ hoạt động lưu trữ Azure nào.

ServicePointManager.UseNagleAlgorithm = false; 

Hoặc chỉ blob:

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

Sẽ là tuyệt vời biết nếu đó là vấn đề của bạn!

+0

Thử cách này; dường như đã cho nó một shot adrenaline cho đến nay :). – Dusda

+0

Chỉ cần nhớ rằng thao tác sao chép không truyền dữ liệu giữa bộ nhớ và thể hiện tính toán của bạn; đây là bản sao lưu trữ, không đồng bộ. Cải tiến duy nhất bạn sẽ thấy, biến Nagle ra trong trường hợp này, là tốc độ mà tại đó mỗi lệnh sao chép riêng lẻ được gửi/hoàn thành. Điều này sẽ cho phép bạn gửi lệnh nhanh hơn. –

+0

Vâng, được rồi. Vấn đề ban đầu là tìm ra lý do tại sao mất quá nhiều thời gian để gửi yêu cầu. Bạn sẽ xảy ra để biết phải mất bao lâu để Azure thực sự thực hiện các bản sao blob? Nói, một nhóm 1.000 đốm màu? – Dusda

2

Thao tác copy blob không đồng bộ sẽ rất nhanh trong cùng một trung tâm dữ liệu (gần đây tôi đã sao chép vhd 30 GB sang một đốm màu khác trong khoảng 1-2 giây). Trên các trung tâm dữ liệu, hoạt động được xếp hàng đợi và xảy ra trên công suất dự phòng không có SLA (xem this article gọi là đặc biệt)

Để sao chép cùng một VHD 30GB trên các trung tâm dữ liệu và mất khoảng 1 giờ.

Tôi không biết kích thước hình ảnh của bạn, nhưng giả sử kích thước hình ảnh trung bình 500K, bạn đang xem khoảng 2.000 GB. Trong ví dụ của tôi, tôi thấy thông lượng 30 GB trong khoảng một giờ. Ngoại suy, có thể ước tính 2000 GB dữ liệu của bạn trong khoảng (2000/30) = 60 giờ. Một lần nữa, không có SLA. Chỉ là một đoán tốt nhất.

Một người nào đó khác đã đề xuất tắt thuật toán của Nagle. Điều đó sẽ giúp đẩy nhanh 4 triệu lệnh sao chép nhanh hơn và khiến chúng xếp hàng nhanh hơn. Tôi không nghĩ rằng nó sẽ có tác dụng của thời gian sao chép.

Các vấn đề liên quan