स्टार्टअप, mmap, mlock और –force-preread के बारे में

जैसा कि लेख “ Indexes load at startup ” में उल्लेखित किया गया था, अब सभी इंडेक्स (विशेषताएँ और शब्द सूची फ़ाइलें) भौतिक रूप से RAM में लोड नहीं होते हैं, बल्कि इसके बजाय मेमोरी-मैप्ड होते हैं। यह उन्हें स्टार्टअप पर बहुत तेज़ी से लाने की अनुमति देता है, लेकिन इसके कुछ पक्ष प्रभाव भी हैं जिन्हें मैं समझाना चाहता हूँ।

सर्वप्रथम, क्योंकि हम मैपिंग करते हैं, इंडेक्स स्थायी रूप से भौतिक RAM में लॉक नहीं हो सकते हैं, और यह आवश्यक नहीं है कि आपके पास उन सभी के लिए इतनी RAM हो। पर्याप्त मात्रा में RAM होने से कई मामलों में आपको तेजी से खोज क्वेरी प्रदान कर सकती है क्योंकि जब इंडेक्स कैश होते हैं, तो वे काफी तेज़ी से काम करते हैं।

दूसरा परिणाम - वास्तव में मेमोरी मैपिंग सिर्फ ‘वर्चुअल एड्रेस स्पेस’ के एक क्षेत्र पर कब्जा करती है। जैसे कि किसी भी आधुनिक प्रणाली पर आपके पास पतों के लिए 64 बिट्स होते हैं, हम कह सकते हैं कि हम किसी भी आकार के इंडेक्स को लोड और सेवा कर सकते हैं, भले ही वास्तव में फ्री RAM कितनी हो। ध्यान दें, हालांकि, कि यह केवल इंडेक्स डेटा से संबंधित है। Manticore सर्च डेमन को सामान्य काम के लिए भी भौतिक RAM की आवश्यकता होती है, जैसे आंतरिक हैश, बफर, एरे, आदि।

यदि आप प्रक्रिया की मेमोरी सांख्यिकी को देखते हैं, तो आप RSS (या RES) कॉलम में कुछ संख्या देखेंगे, और वह वास्तव में कब्जा की गई RAM है (अधिकतर हीप), लेकिन लोड किए गए इंडेक्स नहीं हैं (जब तक कि आप mlock=1 न करें)। वे ज्यादातर ‘VSZ’ कॉलम में दर्शाए गए हैं। यदि आप एक विशाल इंडेक्स लोड करते हैं (लगभग पूरे RAM स्थान के बारे में) और फिर ‘फ्री’ कमांड चलाते हैं, तो आप देखेंगे कि यह वास्तव में ‘यूज़्ड’ स्पेस में नहीं दिखाई देता है, बल्कि ज्यादातर ‘बफ/cache’ में, और इसलिए, ‘उपलब्ध’ में भी।

इसलिए डिफ़ॉल्ट द्वारा लोड किए गए इंडेक्स मेमोरी में LOCKED नहीं होते हैं, बल्कि केवल कैश किए जाते हैं। यदि OS को अन्य प्रक्रियाओं के लिए अधिक RAM आवंटित करने की आवश्यकता है, तो यह बस ऐसा करेगा, कैश किए गए डेटा को बलिदान देकर। इसलिए इंडेक्स को ‘लोड’ करना कोई गारंटी नहीं देता है कि यह वास्तव में RAM में है और पूर्वानुमानित रूप से तेज़ प्रतिक्रिया देगा।

