2012-10-05 30 views
9

Tôi viết WorkerRole đơn giản để thêm dữ liệu thử vào bảng. Mã chèn là như thế này.Cách tăng thêm 10 lần chèn mỗi giây với bảng lưu trữ azure

var TableClient = this.StorageAccount.CreateCloudTableClient(); 
TableClient.CreateTableIfNotExist(TableName); 
var Context = TableClient.GetDataServiceContext(); 

this.Context.AddObject(TableName, obj); 
this.Context.SaveChanges(); 

Mã này chạy cho mỗi yêu cầu của khách hàng. Tôi thử nghiệm với 1-30 chủ đề khách hàng. Tôi có nhiều trys với số lượng khác nhau của các trường hợp kích cỡ khác nhau. Tôi không biết mình làm gì sai nhưng tôi không thể đạt tới 10 lần chèn mỗi giây. Nếu ai đó biết làm thế nào để tăng tốc độ xin vui lòng tư vấn cho tôi. Cảm ơn

CẬP NHẬT

  • sự loại bỏ của CreateTableIfNotExist does't làm cho sự khác biệt cho kiểm tra chèn của tôi.
  • chế độ chuyển đổi thành expect100Continue = "false" useNagleAlgorithm = "false" tạo hiệu ứng thời gian ngắn khi tốc độ chèn nhảy tới 30-40 ips. Nhưng sau đó, sau 30 giây tốc độ chèn giảm xuống còn 6 ips với thời gian chờ là 50%.
+1

Bạn có vô tình gọi tất cả logic đó với CreateTableIfNotExist() trong một vòng lặp không? hoặc chỉ Add/SaveChanges() trong một vòng lặp? CreateTableIfNotExist() không phải là một cuộc gọi giá rẻ và bạn muốn bỏ qua nó nếu nó không cần thiết – Igorek

+0

Mã này chạy cho mỗi yêu cầu. Bạn đang phải trả tiền để gọi CreateTableIfNotExist bất kỳ lúc nào. Tôi sẽ cố gắng loại bỏ nó và chỉ làm gì nếu bảng không tồn tại lỗi. – gabba

Trả lời

29

Để tăng tốc độ điều bạn nên sử dụng các giao dịch hàng loạt (Entity Nhóm giao dịch), cho phép bạn cam kết lên đến 100 mục trong một yêu cầu duy nhất:

foreach (var item in myItemsToAdd) 
{ 
    this.Context.AddObject(TableName, item); 
} 
this.Context.SaveChanges(SaveChangesOptions.Batch); 

Bạn có thể kết hợp này với Partitioner.Create (+ AsParallel) để gửi nhiều yêu cầu về các luồng/lõi khác nhau cho mỗi lô 100 mục để làm cho mọi thứ thực sự nhanh chóng.

Nhưng trước khi thực hiện tất cả việc này, read through the limitations sử dụng giao dịch hàng loạt (100 mục, 1 phân vùng cho mỗi giao dịch, ...).

Cập nhật:

Vì bạn không thể sử dụng giao dịch ở đây là một số mẹo khác. Hãy xem this MSDN thread về cải thiện hiệu suất khi sử dụng bộ nhớ bảng. Tôi đã viết một số mã để cho bạn thấy sự khác biệt:

private static void SequentialInserts(CloudTableClient client) 
    { 
     var context = client.GetDataServiceContext(); 
     Trace.WriteLine("Starting sequential inserts."); 

     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     for (int i = 0; i < 1000; i++) 
     { 
      Trace.WriteLine(String.Format("Adding item {0}. Thread ID: {1}", i, Thread.CurrentThread.ManagedThreadId)); 
      context.AddObject(TABLENAME, new MyEntity() 
      { 
       Date = DateTime.UtcNow, 
       PartitionKey = "Test", 
       RowKey = Guid.NewGuid().ToString(), 
       Text = String.Format("Item {0} - {1}", i, Guid.NewGuid().ToString()) 
      }); 
      context.SaveChanges(); 
     } 

     stopwatch.Stop(); 
     Trace.WriteLine("Done in: " + stopwatch.Elapsed.ToString()); 
    } 

