अपाचे स्पार्क में अपने तिरछे जुड़ने के लिए पांच युक्तियाँ

Jun 17 2022
स्केव्ड जॉइन स्पार्क एप्लिकेशन के जॉइन चरण में स्ट्रगलर को जन्म दे सकता है जो एप्लिकेशन की समग्र दक्षता को कम करता है। यदि आपने भी स्केव्ड जॉइन के समाधान का सामना किया है या खोज रहे हैं, तो इस विशेष कहानी को पढ़ें जो विभिन्न स्थितियों में स्केव्ड जॉइन को संबोधित करने के लिए पांच अलग-अलग तकनीकों की व्याख्या करती है।
संदर्भ: पिक्साबे

स्केव्ड जॉइन स्पार्क एप्लिकेशन के जॉइन चरण में स्ट्रगलर को जन्म दे सकता है जो एप्लिकेशन की समग्र दक्षता को कम करता है। यदि आपने भी स्केव्ड जॉइन के समाधान का सामना किया है या खोज रहे हैं, तो इस विशेष कहानी को पढ़ें जो विभिन्न स्थितियों में स्केव्ड जॉइन को संबोधित करने के लिए पांच अलग-अलग तकनीकों की व्याख्या करती है।

जॉइन एक विशिष्ट डेटा प्रोसेसिंग रूटीन में सबसे मौलिक परिवर्तनों में से एक है। एक जॉइन ऑपरेटर दो इनपुट डेटासेट में सहसंबंध, समृद्ध और फ़िल्टर करना संभव बनाता है। दो इनपुट डेटासेट को आम तौर पर बाएं डेटासेट और दाएं डेटासेट के रूप में वर्गीकृत किया जाता है, जो कि जॉइन क्लॉज/ऑपरेटर के संबंध में होता है।

मूल रूप से, एक जॉइन एक सशर्त बयान पर काम करता है जिसमें एक बूलियन अभिव्यक्ति शामिल होती है जो बाएं डेटासेट से रिकॉर्ड से प्राप्त बाईं कुंजी और दाएं डेटासेट से रिकॉर्ड से प्राप्त दाएं कुंजी के बीच तुलना पर आधारित होती है। बाएँ और दाएँ कुंजियों को आम तौर पर ' Join Keys' कहा जाता है । बूलियन एक्सप्रेशन का मूल्यांकन दो इनपुट डेटासेट में रिकॉर्ड की प्रत्येक जोड़ी के विरुद्ध किया जाता है। अभिव्यक्ति के मूल्यांकन से बूलियन आउटपुट के आधार पर, सशर्त बयान में जोड़े में से किसी एक रिकॉर्ड का चयन करने के लिए एक चयन खंड या जोड़ी बनाने वाले रिकॉर्ड का संयुक्त रिकॉर्ड शामिल होता है।

तिरछे डेटासेट पर जॉइन करना: एक डेटासेट को जॉइन ऑपरेशन के लिए तिरछा माना जाता है, जब डेटासेट में रिकॉर्ड्स में जॉइन कीज़ का वितरण चाबियों के एक छोटे सबसेट की ओर तिरछा होता है। उदाहरण के लिए जब डेटासेट में 80% रिकॉर्ड केवल 20% जॉइन कुंजियों में योगदान करते हैं।

शामिल होने के लिए तिरछे डेटासेट के निहितार्थ : तिरछे डेटासेट, यदि उचित रूप से नियंत्रित नहीं किए जाते हैं, तो शामिल होने के चरण में स्ट्रगलर हो सकते हैं ( स्ट्रैगलर्स के बारे में अधिक जानने के लिए इस लिंक की गई कहानी को पढ़ें )। यह स्पार्क जॉब की समग्र निष्पादन दक्षता को कम करता है। इसके अलावा, तिरछे डेटासेट कुछ निष्पादकों पर मेमोरी ओवररन का कारण बन सकते हैं जिससे स्पार्क जॉब विफल हो जाता है। इसलिए, जॉइन आधारित चरणों की पहचान करना और उन्हें संबोधित करना महत्वपूर्ण है जहां बड़े तिरछे डेटासेट शामिल हैं।

