Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> डेटाबेस

MongoDB में अप्रयुक्त अनुक्रमणिका ढूँढना

MongoDB में अप्रयुक्त अनुक्रमणिका ढूँढना

संस्करण 3.2 से शुरू होकर, MongoDB प्रत्येक इंडेक्स के लिए उपयोग के आंकड़ों को ट्रैक करता है। इन आँकड़ों तक पहुँचने के लिए, MongoDB $indexStats एकत्रीकरण पाइपलाइन चरण प्रदान करता है। MongoDB में अप्रयुक्त इंडेक्स ढूंढते समय यहां छह विचार दिए गए हैं।

उदाहरण के लिए, निम्न कमांड "test.foo" संग्रह के लिए सूचकांक आँकड़े प्रदान करेगा:

db.foo.aggregate( [ { $indexStats: { } } ] )

https://bit.ly/2seXnzo

हम $indexStats आउटपुट का वर्णन नहीं करेंगे क्योंकि इस विषय को कवर करने वाले बहुत सारे दस्तावेज़ीकरण और कई अच्छे लेख हैं। इसके बजाय, हम $indexStats ऑपरेटर का उपयोग करते समय विभिन्न क्षेत्रों पर छह विचार प्रदान करेंगे।

विचार 1:प्रत्येक सेवा पुनरारंभ पर आंकड़े रीसेट किए जाते हैं

$indexStats ऑपरेटर का उपयोग करते समय हमेशा “accesses.since” फ़ील्ड पर अतिरिक्त ध्यान दें। कुछ क्वेरी पैटर्न दुर्लभ हो सकते हैं, जैसे कि दिन की समाप्ति बैच प्रक्रिया या एक साप्ताहिक रिपोर्ट, इसलिए सुनिश्चित करें कि आपके द्वारा मूल्यांकन किए जाने वाले आँकड़ों की अवधि आपकी आवश्यकताओं को कवर करती है। निम्न स्क्रिप्ट आपको एक सीमा (घंटों में) सेट करने की अनुमति देती है और यदि कोई अप्रयुक्त अनुक्रमणिका अनुपालन नहीं करती है तो एक चेतावनी प्रिंट करेगी।

threshold_hours=24; 

