2012-10-05 16 views
9

के साथ प्रति सेकंड अधिक 10 आवेषण कैसे प्राप्त करें मैं सरल वर्कररोल लिखता हूं जो तालिका में परीक्षण डेटा जोड़ता है। आवेषण का कोड इस तरह है।एज़ूर स्टोरेज टेबल

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

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

यह कोड प्रत्येक ग्राहक अनुरोध के लिए चलाता है। मैं 1-30 क्लाइंट धागे के साथ परीक्षण करता हूँ। मेरे पास विभिन्न आकारों के उदाहरणों की विभिन्न गिनती के साथ कई tries हैं। मुझे नहीं पता कि मैं क्या गलत करता हूं लेकिन मैं प्रति सेकंड अधिक 10 आवेषण तक नहीं पहुंच सकता। यदि कोई व्यक्ति गति को बढ़ाने के बारे में जानता है तो कृपया मुझे सलाह दें। धन्यवाद

अद्यतन

  • CreateTableIfNotExist के हटाने के शामिल नहीं है मेरी आवेषण परीक्षण के लिए फर्क।
  • स्विच मोड की अपेक्षा करने के लिए 100Continue = "false" useNagleAlgorithm = "false" कम समय प्रभाव को कम करता है जब दर 30-40 ips तक पहुंच जाती है। लेकिन फिर, 30 सेकंड के बाद 50% टाइमआउट के साथ दर 6 ips तक गिर जाती है।
+1

क्या आप लूप में CreateTableIfNotExist() के साथ उस तर्क को कॉल करने का मौका दे रहे हैं? या केवल एक लूप में जोड़ें/SaveChanges()? CreateTableIfNotExist() एक सस्ता कॉल नहीं है और यदि इसे आवश्यक नहीं है तो आप इसे छोड़ना चाहते हैं – Igorek

+0

यह कोड प्रत्येक अनुरोध के लिए चलाता है। आप किसी भी समय CreateTableIfNotExist को कॉल करने के लिए सही महंगे हैं। मैं इसे हटाने की कोशिश करूंगा और केवल तभी करूंगा जब तालिका त्रुटि न हो। – gabba

उत्तर

29

गति बढ़ाने के लिए आप बैच लेनदेन (इकाई समूह लेन-देन) का उपयोग करना चाहिए, तो आप एक ही अनुरोध के भीतर 100 आइटम तक प्रतिबद्ध करने के लिए अनुमति देता है:

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

आप Partitioner.Create के साथ इस गठजोड़ कर सकते हैं (+ AsParallel) चीजों को वास्तव में तेज़ बनाने के लिए 100 आइटमों के प्रति बैच के विभिन्न थ्रेड/कोर पर एकाधिक अनुरोध भेजने के लिए।

लेकिन यह सब करने से पहले, read through the limitations बैच लेनदेन (100 आइटम, लेनदेन प्रति 1 विभाजन, ...) का उपयोग करने से पहले।

अद्यतन:

आप यहाँ लेनदेन उपयोग नहीं कर सकते क्योंकि कुछ अन्य सुझाव दिए गए हैं। तालिका भंडारण का उपयोग करते समय प्रदर्शन में सुधार के बारे में this MSDN thread पर एक नज़र डालें।

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

तो, पहली बार मैं इस चलाने मैं निम्नलिखित उत्पादन प्राप्त:

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 

यह अधिक से अधिक 3 मिनट लगते हैं 1000 मदों को जोड़ने के लिए मैं तुम्हें अंतर दिखाने के लिए कुछ कोड लिखा था। अब, मैं MSDN मंच पर सुझाव के आधार पर app.config बदल (MAXCONNECTION 12 होना चाहिए * सीपीयू कोर की संख्या):

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 
:

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

और आवेदन चलाने के बाद फिर से मैं इस आउटपुट प्राप्त

3 मिनट से 18 सेकंड तक। क्या अंतर है! लेकिन हम भी बेहतर कर सकते हैं। यहाँ कुछ कोड एक विभाजनर का उपयोग कर सभी आइटम सम्मिलित करता है (डालता है समानांतर में क्या होगा):

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

और परिणाम:

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 

देखा, 3m39s से हम 18s को गिरा दिया और अब हम भी करने के लिए गिरा दिया 4 एस

+0

मैं समानांतर ऑपरेशन की भी सिफारिश करता हूं क्योंकि एक टेबल तालिका 500Tps तक का समर्थन कर सकती है। तो आप जो भी मार रहे हैं वह वास्तविक डालने पर विलंबता है जो आसानी से 75-100ms (इसलिए 10 प्रति सेकंड प्रदर्शन जो आप देख रहे हैं) कर सकते हैं। – BrentDaCodeMonkey

+0

मैंने समूह संचालन की गति को मापने का भी प्रयास किया। मेरे मामले में यह प्रति तत्व आवेषण से 3 गुना तेज है। लेकिन दुर्भाग्य से मेरे मामले में मैं एक लेनदेन में रिकॉर्ड्स समूह नहीं कर सकता। – gabba

+0

ब्रेंटडाकोडमोन्की, क्या आप समझा सकते हैं कि आप "समानांतर ऑपरेशन का क्या अर्थ" करते हैं? मेरे उदाहरण में कोड क्लाइंट रिकॉर्ड्स पर प्रतिक्रिया करता है। मैं धागे की विभिन्न गिनती के साथ reqests अनुकरण। – gabba

संबंधित मुद्दे