Vì vậy, lần đầu tiên tôi chạy này tôi nhận được kết quả như sau:

Starting sequential inserts. 
Adding item 0. Thread ID: 10 
Adding item 1. Thread ID: 10 
.. 
Adding item 999. Thread ID: 10 
Done in: 00:03:39.9675521 

Phải mất hơn 3 phút để thêm 1000 mặt hàng. Bây giờ, tôi đã thay đổi app.config dựa trên những lời khuyên trên diễn đàn MSDN (maxconnection nên 12 * số lõi CPU):

<system.net> 
    <settings> 
     <servicePointManager expect100Continue="false" useNagleAlgorithm="false"/> 
    </settings> 
    <connectionManagement> 
     <add address = "*" maxconnection = "48" /> 
    </connectionManagement> 
    </system.net> 

Và sau khi chạy ứng dụng một lần nữa tôi nhận được kết quả này:

Starting sequential inserts. 
Adding item 0. Thread ID: 10 
Adding item 1. Thread ID: 10 
.. 
Adding item 999. Thread ID: 10 
Done in: 00:00:18.9342480 

Từ trên 3 phút đến 18 giây. Thật la khac biệt! Nhưng chúng ta có thể làm tốt hơn nữa. Dưới đây là một số mã chèn tất cả các mục sử dụng một phân vùng (chèn sẽ xảy ra song song):

private static void ParallelInserts(CloudTableClient client) 
    {    
     Trace.WriteLine("Starting parallel inserts."); 

     var stopwatch = new Stopwatch(); 
     stopwatch.Start(); 

     var partitioner = Partitioner.Create(0, 1000, 10); 
     var options = new ParallelOptions { MaxDegreeOfParallelism = 8 }; 

     Parallel.ForEach(partitioner, options, range => 
     { 
      var context = client.GetDataServiceContext(); 
      for (int i = range.Item1; i < range.Item2; i++) 
      { 
       Trace.WriteLine(String.Format("Adding item {0}. Thread ID: {1}", i, Thread.CurrentThread.ManagedThreadId)); 
       context.AddObject(TABLENAME, new MyEntity() 
       { 
        Date = DateTime.UtcNow, 
        PartitionKey = "Test", 
        RowKey = Guid.NewGuid().ToString(), 
        Text = String.Format("Item {0} - {1}", i, Guid.NewGuid().ToString()) 
       }); 
       context.SaveChanges(); 
      } 
     }); 

     stopwatch.Stop(); 
     Trace.WriteLine("Done in: " + stopwatch.Elapsed.ToString()); 
    } 

Và kết quả:

Starting parallel inserts. 
Adding item 0. Thread ID: 10 
Adding item 10. Thread ID: 18 
Adding item 999. Thread ID: 16 
.. 
Done in: 00:00:04.6041978 

Thì đấy, từ 3m39s chúng tôi giảm xuống còn 18s và bây giờ chúng tôi thậm chí giảm xuống 4s.

+0

Tôi cũng khuyên bạn nên thực hiện thao tác song song dưới dạng bảng phân vùng đơn lẻ có thể hỗ trợ tối đa 500tps. Vì vậy, những gì bạn có khả năng đánh là độ trễ trên chèn thực tế mà có thể dễ dàng 75-100ms (do đó hiệu suất 10 mỗi giây bạn đang nhìn thấy). – BrentDaCodeMonkey

+0

Tôi cũng đã thử đo tốc độ hoạt động của nhóm. Trong trường hợp của tôi nó nhanh gấp 3 lần so với phần tử chèn vào. Nhưng thật không may trong trường hợp của tôi, tôi không thể nhóm lại yêu cầu trong một giao dịch. – gabba

+0

BrentDaCodeMonkey, bạn có thể giải thích xin vui lòng những gì bạn "có nghĩa là hoạt động song song"? Mã trong ví dụ của tôi phản ứng về yêu cầu của khách hàng. Tôi mô phỏng reqests với số lượng khác nhau của chủ đề. – gabba

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