HeadlinesBriefing favicon HeadlinesBriefing.com

तेज़ Tokio अनुप्रयोगों के लिए सिद्धांत

Hacker News •
×

मैं Rust Conf से वापस आ रहा हूँ। Unconf में, हमने async अनुप्रयोगों को डीबग करने और बेंचमार्क करने पर एक उपयोगी चर्चा की। कई दिलचस्प अंतर्दृष्टियाँ साझा की गईं। मैं यहाँ उनमें से कुछ को सूचीबद्ध करने का प्रयास कर रहा हूँ, साथ ही अपने कुछ अनुभव भी। यह उस चीज़ का पहला मसौदा है जो मुझे आशा है कि सर्वोत्तम प्रथाओं का एक जीवंत दस्तावेज़ बन सकता है। बेझिझक एक issue फ़ाइल करें या PR खोलें। मुझे आशा है कि आने वाले दिनों में मैं एक नमूना ऐप भी जोड़ूँगा जो इन मुद्दों को प्रदर्शित करेगा, साथ ही dial9 trace कैसा दिखता है।— Russell

Tokio रनटाइम पर अच्छा प्रदर्शन करने वाला कोड लिखने के लिए कुछ कठोर और तय नियम हैं; इतने सारे प्रश्नों का उत्तर है "यह निर्भर करता है।" एक वर्कलोड का प्रदर्शन इस पर निर्भर करता है कि उस समय रनटाइम पर और क्या चल रहा है। यही कारण है कि इतनी सारी समस्याएँ केवल प्रोडक्शन में दिखाई देती हैं! अच्छा प्रदर्शन करने वाले async अनुप्रयोग लिखना fairness और batching, contention और isolation के बीच एक संतुलन है। यह पोस्ट कुछ सामान्य सिद्धांतों को प्रस्तुत करती है और जहाँ संभव हो अपवादों को कवर करती है। यह Tokio के work-stealing रनटाइम की बुनियादी परिचितता मानती है; एक उच्च-स्तरीय सारांश परिशिष्ट में शामिल है।

सामान्य सिद्धांत

पहले, निर्धारित करें कि क्या आपके पास कोई समस्या है। यदि आप Tokio अनुप्रयोग में red flags खोजना शुरू करते हैं, तो आपको वे मिलेंगे। मैंने जो लगभग हर वास्तविक अनुप्रयोग देखा है, उसमें polls 10-100 माइक्रोसेकंड से बहुत लंबे हैं, जिसकी सिफारिश Alice Ryhl अपने उत्कृष्ट पोस्ट What is Blocking? में करती हैं। ये समस्याएँ उन अनुप्रयोग मेट्रिक्स या व्यवहार को प्रभावित कर सकती हैं या नहीं भी कर सकती हैं जिनकी आप वास्तव में परवाह करते हैं। एक वास्तविक मेट्रिक से पीछे की ओर काम करना महत्वपूर्ण है जिसे आप सुधारने का प्रयास कर रहे हैं। उदाहरण के लिए, एक अनुप्रयोग में लंबे polls हो सकते हैं जो पूरी तरह से हानिरहित हैं; उन्हें "ठीक" करने से उपयोगकर्ता-केंद्रित मेट्रिक्स पर मापनीय प्रभाव नहीं पड़ेगा। मेरे सामने आई अधिकांश समस्याओं में, समस्या अनुप्रयोग कोड में ही थी, अक्सर एक वितरित प्रणाली के कई घटकों के बीच परस्पर क्रिया में (और वास्तव में Tokio में नहीं)। dial9 ने Tokio में बहुत दृश्यता दी है; कम से कम जितनी बार यह Tokio की समस्या पाता है, उतनी ही बार यह वास्तव में स्पष्ट रूप से इसकी अनुपस्थिति प्रदर्शित करता है। बेशक, कभी-कभी यह Tokio की समस्या होती है। Tokio मेट्रिक्स के संदर्भ में, सबसे उपयोगी हाल ही में जोड़ा गया schedule latency histogram है। Schedule latency आपके कार्य के चलने के लिए तैयार होने और Tokio द्वारा वास्तव में future को poll करने के बीच का समय है। हालाँकि यह आपको यह नहीं बताएगा कि कारण क्या है, लेकिन scheduling latency Tokio और आपके कोड के बीच खराब परस्पर क्रिया का सबसे आम लक्षण है।

लेटेंसी के लिए विभाजित करें, थ्रूपुट के लिए बैच करें। लेटेंसी को अनुकूलित करने के लिए अधिक बार yield करें। कई अनुरोधों में कम लेटेंसी के लिए कनेक्शनों के बीच fairness आवश्यक है। Redis (या कोई भी अनुप्रयोग जो request pipelining का समर्थन करता है) पर विचार करें। एक naive कार्यान्वयन सीधे कनेक्शन से डेटा पढ़ेगा जब तक अधिक डेटा उपलब्ध है। जब अनुरोध pipelined होते हैं, तो पूरा pipelined अनुरोध एक इन-मेमोरी बफ़र में समाप्त हो जाएगा। जब आप उससे frames पढ़ते हैं, तो प्रत्येक Poll::Ready होगा बिना नेटवर्क पर वापस जाए। यह लंबे polls और clients के बीच unfairness दोनों पैदा करता है। थ्रूपुट पर प्रभाव आमतौर पर छोटा होता है: समान संख्या में अनुरोध संसाधित होते हैं। हालाँकि, लेटेंसी नाटकीय रूप से बदल जाती है क्योंकि एक पूरा pipeline दूसरे के पीछे प्रतीक्षा कर सकता है। इस उदाहरण में प्रत्येक अनुरोध के बाद स्पष्ट रूप से yield करने से लेटेंसी लगभग 10× कम हो सकती है। आप केवल कई लगातार तुरंत-तैयार reads के बाद yield करके और भी बेहतर कर सकते हैं।

मुख्य इकाइयाँ: कंपनियाँ: Tokio, Redis | व्यक्ति: Russell, Alice Ryhl | स्थान: Rust Conf