MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

मोंगो में अपडेट ऑपरेशन के प्रदर्शन को कैसे बढ़ाया जाए?

आप जैसे हैं वैसे ही अपडेट करते समय, आपको दस्तावेज़ की सामग्री का निरीक्षण करने और ऐसे संशोधन करने के लिए उसे पुनः प्राप्त करने की आवश्यकता होती है। MongoDB का कोई परमाणु संचालन नहीं है जो मौजूदा मूल्यों पर उस तरह से कार्य करता है जैसा आप करना चाहते हैं, इसलिए निश्चित रूप से पुनरावृत्ति आवश्यक है।

बयान के अपने दो संस्करणों के बीच नियमित अभिव्यक्ति पर आप कैसे मिलान कर रहे हैं, इस बारे में "क्वेरी" भाग में कोई वास्तविक अंतर नहीं है। कोई बात नहीं, सर्वर पर भेजने से पहले सामग्री को बीएसओएन में बदल दिया जाता है, इसलिए यदि आप एक मानक अभिव्यक्ति निर्माता या प्रत्यक्ष बीएसओएन दस्तावेज़ का उपयोग करते हैं तो इसका बहुत कम परिणाम होता है।

लेकिन प्रदर्शन में सुधार के लिए जो किए जा सकते हैं।

अपडेट करने के लिए बल्क ऑपरेशन का उपयोग करें

जैसा कि कहा गया है, बल्क ऑपरेशंस वह तरीका है जिससे आपको इस तरह की सूची पुनरावृत्ति पर अपडेट करना चाहिए, और आपको सभी परिणामों को एक सूची में बदलने के बजाय एक कर्सर का उपयोग "चाहिए", क्योंकि यह मेमोरी पर बचत करेगा।

सभी विशिष्ट प्रकार की घोषणाओं को छोड़कर और केवल BsonDocument . के रूप में प्रतिनिधित्व करना (जो शायद आपको मार्शलिंग पर बचाएगा, लेकिन इसकी आवश्यकता नहीं है) तो मूल उदाहरण प्रक्रिया होगी:

var pattern = @"(?si)<([^\s<]*workUnit[^\s<]*)>.*?</\1>";
var filter = Builders<JobInfoRecord>.Filter.Regex(x => x.SerializedBackgroundJobInfo,
                                              new BsonRegularExpression(pattern, "i"));


var ops = new List<WriteModel<BsonDocument>>();
var writeOptions = new BulkWriteOptions() { IsOrdered = false };

using ( var cursor = await records.FindAsync<BsonDocument>(filter))
{
    while ( await cursor.MoveNextAsync())
    {
        foreach( var doc in cursor.Current )
        {
            // Replace inspected value
            var updatedJobInfo = Regex.Replace(doc.SerializedBackgroundJobInfo, pattern, "<$1></$1>");

            // Add WriteModel to list
            ops.Add(
                new UpdateOneModel<BsonDocument>(
                    Builders<BsonDocument>.Filter.Eq("JobTypeValue", doc.JobTypeValue),
                    Builders<BsonDocument>.Update.Set("SerializedBackgroundJobInfo", updatedJobInfo)
                )
            );

            // Execute once in every 1000 and clear list
            if (ops.Count == 1000)
            {
                BulkWriteResult<BsonDocument> result = await records.BulkWriteAsync(ops,writeOptions);
                ops = new List<WriteModel<BsonDocument>>();
            }
        }
    }

    // Clear any remaining
    if (ops.Count > 0 )
    {
        BulkWriteResult<BsonDocument> result = await records.BulkWriteAsync(ops,writeOptions);
    }

}

इसलिए क्वेरी से प्राप्त प्रत्येक दस्तावेज़ के लिए डेटाबेस से अनुरोध करने के बजाय, आप एक List बनाते हैं। WriteModel . का इसके बजाय संचालन।