तिरछी जोड़ को संबोधित करने की तकनीक: अब तक आपने तिरछी जोड़ को संभालने के लिए बहुत सारे बिखरे हुए साहित्य देखे होंगे लेकिन इनमें से अधिकांश 1 या 2 तकनीकों पर जोर देते हैं और इसमें शामिल विवरण और सीमाओं के बारे में संक्षेप में वर्णन करते हैं। इस बिखरे हुए विवरण को ध्यान में रखते हुए, यह विशेष कहानी आपको हर संभावित परिदृश्य में तिरछी जॉइन को संभालने के लिए पाँच महत्वपूर्ण तकनीकों की पूरी और व्यापक सूची प्रदान करने का एक प्रयास है:

1) ब्रॉडकास्ट हैश जॉइन : 'ब्रॉडकास्ट हैश' जॉइन में, या तो लेफ्ट या राइट इनपुट डेटासेट को एक्ज़ीक्यूटर को ब्रॉडकास्ट किया जाता है। 'ब्रॉडकास्ट हैश' जॉइन तिरछी इनपुट डेटासेट से सुरक्षित है। यह इस तथ्य के कारण है कि 'ज्वाइन की' के अनुसार विभाजन, बाएँ और दाएँ डेटासेट पर अनिवार्य नहीं है। यहां, डेटासेट में से एक को प्रसारित किया जाता है जबकि दूसरे को किसी भी पैमाने की समान समानता प्राप्त करने के लिए उपयुक्त तरीके से उचित रूप से विभाजित किया जा सकता है।

