51

मैं गिटहब पर सी # ड्राइवर का उपयोग कर हाल ही में मोंगोडीबी के साथ खेल रहा हूं (यह अजीब तेजी से है)। सब कुछ मेरे छोटे सिंगल थ्रेडेड कंसोल ऐप में ठीक काम कर रहा है जिसका मैं परीक्षण कर रहा हूं। मैं सिंगल थ्रेडेड चलने वाले 8 सेकंड के तहत 1,000,000 दस्तावेज़ (हाँ, मिलियन) जोड़ सकता हूं। अगर मैं लूप के दायरे के बाहर कनेक्शन का उपयोग करता हूं तो मुझे केवल यह प्रदर्शन मिलता है। दूसरे शब्दों में, मैं प्रत्येक डालने के लिए कनेक्ट करने के बजाय कनेक्शन को प्रत्येक सम्मिलन के लिए खोल रहा हूं। जाहिर है कि यह बढ़ गया है।मोंगोडीबी कनेक्शन के लिए .NET सर्वोत्तम प्रथाओं?

मैंने सोचा कि मैं यह देखने के लिए एक पायदान को क्रैंक कर दूंगा कि यह एकाधिक धागे के साथ कैसे काम करता है। मैं ऐसा इसलिए कर रहा हूं क्योंकि मुझे एकाधिक समवर्ती अनुरोधों वाली वेबसाइट अनुकरण करने की आवश्यकता है। मैं 15 से 50 धागे के बीच कताई कर रहा हूं, फिर भी सभी मामलों में कुल 150,000 दस्तावेज डालने वाला हूं। अगर मैं थ्रेड चलाता हूं, प्रत्येक प्रत्येक सम्मिलन ऑपरेशन के लिए एक नया कनेक्शन बनाता है, तो प्रदर्शन एक रुकावट के लिए पीसता है।

स्पष्ट रूप से मुझे कनेक्शन साझा करने, लॉक करने या पूल करने का कोई तरीका ढूंढना होगा। इसमें सवाल है। MongoDB से जोड़ने के मामले में सबसे अच्छा अभ्यास क्या है? क्या कनेक्शन को ऐप के जीवन के लिए खुला रखा जाना चाहिए (प्रत्येक ऑपरेशन के लिए टीसीपी कनेक्शन खोलने और बंद करने के लिए पर्याप्त विलंबता है)?

क्या किसी के पास मोंगोडीबी के साथ कोई वास्तविक दुनिया या उत्पादन अनुभव है, और विशेष रूप से अंतर्निहित कनेक्शन?

यहां एक स्थिर कनेक्शन का उपयोग करके मेरा थ्रेडिंग नमूना है जो सम्मिलित संचालन के लिए बंद है। कृपया उन सुझावों की पेशकश करें जो वेब संदर्भ में प्रदर्शन और विश्वसनीयता को अधिकतम कर देंगे!

private static Mongo _mongo; 

private static void RunMongoThreaded() 
{ 
    _mongo = new Mongo(); 
    _mongo.Connect(); 

    var threadFinishEvents = new List<EventWaitHandle>(); 

    for(var i = 0; i < 50; i++) 
    { 
     var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset); 
     threadFinishEvents.Add(threadFinish); 

     var thread = new Thread(delegate() 
      { 
       RunMongoThread(); 
       threadFinish.Set(); 
      }); 

     thread.Start(); 
    } 

    WaitHandle.WaitAll(threadFinishEvents.ToArray()); 
    _mongo.Disconnect(); 
} 

private static void RunMongoThread() 
{ 
    for (var i = 0; i < 3000; i++) 
    { 
     var db = _mongo.getDB("Sample"); 
     var collection = db.GetCollection("Users"); 
     var user = GetUser(i); 
     var document = new Document(); 
     document["FirstName"] = user.FirstName; 
     document["LastName"] = user.LastName; 

     lock (_mongo) // Lock the connection - not ideal for threading, but safe and seemingly fast 
     { 
      collection.Insert(document); 
     } 
    } 
} 
+2

अंत में आपने क्या निर्णय लिया? एक ही समस्या का सामना करना ... –

+4

अच्छी खबर यह है कि मुझे फैसला नहीं करना पड़ा। Mongodb-csharp और NoRM ड्राइवर दोनों कनेक्शन पूलिंग के लिए समर्थन जोड़ा। दोनों पुस्तकालयों ने अच्छी तरह से डिजाइन किया है, एक मोंगोड या मोंगो प्रक्रिया के खिलाफ कनेक्शन पूलिंग के लिए थ्रेड सुरक्षित तंत्र। दोनों क्षेत्र निकट भविष्य में प्रतिकृति सेट समर्थन भी जोड़ रहे हैं। –

+0