एक बार जब यह सूची एक उचित मूल्य (इस उदाहरण में 1000) तक बढ़ जाती है, तो आप एक ही अनुरोध में सर्वर को लिखने का कार्य करते हैं और सभी बैच संचालन के लिए प्रतिक्रिया करते हैं। यहां हम BulkWriteAsync का उपयोग करते हैं ।

आप चाहें तो 1000 से अधिक आकार में बैच बना सकते हैं, लेकिन यह आमतौर पर निपटने के लिए एक उचित संख्या है। केवल वास्तविक हार्ड सीमा 16 एमबी की बीएसओएन सीमा है, क्योंकि सभी अनुरोध अभी भी वास्तव में बीएसओएन दस्तावेज हैं, यह अभी भी लागू होता है। वैसे भी 16 एमबी तक पहुंचने के लिए बहुत सारे अनुरोध होते हैं, लेकिन इस बात पर विचार करने के लिए एक बाधा मिलान भी है कि जब यह वास्तव में सर्वर तक पहुंचता है तो अनुरोध कैसे संसाधित किया जाएगा, जैसा दस्तावेज:

<ब्लॉकक्वॉट>

"संचालन के प्रत्येक समूह में अधिकतम 1000 ऑपरेशन हो सकते हैं। यदि कोई समूह इस सीमा से अधिक है, तो MongoDB समूह को 1000 या उससे कम के छोटे समूहों में विभाजित करेगा। उदाहरण के लिए, यदि थोक संचालन सूची में 2000 सम्मिलित संचालन शामिल हैं, तो MongoDB 2 समूह बनाता है, प्रत्येक में 1000 ऑपरेशन होते हैं।"

इसलिए अनुरोध आकार को सर्वर द्वारा संसाधित किए जाने के समान स्तर पर रखने से, आपको yield से भी लाभ मिलता है। जहां "एकाधिक बैच" वास्तव में सर्वर के समानांतर कनेक्शन में कार्य कर सकते हैं, बजाय सर्वर को विभाजन और कतारबद्ध करने देने के।

लौटा हुआ परिणाम BulkWriteResult . का है जिसमें भेजे गए ऑपरेशन के बैच से "मैचों" और "संशोधन" आदि की संख्या की जानकारी होगी।

स्वाभाविक रूप से चूंकि संचालन "बैच" में हैं, इसलिए यह देखने के लिए लूप पुनरावृत्ति के अंत में जांच करने के लिए समझ में आता है कि सूची में कोई और "बैच" ऑपरेशन मौजूद है या नहीं, और फिर निश्चित रूप से उसी तरह सबमिट करें।

IsOrdered = false को भी नोट करना BulkWriteOptions . के रूप में इसका मतलब है कि संचालन के बैच को वास्तव में सीरियल क्रम में निष्पादित नहीं किया जाता है, जिसका अर्थ है कि सर्वर वास्तव में "समानांतर" में टेक चला सकता है। यह "विशाल" गति सुधार कर सकता है जहां प्रतिबद्धता के क्रम की आवश्यकता नहीं है। डिफ़ॉल्ट रूप से "आदेशित" और क्रमिक रूप से सबमिट करना है।

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

यह सब सर्वर से किए गए वास्तविक अनुरोधों की संख्या को "कम" करने के बारे में है। अपडेट भेजने और प्रतिक्रिया की प्रतीक्षा करने में समय लगता है, और बड़े ऑपरेशन में यह बहुत महंगा व्यायाम है। एक ही अनुरोध के भीतर कई कार्रवाइयां लागू करके, बल्क ऑपरेशंस से निपटने के लिए यही है।

उस ओवरहेड को कम करना एक "विशाल" प्रदर्शन लाभ है। इसलिए आप इसका इस्तेमाल करते हैं।




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB रेगेक्स, सूचकांक और प्रदर्शन

  2. आराम और मैच के बाद समूह सरणी

  3. 5 मिलियन से अधिक रिकॉर्ड के लिए MongoDB क्वेरी प्रदर्शन

  4. नेवला स्कीमा:'अद्वितीय' का सम्मान नहीं किया जा रहा है

  5. नेवला स्कीमा का उपयोग करके CSV आयात करें