स्पार्क ' ब्रॉडकास्ट हैश जॉइन ' को जॉइन टाइप और इनपुट डेटासेट के आकार के आधार पर चुनता है। यदि जॉइन प्रकार अनुकूल है और प्रसारित किए जाने वाले डेटासेट का आकार एक कॉन्फ़िगर करने योग्य सीमा ( स्पार्क . इसलिए, यदि आप ' स्पार्क.एस.एल .

स्पार्क को 'ब्रॉडकास्ट हैश जॉइन' का उपयोग करने के लिए बाध्य करने के लिए 'स्पार्क.एसक्यूएल.ऑटोब्रॉडकास्टजॉइन थ्रेशोल्ड' मान के बावजूद स्पार्क को बाध्य करने के लिए जॉइन टाइप के आधार पर किसी भी इनपुट डेटासेट पर एसक्यूएल प्रश्नों में प्रसारण संकेतों का उपयोग कर सकते हैं।

इसलिए, यदि कोई निष्पादकों के लिए मेमोरी का खर्च उठा सकता है, तो 'ब्रॉडकास्ट हैश' जॉइन को तिरछी जॉइन के तेजी से निष्पादन के लिए अपनाया जाना चाहिए। हालाँकि यहाँ कुछ मुख्य बिंदु दिए गए हैं जिन पर इस सबसे तेज़ विधि का उपयोग करने की योजना बनाते समय विचार किया जाना चाहिए:

  • पूर्ण बाहरी जुड़ाव के लिए लागू नहीं है।
  • इनर जॉइन के लिए, एक्ज़ीक्यूटर मेमोरी को दो इनपुट डेटासेट में से कम से कम छोटे को समायोजित करना चाहिए।
  • लेफ्ट, लेफ्ट एंटी और लेफ्ट सेमी जॉइन के लिए, एक्ज़ीक्यूटर मेमोरी को सही इनपुट डेटासेट को समायोजित करना चाहिए क्योंकि राइट को प्रसारित करने की आवश्यकता होती है।
  • राइट, राइट एंटी और राइट सेमी जॉइन के लिए, एक्ज़ीक्यूटर मेमोरी को लेफ्ट इनपुट डेटासेट को समायोजित करना चाहिए क्योंकि लेफ्ट को प्रसारित करने की आवश्यकता होती है।
  • प्रसारित डेटासेट के आकार के आधार पर निष्पादकों पर निष्पादन मेमोरी की भी काफी मांग है।

ऐसे परिदृश्यों से निपटने के लिए, ' इटरेटिव ब्रॉडकास्ट ' तकनीक इनपुट डेटा सेट (अधिमानतः छोटे वाले) में से एक को एक या एक से अधिक छोटे टुकड़ों में तोड़ देती है, जिससे यह सुनिश्चित हो जाता है कि प्रत्येक परिणामी चंक को आसानी से प्रसारित किया जा सकता है। फिर इन छोटे टुकड़ों को मानक ' ब्रॉडकास्ट हैश ' जॉइन का उपयोग करके दूसरे अटूट इनपुट डेटासेट के साथ एक-एक करके जोड़ा जाता है । इन मल्टीपल जॉइन के आउटपुट को अंतिम आउटपुट के उत्पादन के लिए ' यूनियन ' ऑपरेटर का उपयोग करके अंत में एक साथ जोड़ दिया जाता है।

डेटासेट को छोटे टुकड़ों में विभाजित करने के तरीकों में से एक यह है कि नए जोड़े गए कॉलम ' chunkId' में डेटासेट के प्रत्येक रिकॉर्ड के लिए वांछित संख्या में यादृच्छिक संख्या असाइन करना है । एक बार जब यह नया कॉलम तैयार हो जाता है, तो लूप के लिए चंक नंबरों पर पुनरावृति करने के लिए शुरू किया जाता है। प्रत्येक पुनरावृत्ति के लिए, सबसे पहले रिकॉर्ड्स को ' chunkId' पर फ़िल्टर किया जाता है।वर्तमान पुनरावृत्ति खंड संख्या के अनुरूप स्तंभ। फ़िल्टर किए गए डेटासेट, प्रत्येक पुनरावृत्ति में, फिर आंशिक रूप से शामिल आउटपुट प्राप्त करने के लिए मानक 'ब्रॉडकास्ट हैश' जॉइन का उपयोग करके अटूट अन्य इनपुट डेटासेट के साथ जुड़ जाते हैं। आंशिक रूप से सम्मिलित आउटपुट को फिर पिछले आंशिक सम्मिलित आउटपुट के साथ जोड़ दिया जाता है। लूप से बाहर निकलने के बाद, दो मूल डेटासेट के जॉइन ऑपरेशन का समग्र आउटपुट प्राप्त होगा। यह तकनीक नीचे चित्र 1 में दिखाई गई है ।

चित्र 1: इटरेटिव ब्रॉडकास्ट हैश जॉइन को लागू करना

हालांकि, 'ब्रॉडकास्ट हैश जॉइन' के विपरीत, 'इटरेटिव ब्रॉडकास्ट जॉइन' केवल 'इनर जॉइन' तक ही सीमित है। यह फुल आउटर जॉइन, लेफ्ट जॉइन और राइट जॉइन को हैंडल नहीं कर सकता है। हालांकि, 'इनर जॉइन' के लिए, यह दोनों डेटासेट पर विषमता को संभाल सकता है।

3) सॉल्टेड सॉर्ट मर्ज जॉइन : ' सॉर्ट मर्ज ' दृष्टिकोण संसाधन की कमी के मामले में जॉइन को संभालने में बहुत मजबूत है। उसी का विस्तार करते हुए, ' सॉर्ट मर्ज ' के नमकीन संस्करण का बहुत प्रभावी ढंग से उपयोग किया जा सकता है, जब कोई छोटे गैर-तिरछे डेटासेट के साथ बड़े तिरछे डेटासेट में शामिल होना चाहता है, लेकिन निष्पादक की स्मृति पर बाधाएं हैं।

