रेडिस को प्रदर्शन पर बहुत जोर देकर विकसित किया गया है। हम हर रिलीज के साथ यह सुनिश्चित करने के लिए अपनी पूरी कोशिश करते हैं कि आप एक बहुत ही स्थिर और तेज़ उत्पाद का अनुभव करेंगे।
फिर भी, यदि आप रेडिस की दक्षता में सुधार की गुंजाइश पा रहे हैं या प्रदर्शन रिग्रेशन जांच का पीछा कर रहे हैं, तो आपको रेडिस के प्रदर्शन की निगरानी और विश्लेषण करने का एक संक्षिप्त व्यवस्थित तरीका चाहिए। यह उन अनुकूलन में से एक की कहानी है।
अंत में, हमने स्ट्रीम के इनजेस्ट प्रदर्शन में लगभग 20% का सुधार किया है, एक सुधार जिसका लाभ आप पहले से ही रेडिस v7.0 पर उठा सकते हैं।
एक मानक SPEC
अनुकूलन में कूदने से पहले, हम आपको इस बारे में एक उच्च-स्तरीय विचार देना चाहते हैं कि हम वहां कैसे पहुंचे।
जैसा कि पहले कहा गया है, हम रेडिस प्रदर्शन रिग्रेशन और/या संभावित ऑन-CPU प्रदर्शन सुधारों की पहचान करना चाहते हैं। ऐसा करने के लिए, हमने प्रदर्शन और अवलोकन आवश्यकताओं और अपेक्षाओं से संबंधित सभी मामलों पर क्रॉस-कंपनी और क्रॉस-कम्युनिटी मानकों के एक सेट को बढ़ावा देने की आवश्यकता महसूस की।
संक्षेप में, हम लगातार SPEC के बेंचमार्क को ब्रांच/टैग के अनुसार तोड़कर चलाते हैं और परिणामी प्रदर्शन डेटा की व्याख्या करते हैं जिसमें प्रोफाइलिंग टूल्स/प्रोबर्स आउटपुट और क्लाइंट आउटपुट "ज़ीरो-टच" पूरी तरह से स्वचालित मोड में शामिल होते हैं।
उपयोग किए गए उपकरण सभी ओपन सोर्स हैं और memtier_benchmark, redis-benchmark, Linux perf_events, bcc/BPF ट्रेसिंग टूल्स, और ब्रेंडन ग्रेग के FlameGraph रेपो जैसे टूल्स/लोकप्रिय फ्रेमवर्क पर भरोसा करते हैं।
यदि आप रेडिस के साथ प्रोफाइलर्स का उपयोग कैसे करते हैं, इस पर अधिक विवरण में रुचि रखते हैं, तो हम हमारे अत्यंत विस्तृत "ऑन-CPU प्रोफाइलिंग और ट्रेसिंग के लिए प्रदर्शन इंजीनियरिंग गाइड." को देखने की सलाह देते हैं।
डुप्लिकेट गणना से बचकर प्रदर्शन में सुधार
जैसे ही यह पहला कदम दिया गया, हमने प्रोफाइलिंग टूल्स/प्रोबर्स के आउटपुट की व्याख्या शुरू की। एक बेंचमार्क जिसने एक दिलचस्प पैटर्न प्रस्तुत किया वह था स्ट्रीम्स का इनजेस्टेड बेंचमार्क जो बस एक कमांड के समान डेटा को स्ट्रीम में इनजेस्ट करता है:
`XADD key * field value`।
हमने देखा कि जब किसी ID के बिना स्ट्रीम में जोड़ा जाता है, तो यह SDS निर्माण/मुक्त/एसडीएसलेन पर डुप्लिकेट काम बनाता है जो CPU चक्रों का लगभग 10% खर्च करता है, जैसा कि अगले दो perf रिपोर्ट प्रिंट में विस्तार से दिखाया गया है।
एक ही इनपुट के लिए, sdscatfmt और _sdsnewlen को दो बार बुलाया जा रहा था:
इसने हमें लगभग 9-10% में स्ट्रीम्स इनजेस्टन को अनुकूलित करने की अनुमति दी, जैसा कि निम्नलिखित बेंचमार्क परिणामों द्वारा पुष्टि की गई:
अनस्टेबल ब्रांच पर बेसलाइन (6b403f5) :
इस PR का पहला कमिट (डुप्लिकेट काम से बचें):
डुप्लिकेट आवंटन से बचकर प्रदर्शन में सुधार
इस उपयोग-मामले सुधार के प्रारंभिक फोकस ने ओरान (कोर-टीम सदस्यों में से एक) के आगे के विश्लेषण को जन्म दिया, जिसने CPU चक्रों की एक और बर्बादी देखी। इस बार, यह उसी कोड ब्लॉक के भीतर गैर-इष्टतम मेमोरी प्रबंधन के कारण था। हम एक खाली SDS आवंटित कर रहे थे, और फिर इसे पुनः आवंटित कर रहे थे। कॉल की संख्या कम करने से हमें एक और गति सुधार मिलेगा, जैसा कि नीचे दिखाया गया है।
दूसरा कमिट (पुनः आवंटन से बचें):
मापा गया सुधार
उम्मीद के मुताबिक, केवल इंटरमीडिएट गणना का पुन: उपयोग करके और परिणामस्वरूप आंतरिक रूप से बुलाए गए कार्यों के भीतर अनावश्यक गणना और आवंटन को कम करके, हमने रेडिस स्ट्रीम्स के समग्र CPU समय में ~= 20% की कमी मापी है।
हम मानते हैं कि यह एक उदाहरण है कि कैसे व्यवस्थित सरल सुधार पहले से ही गहराई से अनुकूलित कोड जैसे रेडिस के लिए भी प्रदर्शन में महत्वपूर्ण उछाल ला सकते हैं।
हमारा लक्ष्य रेडिस के प्रदर्शन दृश्यता का विस्तार करना है, और उद्योग और शिक्षा दोनों के सदस्य, संगठनों और व्यक्तियों सहित, योगदान करने के लिए प्रोत्साहित हैं। अगर हम इसे मापते नहीं हैं, तो हम इसमें सुधार नहीं कर सकते।