जैसा कि मुझे सरल कैशिंग से लेकर मल्टी-टेराबाइट आकार के सेटअप तक विभिन्न प्रकार के उपयोग के मामलों में रेडिस का उपयोग करने वाले कई लोगों और कंपनियों के साथ बोलने का विशेषाधिकार दिया गया है, एक विषय जो मुझे किसी अन्य से अधिक संबोधित करने के लिए कहा गया है वह है प्रदर्शन। रेडिस इस बात से अलग है कि आप प्रदर्शन के बारे में कैसे सोचते हैं। कई में, यदि अधिकांश नहीं, तो डेटाबेस सर्वर आप प्रदर्शन में सुधार करने का प्रयास करते हैं। रेडिस का लक्ष्य इसे धीमा नहीं करना है। यह एक बहुत ही अलग दृष्टिकोण है और इसका लाभ उठाने के लिए एक अलग मानसिकता की आवश्यकता है।
प्रदर्शन मेट्रिक्स - क्या लेटेंसी किंग है?
रेडिस का उपयोग करते समय आप मुख्य रूप से दो प्रदर्शन मेट्रिक्स के बारे में चिंतित हैं:मैं प्रति सेकंड कितने कमांड (या लेनदेन) निष्पादित कर सकता हूं और उन्हें कितना समय लगता है। जब आप इसे तोड़ते हैं तो आप पाते हैं कि पूर्व बाद वाले से द्वितीयक परिणाम है। चूंकि रेडिस सिंगल-थ्रेडेड है, आप कितने ऑप्स/सेकंड पुश कर सकते हैं, यह पूरी तरह से बंधा हुआ है कि वे कितना समय लेते हैं। इस प्रकार, अंततः जो मायने रखता है वह है जिसे मैं "कमांड लेटेंसी" के रूप में संदर्भित करता हूं।
मैं रेडिस के फायदों में से एक मानता हूं, यह सादगी है। आप आदेश जारी करते हैं, प्रश्न नहीं। डेटा खींचने के लिए कमांड एक बहुत ही सरल मार्ग है, और इस मामले में सरलता कमांड की गति में परिलक्षित होती है। यह डेवलपर्स को विभिन्न प्रश्नों के लिए अनुकूलित करने की कोशिश करने के विपरीत अनुकूलित कमांड प्रदान करने की अनुमति देता है। यह सुरुचिपूर्ण सादगी तब रेडिस का उपभोग करने वाले प्रोग्रामर को प्रदान की जाती है। इसका अर्थ अक्सर "क्वेरी" प्रकार के संचालन करना होता है जैसे कि सर्वर सॉफ़्टवेयर करने के बजाय क्लाइंट साइड पर एक सेट को फ़िल्टर करना।
जबकि कुछ लोगों को लगता है कि इस प्रकार की क्वेरी सर्वर पर लगातार तरीके से की जाती है, मेरा वर्तमान में यह विचार है कि यह अब पसंदीदा मार्ग नहीं है। इसका कारण यह है कि बगबियर जिसे हम "स्केलेबिलिटी" कहते हैं। जब आप "क्षैतिज रूप से मापनीय" वेब सेवा या साइट चलाना शुरू करते हैं, उदाहरण के लिए, आप अक्सर जल्दी पाएंगे कि यह संरक्षक ठीक काम करता है। हालाँकि, जब आप ट्रैफ़िक के "अश्लील" स्तरों को संभालना शुरू करते हैं, तो आप जल्दी से सीखते हैं कि डेटाबेस एक महत्वपूर्ण अड़चन है। इसके तुरंत बाद आप इस डेटाबेस को सीखते हैं, आमतौर पर एक SQL स्टोर जैसे कि MySQL, "क्षैतिज रूप से स्केलेबल" नहीं है। आप बस और नहीं जोड़ सकते।
कमांड लेटेंसी
बेशक, न तो रेडिस है। हालाँकि यहाँ अंतर यह है कि फ़िल्टरिंग लॉजिक, सॉर्टिंग, और कुछ भी जिसे आप एक रेडिस कमांड में या कुछ कमांड में निष्पादित नहीं कर सकते हैं, आप डीबी को लॉजिक के साथ लोड नहीं कर रहे हैं - और इस प्रकार "चीजें संसाधित करने के लिए" . रेडिस का उपयोग "डेटा स्टोर" के रूप में किया जाना चाहिए, न कि पारंपरिक "डेटाबेस सर्वर" के रूप में। यह "रेडिस को धीमा न करें" का पहला पहलू है जिसे आपको टटोलने की आवश्यकता है। यह कहने की आवश्यकता नहीं है कि एक बार जब आप लुआ स्क्रिप्टिंग का मार्ग शुरू कर देते हैं, तो आप शुद्ध कम प्रदर्शन का जोखिम उठाते हैं। हो सकता है कि आपका ट्रैफ़िक कम से मध्यम होने पर आप इसे विकास में न देखें। हालाँकि, जब आप बड़े पैमाने पर हिट करते हैं तो आप इसे देखेंगे। और तब तक तर्क अक्सर पहले से ही बेक हो चुका होता है और एप्लिकेशन कोड में जाने के लिए भारी मात्रा में तकनीकी ऋण बन जाता है। हम सभी जानते हैं कि तकनीकी ऋण को चुकाने को अक्सर कितनी प्राथमिकता दी जाती है।
यह कहना नहीं है कि लुआ स्क्रिप्टिंग में जगह नहीं है। इसका सीधा सा मतलब है कि इसकी अत्यधिक जांच होनी चाहिए। जब लुआ स्क्रिप्ट शुद्ध प्रदर्शन हानि होती है या नहीं होती है तो कलाई का एक अच्छा नियम अतिरिक्त राउंड ट्रिप की लागत की तुलना करना है यदि आपने उस तर्क क्लाइंट-साइड को संभाला है। हालांकि, यह नहीं है कि आपका क्लाइंट कोड इसे कब तक कर सकता है। इस पर इस तरह विचार करें:यदि आप अपनी राउंड ट्रिप लागत 2ms से कम करते हैं, लेकिन स्क्रिप्ट निष्पादन समय में 3ms जोड़ते हैं तो आप गलत दिशा में चले गए।
यहां हमें सिंगल-थ्रेडेड सर्वर की प्रकृति के बारे में पूरी जानकारी होनी चाहिए। वह 3ms स्क्रिप्ट निष्पादित होने पर संभावित रूप से सैकड़ों (या यहां तक कि हजारों) आदेशों को अवरुद्ध कर रही है। यदि आप उन्हें (पुल) -> (तर्क) -> (पुल) अनुक्रम में विभाजित करते हैं तो सर्वर "(तर्क)" चरणों के दौरान अतिरिक्त अनुरोधों को संसाधित करने में सक्षम होता है। क्लाइंट कोड में लॉजिक रखकर आप मल्टी-क्लाइंट आधारित सिस्टम में निहित कंसीडर को सुरक्षित रखते हैं। यदि आपको लेन-देन या लुआ स्क्रिप्टिंग की आवश्यकता है तो निश्चित रूप से उनका उपयोग करें। लेकिन उनका उपयोग न करें क्योंकि वे आपके कोड को "आसान" बनाते हैं। समवर्ती प्रदर्शन हिट के बारे में हमेशा जागरूक रहें, इसे मापें, और होशपूर्वक चुनाव करें।
यह हमें "डोन्ट स्लो रेडिस डाउन" के दूसरे नियम की ओर ले जाता है:स्क्रिप्ट के माध्यम से सर्वर लॉजिक से बचकर संगामिति को संरक्षित करें। एक साइड बेनिफिट आपकी Lua स्क्रिप्ट को फिर से लिखे या डंप किए बिना Redis क्लस्टर सेटअप में माइग्रेट करने की क्षमता है जो कई कुंजियों पर काम करती है।
रेडिस को धीमा करने के अन्य तरीके
Redis सर्वर चलाने के कुछ सिस्टम-स्तरीय, या परिचालन पहलू हैं जो Redis को धीमा कर सकते हैं। जैसा कि I/O संसाधन सीमाओं का उपयोग करने वाले किसी भी सर्वर के साथ, Redis को धीमा कर सकता है। उदाहरण के लिए, यदि आपको 8GB नेटवर्क बैंडविड्थ की आवश्यकता है, लेकिन 1GB है, तो यह आपके लिए "धीमा" होगा। यदि आपकी डेमॉन प्रक्रिया कम खुले सॉकेट तक सीमित है, तो आपको समवर्ती कनेक्शन की आवश्यकता है, आदेशों को निष्पादित करने के बजाय कनेक्शन बंद होने की प्रतीक्षा में समय व्यतीत होगा।
संभवतः दो सबसे आम परिचालन विकल्प जो रेडिस को धीमा कर देते हैं, वह है 1) इसे एक वर्चुअल मशीन पर रखना - विशेष रूप से एक ज़ेन हाइपरवाइजर आधारित एक और 2) भारी डिस्क दृढ़ता।
मानक रेडिस साहित्य में पहले वाले को काफी अच्छी तरह से संबोधित किया गया है:इसे ज़ेन हाइपरवाइजर वीएम पर न रखें। दूसरा, दृढ़ता, प्रतीत होता है, लेकिन मेरे अनुमान में यह काफी दूर नहीं जाता है।
निश्चित रूप से, मानक सिफारिशें हैं:स्थानीय फास्ट डिस्क का उपयोग करें, सुनिश्चित करें कि आपके पास गाय नृत्य को संभालने के लिए पर्याप्त मेमोरी है - यहां तक कि केवल दासों पर भी चल रहा है। ये वास्तव में आपके कमांड लेटेंसी के माध्यम से प्रभाव डाल सकते हैं। जो कमी है वह यह है कि कैसे ठीक से निर्धारित किया जाए कि वे हैं या नहीं।
इसका परीक्षण करने का एक मानक तरीका अंतर्निर्मित विलंबता परीक्षण का उपयोग करना है। इससे पहले कि मैं तकनीकी विवरण में आऊं कि यह कैसे करना है, मैं बड़े "कैसे" प्रश्न को संबोधित करना चाहता हूं। इन परीक्षणों को चलाने के लिए यहां मुख्य सबसेट है। सबसे पहले, यदि आपका डेटा सेट छोटा है तो यह परीक्षण व्यर्थ होने की संभावना है। कितना छोटा? निर्धारित करें कि आपके डेटा को डिस्क पर डंप करने में कितना समय लगता है। अगर हम एक या दो सेकंड की बात कर रहे हैं, शायद दस भी, तो आपको सार्थक डेटा मिलने की संभावना कम है। बेशक, यह सब आपके द्वारा सेव करने के बजाय BGSAVE करने पर आधारित है।
दृढ़ता विलंबता
यह हमें उस पहले सिद्धांत की ओर ले जाता है जिसे मैं "दृढ़ता विलंबता" के रूप में संदर्भित करता हूं - आदेश से सर्वर को मारने के परिणाम से किसी प्रकार की दृढ़ता को प्रभावित करने का समय:कम से कम विलंबता का पता लगाएं, जो आप कर सकते हैं। आपके नेटवर्क और डिस्क के आधार पर या तो AoF या स्लेव सर्वर सबसे कम लेटेंसी बंपिंग परसिस्टेंस विकल्प होगा, जिसमें RDB सबसे अंत में आएगा।
RDB मुख्य रूप से अंतिम में आएगा क्योंकि इसमें T सेकंड में N परिवर्तनों की एक अंतर्निहित देरी है। तो, यह मानते हुए कि आपके पास उस न्यूनतम अवधि में पर्याप्त परिवर्तन हैं (सबसे छोटी डिफ़ॉल्ट विंडो 60 सेकंड है) आपकी दृढ़ता देरी अंतराल टी + डिस्क पर आरडीबी लिखने का समय है। यदि डिफ़ॉल्ट 60 सेकंड के अंतराल के साथ उस मेमोरी को डिस्क पर डंप करने में 30 सेकंड का समय लगता है, तो आपकी "दृढ़ता विलंबता" (60+30) 90 सेकंड होगी।
हालाँकि, यह सवाल उठाता है कि क्या यह दृढ़ता विलंबता एक समस्या है। इस प्रश्न के दो पहलू हैं:1) क्या यह आपकी व्यावसायिक आवश्यकताओं के लिए पर्याप्त है? और 2) क्या यह आपके रेडिस को धीमा कर देता है?
पहला प्रश्न यह है कि मैं एक सामान्य उत्तर नहीं दे सकता जो सभी को उत्तर देता है। हालाँकि, मैं कह सकता हूँ कि यदि दृढ़ता विलंबता के लिए आपकी आवश्यकताएँ उपरोक्त सूत्र से अधिक सख्त हैं, तो आपको पता चलता है कि उत्तर RDB के बजाय "एक दास और / या AoF का उपयोग करें" की ओर रुझान की संभावना है। यह मानता है कि आप उस प्लेटफ़ॉर्म पर स्पष्ट गलतियाँ नहीं कर रहे हैं जिस पर आप Redis चलाते हैं। जो हमें दूसरे पहलू पर लाता है:क्या यह रेडिस को धीमा कर देता है?
कुछ के लिए "RDB फ़ाइल को सहेजने में कितना समय लगता है" का प्रश्न उनके मन में सर्वोपरि हो जाता है। मेरे विचार से यह एक भूल है। क्या इससे कोई फर्क नहीं पड़ता कि इसमें कितना समय लगता है? इस प्रश्न का उत्तर है "क्या बचत रेडिस को धीमा कर देती है"। यदि नहीं, तो आपको परवाह नहीं करनी चाहिए कि इसमें 1 सेकंड या 1 घंटा लगता है। उदाहरण के लिए, सर्वर ए पर विचार करें जो आरडीबी को बचाने के लिए 1000 सेकंड लेता है। इंट्रिंसिक कमांड को सेव न करते हुए लेटेंसी रेंज 30-100 माइक्रोसेकंड है। सेव के दौरान यह लेटेंसी अभी भी 30-100 माइक्रोसेकंड रेंज में है। इस मामले में, इस आरडीबी को कम करने के लिए काम करना समय से पहले अनुकूलन होगा, इस धारणा के तहत कि आपके पास खराब रेडिस प्रदर्शन है।
हालाँकि सर्वर B केवल 10 सेकंड लेता है, लेकिन कमांड विलंबता 30-100us से 130-250us तक कूद जाती है। अब आपके पास इस बात से चिंतित होने का एक कारण है कि RDB फ़ाइल को उत्पन्न होने में कितना समय लगता है क्योंकि बचत Redis को धीमा कर रही है और आप इसे कम से कम करना चाहते हैं। यदि इसका मतलब तेज डिस्क है, तो कम से कम अब आपके पास उन्हें उचित ठहराने का कारण है - यह मानते हुए कि लगभग 100-150 माइक्रोसेकंड की वृद्धि आपके एप्लिकेशन के लिए प्रदर्शन की चिंता का कारण बनती है। यदि ऐसा नहीं होता है, तो आप समयपूर्व अनुकूलन पर वापस आ गए हैं।
अब, उस विलंबता को कैसे मापें, मैं इस पोस्ट के भाग दो में अधिक विवरण में जाऊंगा क्योंकि यह पहले से ही काफी लंबा हो गया है।