इसके अतिरिक्त, सॉल्टेड सॉर्ट मर्ज संस्करण का उपयोग बड़े तिरछे डेटासेट के साथ छोटे गैर-तिरछे डेटासेट के लेफ्ट जॉइन करने के लिए भी किया जा सकता है, जो ब्रॉडकास्ट हैश जॉइन के साथ संभव नहीं है, भले ही छोटे डेटासेट को निष्पादकों को प्रसारित किया जा सके। हालांकि, यह सुनिश्चित करने के लिए कि स्पार्क द्वारा सॉर्ट मर्ज जॉइन का चयन किया गया है, किसी को ' ब्रॉडकास्ट हैश जॉइन' दृष्टिकोण को बंद करना होगा । यह ' स्पार्क.एसक्यूएल.ऑटोब्रॉडकास्टजॉइन थ्रेशोल्ड ' को -1 पर सेट करके किया जा सकता है ।

' साल्टेड सॉर्ट मर्ज ' जॉइन की कार्यप्रणाली ' इटरेटिव ब्रॉडकास्ट हैश ' जॉइन के समान है। एक अतिरिक्त कॉलम ' नमक कुंजी' को तिरछे इनपुट डेटासेट में से एक में पेश किया गया है। इसके बाद, प्रत्येक रिकॉर्ड के लिए, ' नमक कुंजी ' कॉलम के लिए नमक कुंजी मानों की एक चयनित श्रेणी से यादृच्छिक रूप से एक संख्या असाइन की जाती है ।

तिरछे इनपुट डेटासेट को नमकीन करने के बाद, चयनित श्रेणी में नमक कुंजी मानों पर एक लूप शुरू किया जाता है। लूप में पुनरावृत्त होने वाले प्रत्येक नमक कुंजी मान के लिए, नमकीन इनपुट डेटासेट को पहले पुनरावृत्त नमक कुंजी मान के लिए फ़िल्टर किया जाता है, निस्पंदन के बाद, नमकीन फ़िल्टर किए गए इनपुट डेटासेट को अन्य अनसाल्टेड इनपुट डेटासेट के साथ आंशिक रूप से शामिल आउटपुट का उत्पादन करने के लिए जोड़ा जाता है। अंतिम सम्मिलित आउटपुट का उत्पादन करने के लिए, यूनियन ऑपरेटर का उपयोग करके सभी आंशिक रूप से जुड़े आउटपुट को एक साथ जोड़ दिया जाता है ।

' नमकीन सॉर्ट मर्ज ' दृष्टिकोण के लिए एक वैकल्पिक दृष्टिकोण भी मौजूद है । इसमें, प्रत्येक नमक कुंजी मान लूप में पुनरावृत्त होने के लिए, दूसरा गैर-स्क्यूड इनपुट डेटासेट एक आंशिक नमक समृद्ध डेटासेट बनाने के लिए नए ' नमक ' कॉलम में समान मान को दोहराकर वर्तमान पुनरावृत्त नमक कुंजी मान से समृद्ध होता है। ये सभी आंशिक समृद्ध डेटासेट दूसरे गैर-तिरछे डेटासेट के संयुक्त नमक समृद्ध डेटासेट संस्करण का उत्पादन करने के लिए ' संघ ' ऑपरेटर का उपयोग करके संयुक्त होते हैं। इसके बाद, पहले तिरछा नमकीन डेटासेट को दूसरे नमक समृद्ध डेटासेट के साथ जोड़ा जाता है ताकि अंतिम रूप से शामिल आउटपुट का उत्पादन किया जा सके। यह दृष्टिकोण नीचे चित्र 3 में दिखाया गया है :

चित्र 2: नमकीन सॉर्ट किए गए मर्ज जॉइन को लागू करना