व्यवहार में इसका क्या अर्थ है?

  1. सबसे पहले, डिफ़ॉल्ट के द्वारा कोई गारंटी नहीं। स्टार्ट में मेमोरी मैपिंग द्वारा इंडेक्स ‘लोड’ करना और फिर उस मैप के अंदर पृष्ठ-दर-पृष्ठ कदम उठाना केवल उस पृष्ठ को लोड करता है जिसमें आप कदम रखते हैं। OS यह गारंटी नहीं देता है कि एक पृष्ठ में कदम उठाने के बाद, ‘लोडिंग’ का अगला कदम पहले के एक को RAM में स्थायी रूप से लॉक करता है। हाँ, यह हो सकता है - यदि कहें कि आपके पास 128GB की फ्री RAM है और लोड किया गया इंडेक्स केवल 30GB है। लेकिन यदि आपके पास 120GB का आकार का इंडेक्स है और केवल 16GB RAM है, तो ‘लोडिंग’ उसी तरीके से सफल होगा, लेकिन चूंकि इंडेक्स RAM में नहीं फिट हो सकता है, यह पूरी तरह से कैश नहीं होगा और इसका प्रतिक्रिया समय बढ़ जाएगा।
  2. दूसरे, लोड किए गए इंडेक्स के लिए यही प्रतिक्रिया समय स्थायी रूप से बनाए रखा जाएगा, इसकी कोई गारंटी नहीं है। फिर से कल्पना करें, कि आप 30GB के इंडेक्स को 50GB की फ्री RAM वाले सिस्टम पर लोड करते हैं, और सब कुछ तेज़ी से काम कर रहा है। लेकिन फिर आप एक और RAM-खपत करने वाली प्रक्रिया लोड करते हैं, और यह 40GB का प्रयोग करती है। इसका मतलब है कि आपके 30GB के इंडेक्स में से केवल ~10GB अभी भी कैश होगा, और बाकी तक पहुँचने के लिए अब डिस्क से पढ़ना आवश्यक है।

इसलिए, न तो लेज़ी प्रीरीड, न ही --force-preread विकल्प यह गारंटी देते हैं कि पूरा इंडेक्स कैश है और स्थायी रूप से और पूर्वानुमानित रूप से तेज़ प्रतिक्रिया देगा। कोई गारंटी नहीं, केवल संभावना। आपके पास जितनी अधिक RAM होगी - पूरे इंडेक्स के कैश हो जाने की अधिक संभावना होगी और यह अधिकतम तेजी से प्रतिक्रिया देगा। यह सभी mmap “मसाज” केवल संभावना के बारे में है।

लेकिन मुझे गारंटी की आवश्यकता है, केवल संभावना नहीं! क्या यह संभव है?

हाँ! RAM में पूरे इंडेक्स को निश्चित रूप से लॉक करने का एकमात्र तरीका mlock विकल्प का उपयोग है। इसे इंडेक्स कॉन्फ़िग में सेट किया जाना चाहिए (कमांड लाइन विकल्पों में नहीं)। इसके लिए आपको ऐसा करने के लिए विशेषाधिकार आवश्यक हैं (विवरण के लिए सिस्टम ‘man mlock’ देखें)। यह कैसे काम करता है? डेमन इंडेक्स फ़ाइलों को mmap करेगा, और फिर उन पर ‘mlock’ कॉल करेगा। उस क्षण में OS यह पहचान लेगा कि क्या इसके पास सभी इच्छित मानचित्रों को लोड करने के लिए पर्याप्त RAM है, और यदि ऐसा है, तो यह तुरंत लोडिंग करेगा। यह अपेक्षाकृत लंबी प्रक्रिया हो सकती है (बस अपने स्टोरेज की गति लें और यह अनुमान लगाएँ कि आवश्यक मात्रा में डेटा को अनुक्रमिक रूप से लोड करने में कितना समय लगेगा)।

इस प्रकार हम लक्ष्य को प्राप्त कर सकते हैं - RAM में पूरी तरह से लॉक किए गए इंडेक्स तक पहुँचें जो पूर्वानुमानित रूप से तेज़ी से प्रतिक्रिया देगा। यह अच्छा है।