@ टाइलरब्रिंक क्या आप 8sec के तहत 1 एम दस्तावेज़ों को सम्मिलित करने में सक्षम हैं इसका एक उदाहरण दिखा सकते हैं? मैं एकल थ्रेड पर उस गति तक पहुंचने में असमर्थ हूं। – IamStalker

उत्तर

9

एक स्थिर कनेक्शन के बारे में याद रखने की बात यह है कि यह आपके सभी धागे के बीच साझा किया जाता है। आप जो चाहते हैं वह प्रति थ्रेड एक कनेक्शन है।

+0

आपने उस हिस्से को याद किया होगा जहां मैंने कहा था कि प्रति थ्रेड एक कनेक्शन काफी धीमा है।मुझे नहीं लगता कि यह एक उच्च यातायात वेबसाइट के लिए सबसे अच्छा जवाब है। –

+5

अपने नमूने के लिए, जहां आप चीजों को समूहीकृत कर रहे हैं, प्रति थ्रेड एक ऐसा सर्वोत्तम है जिसे आप कर सकते हैं। एक स्थैतिक, साझा कनेक्शन _will_ आप देख रहे हैं जैसे deadlocks बनाएँ। आपका विकल्प कनेक्शन पूलिंग करना है। ऐसा कुछ है जो एसक्यूएल सर्वर प्रदाता ने अंतर्निहित किया है लेकिन मोंगो के लिए आपको खुद को बनाना होगा, और सही होने के लिए यह छोटा नहीं है। –

+1

आज फिर से यह देखकर, यह भी संभव है कि आपके पास बहुत सारे धागे हैं। आदर्श रूप में, आप अपने काम के सामानों के लिए एक साझा, थ्रेड-सुरक्षित कतार चाहते हैं, और केवल एक मुट्ठी भर धागे (सटीक संख्या आपके सिस्टम के आधार पर भिन्न होती है, लेकिन सबसे बड़ा कारक प्रोसेसर कोर की संख्या है)। प्रत्येक थ्रेड कतार से आइटम खींचता है। इससे कनेक्शन की संख्या कम हो जाएगी, इसलिए वे अब बाधा नहीं हैं। –

0

कनेक्शन पूल आपका उत्तर होना चाहिए।