एक अन्य वैकल्पिक दृष्टिकोण भी ' नमकीन सॉर्ट मर्ज ' दृष्टिकोण के लिए मौजूद है। इस दृष्टिकोण में, अतिरिक्त ' नमक कुंजी ' कॉलम के साथ तिरछे इनपुट डेटासेट को नमकीन करने के बाद, बिना नमक वाले गैर-तिरछे डेटासेट में एक ' नमक ' कॉलम भी पेश किया जाता है। ' नमक ' कॉलम में एक निश्चित मान (सभी अभिलेखों में) होता है जो पहले चयनित श्रेणी में नमक कुंजी के सभी मानों से बने सरणी के बराबर होता है। बाद में, इस डेटासेट को ' नमक ' कॉलम पर विस्फोटित किया जाता है। विस्फोटित डाटासेट को अंतिम रूप से जुड़े आउटपुट का उत्पादन करने के लिए ' नमक ' और ' नमक कुंजी ' की समानता पर एक अतिरिक्त जुड़ने की स्थिति के साथ पहले के नमकीन तिरछे इनपुट डेटासेट के साथ जोड़ा जाता है।

सॉल्टेड सॉर्ट मर्ज जॉइन फुल आउटर जॉइन को हैंडल नहीं कर सकता। साथ ही, यह दोनों इनपुट डेटासेट पर विषमता को संभाल नहीं सकता है। यह केवल लेफ्ट जॉइन श्रेणी (बाहरी, अर्ध और विरोधी) में बाएं डेटासेट में तिरछा को संभाल सकता है। इसी तरह, यह केवल राइट जॉइन श्रेणी में सही डेटासेट में तिरछा को संभाल सकता है।

4) AQE ( उन्नत क्वेरी निष्पादन ): AQE रनटाइम ऑप्टिमाइज़ेशन सुविधाओं का एक सूट है जो अब स्पार्क 3.0 से डिफ़ॉल्ट रूप से सक्षम है। इस सुइट पैक की एक प्रमुख विशेषता विषम डेटासेट के लिए जॉइन को स्वचालित रूप से अनुकूलित करने की क्षमता है।

AQE इस अनुकूलन को आम तौर पर एक गैर-स्क्यूड डेटासेट वाले तिरछे डेटासेट के ' सॉर्ट मर्ज जॉइन' के लिए करता है। AQE एक सॉर्ट मर्ज जॉइन के विभाजन चरण पर संचालित होता है, जहां दो इनपुट डेटासेट को पहले संबंधित जॉइन की के आधार पर विभाजित किया जाता है । फेरबदल के बाद ब्लॉक MapTasks द्वारा लिखे गए हैंविभाजन के दौरान, स्पार्क निष्पादन इंजन को प्रत्येक फेरबदल किए गए विभाजन के आकार के आंकड़े मिलते हैं। स्पार्क एक्ज़ीक्यूशन इंजन से उपलब्ध इन आँकड़ों के साथ, AQE कुछ विन्यास योग्य मापदंडों के साथ मिलकर निर्धारित कर सकता है कि कुछ विभाजन तिरछे हैं या नहीं। यदि कुछ विभाजन तिरछे पाए जाते हैं, तो AQE इन विभाजनों को छोटे विभाजनों में तोड़ देता है। यह ब्रेकडाउन विन्यास योग्य मापदंडों के एक सेट द्वारा नियंत्रक है। बड़े तिरछे विभाजन के टूटने से उत्पन्न छोटे विभाजन को फिर अन्य गैर-स्क्यूड इनपुट डेटासेट के संबंधित विभाजन की एक प्रति के साथ जोड़ दिया जाता है। प्रक्रिया नीचे चित्र 3 में दिखाई गई है।

चित्र 3: तिरछी जॉइन को संभालने का AQE तरीका।

निम्नलिखित कॉन्फ़िगरेशन पैरामीटर हैं जो AQE में स्क्यूड जॉइन ऑप्टिमाइजेशन फीचर को प्रभावित करते हैं:

