सर्वर को उत्तरदायी बनाए रखना
यह सुनिश्चित करने के अलावा कि हम थ्रूपुट सीमा के भीतर रहें, हमें यह भी सुनिश्चित करना था कि सर्वर उत्तरदायी रहें। फिर से, टाइमिंग डेटा को देखना उपयोगी था: यहां, उच्च कुल अवधि के बजाय उच्च प्रति-कॉल अवधि वाले संचालन पर अधिक ध्यान केंद्रित करना अधिक प्रभावशाली था।
कार्यकर्ता प्रक्रियाएं + ईटीएस
अनुत्तरदायीता के सबसे बड़े दोषियों में से एक ऑपरेशन था जिसे गिल्ड में चलाने और सभी सदस्यों पर पुनरावृत्त करने की आवश्यकता थी। ये काफी दुर्लभ हैं, लेकिन होते हैं। उदाहरण के लिए, जब कोई हर किसी को पिंग करता है, तो हमें सर्वर में मौजूद सभी लोगों को जानना होगा जो उस संदेश को देखने में सक्षम हैं। लेकिन उन जाँचों को करने में कई सेकंड लग सकते हैं। हम उसे कैसे संभाल सकते हैं? आदर्श रूप से हम उस तर्क को तब चलाएंगे जब गिल्ड अन्य चीजों को संसाधित करने में व्यस्त है, लेकिन एलिक्सिर प्रक्रियाएं मेमोरी को अच्छी तरह से साझा नहीं करती हैं। इसलिए हमें एक अलग समाधान की आवश्यकता थी।
मेमोरी में डेटा संग्रहीत करने के लिए एर्लैंग/एलिक्सिर में उपलब्ध उपकरणों में से एक है जहां प्रक्रियाएं इसे साझा कर सकती हैं टिकट. यह एक इन-मेमोरी डेटाबेस है जो कई अमृत प्रक्रियाओं को सुरक्षित रूप से एक्सेस करने की क्षमता का समर्थन करता है। हालाँकि यह प्रोसेस हीप में डेटा तक पहुँचने की तुलना में कम कुशल है, फिर भी यह काफी तेज़ है। इससे प्रक्रिया ढेर के आकार को कम करने का भी लाभ होता है, जिससे कचरा संग्रहण में विलंब कम हो जाता है।
हमने सदस्यों की सूची रखने के लिए एक हाइब्रिड संरचना बनाने का निर्णय लिया: हम सदस्यों की सूची को ईटीएस में संग्रहीत करेंगे, जो अन्य प्रक्रियाओं को भी इसे पढ़ने की अनुमति देता है, लेकिन हाल के परिवर्तनों (सम्मिलित करना, अपडेट करना, हटाना) का एक सेट भी संग्रहीत करता है। प्रक्रिया ढेर. चूँकि अधिकांश सदस्यों को हर समय अद्यतन नहीं किया जा रहा है, हाल के परिवर्तनों का सेट सदस्यों के समग्र सेट का एक बहुत छोटा सा अंश है।
ईटीएस में सदस्यों के साथ, अब हम कार्यकर्ता प्रक्रियाएं बना सकते हैं और जब हमारे पास महंगे ऑपरेशन होते हैं तो काम करने के लिए उन्हें ईटीएस तालिका पहचानकर्ता पास कर सकते हैं। कार्यकर्ता प्रक्रिया महंगे हिस्से को संभाल सकती है जबकि गिल्ड अन्य काम करना जारी रखता है। हम यह कैसे करते हैं इसके सरलीकृत संस्करण के लिए कोड स्निपेट देखें।
एक जगह जहां हम इसका उपयोग करते हैं वह तब होता है जब हमें गिल्ड प्रक्रिया को एक मशीन से दूसरी मशीन में सौंपने की आवश्यकता होती है (आमतौर पर रखरखाव या तैनाती के लिए)। उस प्रक्रिया में, हमें नई मशीन पर गिल्ड को संभालने के लिए एक नई प्रक्रिया शुरू करने की आवश्यकता है, फिर पुरानी गिल्ड प्रक्रिया की स्थिति को नए में कॉपी करें, सभी जुड़े सत्रों को नई गिल्ड प्रक्रिया से दोबारा कनेक्ट करें, और फिर प्रक्रिया करें उस ऑपरेशन के दौरान जो बैकलॉग बना। एक कार्यकर्ता प्रक्रिया का उपयोग करके, हम अधिकांश सदस्यों को (जो कई जीबी डेटा हो सकता है) भेज सकते हैं, जबकि पुरानी गिल्ड प्रक्रिया अभी भी काम कर रही है, और इस प्रकार हर बार जब हम हाथ से काम करते हैं तो कुछ मिनट रुक जाते हैं।
मैनिफोल्ड ऑफलोड
प्रतिक्रियाशीलता में सुधार (और थ्रूपुट सीमा को भी आगे बढ़ाने) के लिए हमारे पास एक और विचार था विस्तार करना विविध (में चर्चा की गई एक पिछला ब्लॉग पोस्ट) प्राप्तकर्ता नोड्स को फैनआउट करने के लिए एक अलग “प्रेषक” प्रक्रिया का उपयोग करना (गिल्ड प्रक्रिया के बजाय इसे करना)। इससे न केवल गिल्ड प्रक्रिया द्वारा किए गए कार्य की मात्रा कम हो गई, बल्कि यह इसे BEAM से भी बचाएगा वापस दबाव यदि गिल्ड और रिले के बीच नेटवर्क कनेक्शन में से एक को अस्थायी रूप से बैकअप लेना था (बीईएएम वर्चुअल मशीन है जिसमें हमारा एलिक्सिर कोड चलता है)। सैद्धांतिक रूप से ऐसा लग रहा था कि यह एक त्वरित जीत होगी। दुर्भाग्य से, जब हमने इस सुविधा (जिसे मैनिफोल्ड ऑफलोड कहा जाता है) को चालू करने का प्रयास किया, तो हमने पाया कि इससे वास्तव में बड़े पैमाने पर प्रदर्शन में गिरावट आई। यह कैसे हो सकता है? हम सैद्धांतिक रूप से कम काम कर रहे हैं लेकिन प्रक्रिया अधिक व्यस्त है?
अधिक बारीकी से देखने पर, हमने देखा कि अधिकांश अतिरिक्त कार्य कचरा संग्रहण से संबंधित था। यह समझने की कोशिश की जा रही है कि स्वाभाविक रूप से अधिक डेटा की आवश्यकता कैसे और क्यों पड़ी। यहां ही erlang.trace समारोह बचाव में आया. इससे हमें हर बार गिल्ड प्रक्रिया द्वारा कचरा संग्रहण किए जाने के बारे में डेटा प्राप्त करने की अनुमति मिलती है, जिससे हमें न केवल यह पता चलता है कि यह कितनी बार हो रहा है, बल्कि यह भी पता चलता है कि यह किस कारण से हुआ।
उन निशानों से जानकारी लेकर देख रहा हूं BEAM का कचरा संग्रहण कोडहमने महसूस किया कि मैनिफोल्ड ऑफलोड सक्षम होने पर प्रमुख (पूर्ण) कचरा संग्रहण के लिए ट्रिगर स्थिति थी आभासी बाइनरी ढेर. वर्चुअल बाइनरी हीप एक ऐसी सुविधा है जिसे उन स्ट्रिंग्स द्वारा उपयोग की जाने वाली मेमोरी को मुक्त करने की अनुमति देने के लिए डिज़ाइन किया गया है जो प्रक्रिया हीप के अंदर संग्रहीत नहीं हैं, भले ही प्रक्रिया को अन्यथा कचरा इकट्ठा करने की आवश्यकता न हो। दुर्भाग्य से, हमारे उपयोग पैटर्न का मतलब था कि हम कुछ सौ किलोबाइट मेमोरी को पुनः प्राप्त करने के लिए लगातार कचरा संग्रहण को ट्रिगर करेंगे, एक ढेर की प्रतिलिपि बनाने की कीमत पर जो आकार में गीगाबाइट था, एक समझौता जो स्पष्ट रूप से इसके लायक नहीं था। शुक्र है कि BEAM ने हमें एक प्रक्रिया ध्वज का उपयोग करके इस व्यवहार को समायोजित करने की अनुमति दी, min_bin_vheap_size. एक बार जब हमने इसे कुछ मेगाबाइट तक बढ़ा दिया, तो पैथोलॉजिकल कचरा संग्रहण व्यवहार गायब हो गया, और फिर हम कई गुना ऑफलोड चालू करने और एक महत्वपूर्ण प्रदर्शन जीत देखने में सक्षम हुए।
2023-11-16 13:37:51
#एक #ह #सरवर #म #दस #लख #स #अधक #ऑनलइन #उपयगकरतओ #क #सथ #डसकरड #क #समओ #क #आग #बढन