सुविधा विकसित की जा रही है (कृपया अधिक जानकारी के लिए http://jira.mongodb.org/browse/CSHARP-9 देखें)।

अभी, वेब एप्लिकेशन के लिए, सबसे अच्छा अभ्यास BeginRequest पर कनेक्ट करना है और EndRequest पर कनेक्शन जारी करना है। लेकिन मेरे लिए, मुझे लगता है कि कनेक्शन पूल के बिना प्रत्येक अनुरोध के लिए ऑपरेशन बहुत महंगा है। इसलिए मैं वैश्विक मोंगो ऑब्जेक्ट का निर्णय लेने और प्रत्येक थ्रेड के लिए साझा संसाधन के रूप में इसका उपयोग करने का निर्णय लेता हूं (यदि आपको अभी गिटूब से नवीनतम सी # ड्राइवर मिलता है, तो वे थोड़ी देर के लिए प्रदर्शन में भी सुधार करते हैं)।

मुझे ग्लोबल मोंगो ऑब्जेक्ट का उपयोग करने के लिए नुकसान नहीं पता है। तो आइए इस पर टिप्पणी करने के लिए किसी अन्य विशेषज्ञ की प्रतीक्षा करें।

लेकिन मुझे लगता है कि जब तक सुविधा (कनेक्शन पूल) पूरा नहीं हो जाता है, तब तक मैं इसके साथ रह सकता हूं।

+0

क्या आप SQL सर्वर/MySQL के कनेक्शन के साथ उसी तरह उपयोग करते हैं? मुझे लगता है कि कनेक्शन पूलिंग के साथ सबसे अच्छा प्रथा अभी भी "खुली देर से, जल्दी जल्दी" है, और अनुरोध के दौरान कई बार कनेक्शन खोलने/बंद करने के लिए लगभग कुछ भी लागत नहीं है। –

1

कुछ हद तक अभी भी ब्याज की बात है CSMongo, jLinq के डेवलपर द्वारा निर्मित मोंगोडीबी के लिए एक सी # चालक। यहां एक नमूना है:

//create a database instance 
using (MongoDatabase database = new MongoDatabase(connectionString)) { 

    //create a new document to add 
    MongoDocument document = new MongoDocument(new { 
     name = "Hugo", 
     age = 30, 
     admin = false 
    }); 

    //create entire objects with anonymous types 
    document += new { 
     admin = true, 
     website = "http://www.hugoware.net", 
     settings = new { 
      color = "orange", 
      highlight = "yellow", 
      background = "abstract.jpg" 
     } 
    }; 

    //remove fields entirely 
    document -= "languages"; 
    document -= new[] { "website", "settings.highlight" }; 

    //or even attach other documents 
    MongoDocument stuff = new MongoDocument(new { 
     computers = new [] { 
      "Dell XPS", 
      "Sony VAIO", 
      "Macbook Pro" 
      } 
     }); 
    document += stuff; 

    //insert the document immediately 
    database.Insert("users", document); 

} 
6

जब mongodb-csharp का उपयोग करते हैं तो आप इसका इलाज करते हैं जैसे आप एक एडीओ कनेक्शन करेंगे। जब आप एक मोंगो ऑब्जेक्ट बनाते हैं तो यह पूल से एक कनेक्शन उधार लेता है, जिसका निपटारा होने तक इसका स्वामित्व होता है। तो उपयोग ब्लॉक के बाद कनेक्शन पूल में वापस आ गया है। मोंगो वस्तुओं का निर्माण सस्ता और तेज़ है।

उदाहरण

for(var i=0;i<100;i++) 
{ 
     using(var mongo1 = new Mongo()) 
     using(var mongo2 = new Mongo()) 
     { 
       mongo1.Connect(); 
       mongo2.Connect(); 
     } 
} 

डाटाबेस लॉग
बुध जून 02 20:54:21 कनेक्शन से 127.0.0.1:58214 # स्वीकार कर लिया 1
बुध जून 02 20:54:21 कनेक्शन 127.0.0.1:58215 से स्वीकार किया गया # 2
बुध जून 02 20:54:21 मैसेजिंगपोर्ट recv() errno: 0 कोई त्रुटि 127.0.0.1:58214
बुध जून 02 20:54:21 अंत कनेक्शन 127.0.0.1:58214
बुध जून 02 20:54:21 MessagingPort recv() errno: यह 0 कोई त्रुटि 127.0.0.1:58215
बुध जून 02 20:54:21 अंत कनेक्शन 127.0.0.1:58215

सूचना केवल 2 कनेक्शन खोले

मैंने इसे mongodb-csharp फ़ोरम का उपयोग करके एक साथ रखा है। http://groups.google.com/group/mongodb-csharp/browse_thread/thread/867fa78d726b1d4

+1

अब तक का सबसे अच्छा जवाब। धन्यवाद! :) –

0

मैं कोई तिथि नहीं-MongoDB ड्राइवर का उपयोग कर रहा है और यह मुझे अपने कनेक्शन पूल के साथ मदद नहीं करता है :(मैं 10-20 के बारे में अनुरोध वेब अनुरोध के अनुसार MongoDB करने के लिए है (150 उपयोगकर्ताओं को ऑनलाइन - औसत)। और मैं कर सकता हूँ ' टी भी आंकड़ों की निगरानी या इसे फेंक अपवाद मेरे लिए खोल से MongoDB से कनेक्ट

मैं भंडार बनाया है, जो खुले और अनुरोध के अनुसार कनेक्शन निपटाने मैं के रूप में ऐसी बातों पर भरोसा करते हैं:।। 1) चालक कनेक्शन पूल 2 है) मेरे शोध के बाद (मैंने इस बारे में उपयोगकर्ता समूहों में कुछ प्रश्न पोस्ट कर दिए हैं) - मुझे समझ में आया कि मोंगो ऑब्जेक्ट और ओपन कनेक्शन बनाने से भारी ऑपरेशन नहीं होता है, इसलिए भारी ऑपरेशन होता है।

लेकिन आज मेरी उत्पादन :( नीचे जाना हो सकता है मैं अनुरोध के अनुसार खुले कनेक्शन को बचाने के लिए है ...

यहाँ उपयोगकर्ता समूह के लिए लिंक है http://groups.google.com/group/mongodb-user/browse_thread/thread/3d4a4e6c5eb48be3#

54

अधिकांश यहाँ जवाब पुराना कर रहे हैं और कर रहे हैं अब लागू नहीं के रूप में .net ड्राइवर परिपक्व और पड़ा है अगणित सुविधाओं को जोड़ा

नई 2.0 चालक के प्रलेखन यहां पाया को देखते हुए:। http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/

.NET ड्राइवर अब थ्रेड सुरक्षित है और कनेक्शन पूलिंग को संभालता है। प्रलेखन के अनुसार

यह एक स्थिर स्थान के रूप में या एक सिंगलटन जीवनकाल के साथ एक आईओसी कंटेनर में एक मोंगो क्लाइंट उदाहरण को स्टोर करने की अनुशंसा की जाती है।

+0

इस उत्तर को शीर्ष पर भेजा जाना आवश्यक है। मेरा अपवित्र ले लो! – Zignd

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