db.foo.aggregate( [ { $indexStats: { } } ] ).forEach(function(f){if (f.accesses.ops==0) 
{if (ISODate()-f.accesses.since < threshold_hours*3600*1000) {print('Index: ' +f.name+ ' accessed: 
' +f.accesses.ops+ ' times, Status:WARNING, The duration of statistics DOES NOT meet your compliance')} 
else {print('Index: ' +f.name+ ' accessed: ' +f.accesses.ops+ ' times,  Status:OK The duration of 
statistics meet your compliance');};}})

आपके लिए सही दहलीज क्या है? कोई आसान जवाब नहीं है। सभी स्टेटमेंट पैटर्न समान आवृत्ति के साथ निष्पादित नहीं होते हैं, इसलिए सही थ्रेशोल्ड एप्लिकेशन से एप्लिकेशन में भिन्न होता है और एक ही डेटाबेस में प्रति संग्रह भिन्न भी हो सकता है।

विचार 2:माध्यमिक पढ़ता है

डिफ़ॉल्ट रूप से, $indexStats प्राथमिक से पढ़ता है। यदि आपका आवेदन केवल सेकेंडरी से पढ़ता है, तो प्राथमिक के खिलाफ $indexStats चलाने से गलत निष्कर्ष निकलेगा। सेकेंडरी से परिणाम पढ़ने के लिए, आप ऊपर दिए गए पहले विचार से स्क्रिप्ट का उपयोग कर सकते हैं, लेकिन db.getMongo().setReadPref('secondary') निष्पादित करें। इसे चलाने से पहले, जो कमांड को सेकेंडरी से पढ़ने के लिए मजबूर करता है।

अब प्रश्न यह है कि "क्या होगा यदि कोई संग्रह प्राथमिक और माध्यमिक दोनों पठन प्राप्त करता है?" निम्न स्क्रिप्ट का उपयोग करके, आप idx सरणी को उन अनुक्रमणिकाओं के साथ पॉप्युलेट कर सकते हैं जो प्राथमिक और माध्यमिक दोनों पर अप्रयुक्त हैं:

idx=[];

db.foo.getIndexes().forEach(function(f){idx.push(f.name)})
db.getMongo().setReadPref('primary');
db.foo.aggregate( [ { $indexStats: { } } ] ).forEach(function(f){if (f.accesses.ops>0) 
{ var index = idx.indexOf(f.name); if (index > -1) {idx.splice(index, 1);};}})
db.getMongo().setReadPref('secondary');
db.foo.aggregate( [ { $indexStats: { } } ] ).forEach(function(f){if (f.accesses.ops>0) 
{ var index = idx.indexOf(f.name); if (index > -1) {idx.splice(index, 1);};}})

idx सरणी की सामग्री में प्राइमरी और सेकेंडरी दोनों पर अप्रयुक्त इंडेक्स होंगे। अनुपालन विंडो (थ्रेसहोल्ड_घंटे) के बारे में क्या? स्क्रिप्ट को विचार 1 (पिछला उपखंड) से थोड़ा संशोधित करने से हम समय अनुपालन लागू कर सकेंगे। बस एग्रीगेशन वाले हिस्से को नीचे दिए गए हिस्से से बदलें और setReadPref का इस्तेमाल करके स्क्रिप्ट को प्राइमरी और सेकेंडरी में चलाएं:

db.foo.aggregate( [ { $indexStats: { } } ,{$match:{"name" : {$in:idx}}}] ).

अगर प्राइमरी और सेकेंडरी अलग-अलग अनुपालन परिणाम लौटाते हैं, तो दोनों स्तरों के अनुपालन के लिए प्रतीक्षा करना सबसे अच्छा तरीका है।

माध्यमिक पठन वरीयता का उपयोग करने से उस स्थिति में "गलत परिणाम" हो सकते हैं जब एक माध्यमिक को हाल ही में फिर से शुरू किया गया हो और स्क्रिप्ट उस माध्यमिक को आंकड़ों को खींचने के लिए चुनती है। इस मामले के लिए, db.serverStatus().uptime . की जांच करना एक अच्छा तरीका है और उच्चतर अपटाइम के साथ माध्यमिक चुनें। अपटाइम विधि को स्क्रिप्ट पर एक अलग दृष्टिकोण की आवश्यकता होती है जिसे इस ब्लॉग पोस्ट के भविष्य के संशोधन में लागू किया जाएगा।

विचार 3:प्रतिकृति सेट टैग

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

 db.getMongo().setReadPref('secondary', [ { "workload": "analytics" } ] ) .  

ऊपर के दूसरे विचार के अंतिम पैराग्राफ में वर्णित भविष्य के दृष्टिकोण को टैग की गई माध्यमिकियों की जांच के लिए भी विस्तारित किया जा सकता है।

विचार 4:TTL अनुक्रमणिका

टीटीएल इंडेक्स ऑपरेशन की सेवा करते हैं लेकिन उनका मुख्य उपयोग डेटा प्रूनिंग के लिए होता है। बहुत संभव है कि  $indexStats इन इंडेक्स को अप्रयुक्त के रूप में रिपोर्ट करे क्योंकि TTL मॉनिटर को इंडेक्स ऑपरेशन के रूप में नहीं गिना जाता है। आप निश्चित रूप से $indexStats रिपोर्ट के निष्कर्षों के आधार पर एक TTL इंडेक्स नहीं छोड़ना चाहते हैं, इसलिए स्क्रिप्ट को इस प्रकार के इंडेक्स को बाहर करना चाहिए।

दूसरे खंड से पॉप्युलेट idx सरणी स्क्रिप्ट पर एक छोटा सा संशोधन काम करेगा। दूसरी पंक्ति को निम्न के साथ बदलें और idx सरणी में कोई TTL अनुक्रमणिका नहीं होगी।

db.foo.getIndexes().forEach(function(f){if (f.expireAfterSeconds==undefined) 
{idx.push(f.name)}})

बहिष्कृत अनुक्रमणिका के बारे में चर्चा को एक कदम आगे बढ़ाते हुए, हम यह दावा कर सकते हैं कि _id भी इसी श्रेणी में आता है। जाहिर है, आप अप्रयुक्त होने पर भी _id इंडेक्स को नहीं छोड़ सकते। एक संग्रह जो कभी भी _id अनुक्रमणिका को नहीं छूता है उसे पुन:डिज़ाइन करने की आवश्यकता हो सकती है।

विचार 5:साझा क्लस्टर

जब शार्प क्लस्टर की बात आती है, तो $indexStats के आउटपुट का मूल्यांकन करने से पहले दो बातों पर विचार करना चाहिए। सबसे पहले, शार्प किए गए संग्रह के विरुद्ध $indexStats का उपयोग करते समय, यह संभव है कि शार्प कुंजी अनुक्रमणिका को अप्रयुक्त के रूप में वर्गीकृत किया गया हो। उदाहरण के लिए, एक लेखन-भारी संग्रह जिसे {_id:"hash"} पर शार्प किया गया है (लिखने के वितरण के लिए भी) लेकिन बिना किसी रीड/अपडेट/डिलीट ऑपरेशंस जो _id इंडेक्स का उपयोग कर सकते हैं। इस मामले में, {_id:"हैशेड"} अप्रयुक्त के रूप में रिपोर्ट। इंडेक्स को गिराना अच्छा नहीं है क्योंकि यह आपके शार्प किए गए क्लस्टर को तोड़ने वाला है। यदि आप 'stats.foo' संग्रह के लिए शार्ड कुंजी को बाहर करना चाहते हैं, तो निम्नलिखित स्क्रिप्ट को विचार दो (सेकेंडरी रीड्स) में वर्णित विधि से जोड़ा जा सकता है और शार्प कुंजी को idx सरणी से बाहर रखा जाएगा।

shardkey=db.getSiblingDB('config').collections.findOne({_id:'stats.foo'},{_id:0,key:1});
db.foo.getIndexes().forEach(function(f){if (JSON.stringify(f.key)!=JSON.stringify(shardkey.key)) 
{printjson(shardkey.key);printjson(f.key);idx.push(f.name)}})

एक और विचार $indexStats के आउटपुट से संबंधित है, क्योंकि यह अब संग्रह में मौजूद प्रत्येक शार्क के आंकड़े लौटाता है। हालांकि यह असामान्य है, ऐसे मामले हैं कि इंडेक्स (एस) कुछ शार्क में अप्रयुक्त के रूप में रिपोर्ट करते हैं जबकि अन्य इसका उपयोग करते हैं। एक खराब शार्ड कुंजी इसका कारण हो सकती है लेकिन सबसे आम परिदृश्य को "कवरिंग इंडेक्स" नाम दिया गया है।

कवरिंग इंडेक्स को बेहतर ढंग से समझने के लिए यहां एक उदाहरण दिया गया है:इंडेक्स {ए:1} और {ए:1, बी:1} दोनों फ़ील्ड 'ए' पर समानता मैच की सेवा कर सकते हैं। अगर शारदा का ऑप्टिमाइज़र {a:1} और shardB का चयन {a:1,b:1} करता है, तो दोनों इंडेक्स कम से कम एक शार्प के लिए अप्रयुक्त रिपोर्ट करेंगे।

चुनौती यह पता लगाना है कि कौन से सूचकांक विश्व स्तर पर उपयोग में नहीं हैं। निम्नलिखित के साथ विचार 2 स्क्रिप्ट (माध्यमिक पढ़ता है) के एकत्रीकरण भाग (प्रत्येक लूप के बाद) को प्रतिस्थापित करने से काम होगा:

db.foo.aggregate( [ { $indexStats: { } } , {$group: {_id:"$name",number :
 {$sum:"$accesses.ops"}}}] ).forEach(function(f){if (f.number>0) { var index = idx.indexOf(f._id);
 if (index > -1) {idx.splice(index, 1);};}})

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

db.foo.aggregate( [ { $indexStats: { } 
},{$match:{name:{$nin:idx},"accesses.ops":0}}]).forEach(function(f){print("Index "+f.name+" 
reports as partially unused on shard/host " +f.host)})

विचार 6:सबसे कम इस्तेमाल किए गए इंडेक्स

अप्रयुक्त इंडेक्स को खोजना और छोड़ना महत्वपूर्ण है लेकिन कम से कम इस्तेमाल किए गए इंडेक्स का मूल्यांकन करना भी महत्वपूर्ण है। यदि कोई इंडेक्स सप्ताह या महीनों के समय में केवल एक या दो बार एक्सेस किया जाता है, तो इसका मतलब यह हो सकता है कि यह आपके कार्यभार के लिए आवश्यक या फायदेमंद नहीं है। निम्न एकत्रीकरण का उपयोग करके समय-समय पर सबसे कम उपयोग किए गए इंडेक्स की जांच करना हमेशा एक अच्छा अभ्यास है:

db.foo.aggregate( [ { $indexStats: { } },{$match:{"accesses.ops":{$gt:0}}},{$group: 
{_id:"$name",number : {$sum:"$accesses.ops"}}},{$sort:{number:1}}] )

फिर, उचित कार्रवाई करें जो या तो इंडेक्स (एस) को छोड़ने, इंडेक्स (एस) की परिभाषा को बदलने, या इंडेक्स (एस) को बेमानी बनाने के लिए अपने स्कीमा/एप्लिकेशन लॉजिक को बदलने के लिए भी हो सकती हैं।

हम यहां आपके लिए हैं

हम यहां आपके MongoDB इंस्टेंस के लिए आपकी अनुक्रमणिका को साफ़ करने में आपकी सहायता करने के लिए हैं। आपको बस इतना करना है कि [email protected] पर एक टिकट बनाएं और हमें आपकी अनुक्रमणिका को बेहतर बनाने में मदद करने दें!


  1. MongoDB को डॉकर कंटेनर के रूप में तैनात करें

    सबसे सुलभ NoSQL डेटाबेस में से एक, MongoDB® में कई उपलब्ध परिनियोजन विकल्प हैं। इस पोस्ट में, मैं MongoDB को एक कंटेनर के रूप में तैनात करने के लिए Docker® का उपयोग करता हूं और उस कंटेनर के साथ बातचीत करने के लिए शेल क्लाइंट का उपयोग करता हूं। परिचय अपने कंप्यूटर या सर्वर पर डॉकर स्थापित करने के बा

  1. पेश है MongoDB कम्पास

    यह पोस्ट MongoDB® के लिए GUI का परिचय देता है, जिसे MongoDB Compass के नाम से जाना जाता है। अवलोकन कम्पास आपको MongoDB क्वेरी सिंटैक्स के किसी भी औपचारिक ज्ञान के बिना अपने MongoDB डेटा का विश्लेषण और समझने की अनुमति देता है। आप कंपास का उपयोग क्वेरी प्रदर्शन को अनुकूलित करने, अनुक्रमणिका को प्रबंध

  1. MongoDB में कोड इंजेक्शन

    मूल रूप से 5 मार्च 2019 को प्रकाशित अगर आप एप्लिकेशन डेवलपर, डेटाबेस एडमिनिस्ट्रेटर (डीबीए), या टेक्नोलॉजिस्ट के किसी भी फ्लेवर के हैं, तो कोड इंजेक्शन आपके रडार पर होना चाहिए। आपके पास एक सुरक्षित क्लाउड वातावरण है। आपके पास डेटाबेस एक्सेस लॉक डाउन है। लेकिन आपके आवेदन कोड के बारे में क्या?यद्य