"spark.sql.adaptive.skewJoin.enabled" : यह बूलियन पैरामीटर नियंत्रित करता है कि स्क्यूड जॉइन ऑप्टिमाइज़ेशन चालू है या बंद । डिफ़ॉल्ट मान सत्य है

"spark.sql.adaptive.skewJoin.skewedPartitionFactor": यह पूर्णांक पैरामीटर एक तिरछे विभाजन की व्याख्या को नियंत्रित करता है। डिफ़ॉल्ट मान 5 है।

"spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes": एमबी में यह पैरामीटर एक तिरछे विभाजन की व्याख्या को भी नियंत्रित करता है। डिफ़ॉल्ट मान 256 एमबी है।

एक विभाजन को तिरछा माना जाता है जब दोनों (विभाजन आकार> तिरछापार्टिशन फैक्टर * माध्य विभाजन आकार) और (विभाजन आकार> तिरछापार्टिशन थ्रेशोल्डइनबाइट्स) सत्य हैं।

AQE जैसे 'ब्रॉडकास्ट हैश जॉइन' और 'सॉल्टेड सॉर्ट मर्ज जॉइन' 'फुल आउटर जॉइन' को हैंडल नहीं कर सकते। साथ ही, यह दोनों इनपुट डेटासेट पर विषमता को संभाल नहीं सकता है। इसलिए, जैसा कि 'साल्टेड सॉर्टेड मर्ज जॉइन' के मामले में, AQE केवल लेफ्ट जॉइन श्रेणी (आउटर, सेमी और एंटी) में लेफ्ट डेटासेट में स्क्यू को हैंडल कर सकता है और राइट जॉइन कैटेगरी में राइट डेटासेट में स्क्यू को हैंडल कर सकता है।

5) ब्रॉडकास्ट मैपपार्टिशन जॉइन : ' ब्रॉडकास्ट मैपपार्टिशन जॉइन' एक बड़े तिरछे डेटासेट और छोटे नॉन-स्क्यूड डेटासेट के बीच एक तिरछी ' फुल आउटर जॉइन' को फास्ट करने का एकमात्र तंत्र है । इस दृष्टिकोण में, दो इनपुट डेटासेट में से छोटे को निष्पादकों को प्रसारित किया जाता है, जबकि जॉइन लॉजिक को मैन्युअल रूप से ' मैपपार्टिशन' ट्रांसफ़ॉर्मेशन में प्रोविज़न किया जाता है जिसे बड़े गैर-प्रसारित डेटासेट पर लागू किया जाता है।

हालांकि ' ब्रॉडकास्ट मैपपार्टिशन जॉइन' सभी प्रकार के जॉइन का समर्थन करता है और दोनों में से किसी एक या दोनों डेटासेट में तिरछा संभाल सकता है, केवल एक सीमा यह है कि इसके लिए निष्पादकों पर काफी मेमोरी की आवश्यकता होती है। छोटे इनपुट डेटासेट में से किसी एक को प्रसारित करने के लिए और मैन्युअल जॉइन प्रावधान के लिए इंटरमीडिएट इन-मेमोरी संग्रह का समर्थन करने के लिए बड़ी एक्ज़ीक्यूटर मेमोरी की आवश्यकता होती है।

मुझे उम्मीद है कि उपरोक्त ब्लॉग ने आपको अपने स्पार्क अनुप्रयोगों में तिरछी जॉइन को संभालने का एक अच्छा परिप्रेक्ष्य दिया है। इस पृष्ठभूमि के साथ, मैं आप सभी को इन विकल्पों में से एक का पता लगाने के लिए प्रोत्साहित करूंगा जब भी आप अपने स्पार्क एप्लिकेशन के जॉइन चरणों में स्ट्रगलर या मेमोरी ओवररन का सामना करते हैं।

यदि आप इनमें से प्रत्येक तकनीक से संबंधित कोड स्निपेट चाहते हैं, तो आप मुझसे @ लिंक्डइन पर संपर्क कर सकते हैं ।