अपाचे स्पार्क: किसी ज्वाइन पर रिपर्टिशनिंग, सॉर्टिंग और कैशिंग का प्रभाव


10

मैं खुद एक टेबल से जुड़ने पर स्पार्क के व्यवहार का पता लगा रहा हूं। मैं डेटाब्रिक्स का उपयोग कर रहा हूं।

मेरा डमी परिदृश्य है:

  1. डेटाफ़्रेम ए के रूप में एक बाहरी तालिका पढ़ें (अंतर्निहित फाइलें डेल्टा प्रारूप में हैं)

  2. डेटाफ्रेम ए के रूप में डेटाफ्रेम बी को केवल कुछ निश्चित कॉलम के साथ परिभाषित करें

  3. कॉलम 1 और कॉलम 2 पर डेटाफ्रेम ए और बी को मिलाएं

(हां, इसका कोई मतलब नहीं है, मैं स्पार्क के अंतर्निहित यांत्रिकी को समझने के लिए प्रयोग कर रहा हूं)

a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))

b = a.select("column1", "column2", "columnA")

c= a.join(b, how="left", on = ["column1", "column2"])

मेरा पहला प्रयास कोड को चलाने का था जैसा कि यह है (प्रयास 1)। मैं तो repartition और कैश करने की कोशिश की (प्रयास 2)

a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
.repartition(col("column1"), col("column2")).cache()

अंत में, मैंने पुनर्विचार किया, हल किया और कैश किया

 a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
.repartition(col("column1"), col("column2")).sortWithinPartitions(col("column1"), col("column2")).cache()

उत्पन्न संबंधित डैग संलग्न हैं।

मेरे प्रश्न हैं:

  1. प्रयास में क्यों 1 तालिका को कैश किया गया प्रतीत होता है भले ही कैशिंग स्पष्ट रूप से निर्दिष्ट नहीं किया गया है।

  2. InMemoreTableScan को हमेशा इस प्रकार के दूसरे नोड द्वारा अनुसरण क्यों किया जाता है।

  3. प्रयास में 3 कैशिंग दो चरणों में क्यों प्रतीत होते हैं?

  4. प्रयास में 3 WholeStageCodegen एक (और केवल एक) InMemoreTableScan का अनुसरण करता है।

प्रयास 1

प्रयास २

यहां छवि विवरण दर्ज करें


मुझे संदेह है कि जब स्रोत एक बाहरी तालिका है, तो DataFrame रीडर स्वचालित रूप से डेटा को कैश करता है। मेरे पास ऐसी ही स्थिति है जहां मैं एक डेटाबेस टेबल से डेटा पढ़ रहा हूं, जबकि सक्षम होने पर "एप्लिकेशन विवरण UI" पर "एसक्यूएल" टैब डाउनलोड किया जा रहा है, मुझे डाउनलोड की जाने वाली पंक्तियों की संख्या दिखाती है, लेकिन निर्दिष्ट स्थान पर अभी तक कोई फ़ाइल सहेजी नहीं गई है । मुझे लगता है कि यह गिनती जानता है क्योंकि इसमें डेटा कहीं है और यह वही है जो DAG पर दिखाई देता है। यदि आप स्थानीय रूप से पाठ फ़ाइल से डेटा पढ़ते हैं, तो आप कैश स्थिति नहीं देखेंगे।
सलीम

जवाबों:


4

इन 3 योजनाओं में आप जो देख रहे हैं, वह डेटाब्रिक्स रनटाइम और स्पार्क का मिश्रण है।

DataBricks रनटाइम 3.3+ को चलाने के दौरान सबसे पहले, कैशिंग स्वचालित रूप से सभी लकड़ी की छत फ़ाइलों के लिए सक्षम है। उस के लिए कॉन्फ़िगर करना: spark.databricks.io.cache.enabled true

आपकी दूसरी क्वेरी के लिए, InMemoryTableScan दो बार हो रहा है क्योंकि राइट जब ज्वाइन किया गया था, तो स्पार्क ने समानांतर में डेटासेट ए और डेटासेट बी की गणना करने की कोशिश की थी। अलग-अलग निष्पादकों को उपरोक्त कार्य सौंपे जाने पर, दोनों को (DataBricks) कैश से तालिका को स्कैन करना होगा।

तीसरे के लिए, InMemoryTableScan अपने आप में कैशिंग का उल्लेख नहीं करता है। इसका मतलब सिर्फ यह है कि जो भी योजना उत्प्रेरक बने, उसमें कैश्ड टेबल को कई बार स्कैन करना शामिल है।

पुनश्च: मैं बिंदु 4 की कल्पना नहीं कर सकता :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.