लेकिन इसके साथ कुछ बातें भी उल्लेखनीय हैं जो mlock से संबंधित हैं।

  1. सबसे पहले, जैसा कि उल्लेख किया गया था - आपको इसे चलाने के लिए विशेषाधिकार की आवश्यकता है। यह आंशिक रूप से इससे संबंधित है कि यह कैसे काम करता है और यह पूरे सिस्टम को प्रभावित कर सकता है। हालांकि, अधिकांश मामलों में यह बड़ी बात नहीं है जब तक आप बहुत सीमित अनुमतियों के साथ साझा होस्टिंग का उपयोग नहीं कर रहे हैं।
  2. दूसरा, मैप (mlocking) का कैशिंग एक ब्लॉकिंग प्रक्रिया है जिसे हम प्रबंधित नहीं कर सकते। आंतरिक रूप से हम बस mlock() कॉल करते हैं, यह कुछ जादू करता है और सब कुछ होने के बाद कुछ सेकंड/मिनट में लौटता है। इसे बाधित करने का कोई तरीका नहीं, i/o को थ्रॉटल करने का कोई तरीका नहीं, बस इंतज़ार करें। इसलिए, mlocking की प्रक्रिया मशीन पर अन्य i/o ऑपरेशनों को प्रभावित कर सकती है।
  3. जब सिस्टम mlocking के लिए RAM की खोज करता है, तो संभावना है कि यह आपके लिए RAM मुक्त करने के लिए OOM-किलर को कॉल करेगा जिससे कोई अन्य प्रक्रिया बंद हो सकती है। सावधान रहें!
  4. यहां तक कि यदि आप mlock का उपयोग करते हैं तो भी कई मामलों में आप --force-preread का उपयोग करना चाह सकते हैं। यहाँ दुविधा है:
    • बिना --force-preread के, searchd कनेक्शन की पेशकश करना जल्दी शुरू करेगा, लेकिन इंडेक्स तब तक ठंडे रहेंगे जब तक वे बैकग्राउंड में पूर्ण प्रीरीड न हो जाएं। यह आने वाली क्वेरी के लिए बुरा हो सकता है।
    • --force-preread के साथ आपको प्रतीक्षा करनी होगी (शायद कुछ मिनट), लेकिन उसके बाद आप बहुत अच्छा प्रदर्शन प्रदान करने में सक्षम होंगे।

यह mlock के साथ कैसा दिख सकता है, लेकिन बिना --force-preread:

no_force_prereadऔर वही इंडेक्स वही हार्डवेयर के साथ --force-preread में:

force_prereadजैसा कि आप देख सकते हैं, इस मामले में शुरू में 6 मिनट का इंतज़ार करना समझ में आता है, अन्यथा औसत प्रतिक्रिया समय कई गुना अधिक हो जाता है और iowait भी अत्यधिक उच्च होता है क्योंकि क्वेरी यादृच्छिक डिस्क पढ़ने करती हैं। बेशक अन्य मामलों में हो सकता है और आपका लोड संतुलन अलग काम कर सकता है और इस तरह की स्थितियों को अधिक समझदारी से संभाल सकता है या आपके पास पूरे इंडेक्स को फिट करने के लिए पर्याप्त RAM नहीं हो सकती, या आपकी क्वेरी हल्की हो सकती हैं। बस दोनों दृष्टिकोणों पर विचार करें और वह चुनें जो आपके लिए सबसे अच्छा हो।

और भी क्या महत्वपूर्ण हो सकता है?

  1. OS पैरामीटर जैसे ‘swapinness’ के साथ खेलें या यदि आप इसे सहन कर सकते हैं तो स्वैपिंग को पूरी तरह से निष्क्रिय करें। इससे तेज प्रतिक्रिया की संभावना बढ़ाने में मदद मिल सकती है (mlocking के बिना)। ध्यान दें कि आधुनिक लिनक्स कर्नेल्स पर आपके पास नियंत्रण-समूह (या cgroups) जैसा एक अद्भुत चीज है। आप अपने डेमन को एक समर्पित cgroup में रख सकते हैं और इसके लिए किसी भी सिस्टम चीज़ों (जैसे उल्लेखित swapinness) को ट्यून कर सकते हैं बिना वैश्विक सिस्टम सेटिंग्स को छुए।
  2. आधुनिक SSDs आकस्मिक पहुँच के लिए भी काफी तेज हैं, इसलिए उनका उपयोग करने से ‘mapped’ (‘mlocked’) और ‘cached’ डेटा के बीच का अंतर मिट सकता है।

मैंटीकोर सर्च इंस्टॉल करें

मैंटीकोर सर्च इंस्टॉल करें