2015-10-20 12 views
8

मैं निम्नलिखित कोड है पर:स्पार्क println खोने() stdout

val blueCount = sc.accumulator[Long](0) 
val output = input.map { data => 
    for (value <- data.getValues()) { 
    if (record.getEnum() == DataEnum.BLUE) { 
     blueCount += 1 
     println("Enum = BLUE : " + value.toString() 
    } 
    } 
    data 
}.persist(StorageLevel.MEMORY_ONLY_SER) 

output.saveAsTextFile("myOutput") 

फिर blueCount शून्य नहीं है, लेकिन मैं कोई println() उत्पादन मिल गया है! क्या मुझसे यहां कुछ छूट रहा है? धन्यवाद!

उत्तर

3

मैं एक UtilityFunction बनाकर चारों ओर यह काम करने में सक्षम था:

object PrintUtiltity { 
    def print(data:String) = { 
     println(data) 
    } 
} 
+5

द्वारा समझाया गया है यह क्यों काम कर रहा है? – angelcervera

+0

क्योंकि स्पार्क सोचता है कि यह प्रिंट फ़ंक्शन को कॉल करने के बजाय उपयोगिता फ़ंक्शन को कॉल कर रहा है। स्पार्क स्पष्ट रूप से (और व्यावहारिक रूप से नहीं कर सकता) अपने उपयोगिता समारोह में हर पंक्ति की जांच नहीं करता था। – Edamame

+1

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

13

यह एक वैचारिक सवाल यह है कि ...

कल्पना कीजिए कि आप एक बड़ा क्लस्टर, कई कार्यकर्ताओं से बना है चलो कहते हैं कि n श्रमिकों और उन श्रमिकों एक RDD या DataFrame के विभाजन का संग्रहण करने दे, कल्पना कीजिए कि आप एक map काम भर में शुरू उस डेटा, और कहा कि map अंदर आप एक print बयान है, सब से पहले:

  • कहाँ है कि डेटा बाहर प्रिंट किया जाएगा?
  • क्या नोड प्राथमिकता और क्या विभाजन है?
  • यदि सभी नोड समानांतर में चल रहे हैं, तो पहले कौन मुद्रित किया जाएगा?
  • यह प्रिंट कतार कैसे बनाई जाएगी?

उन बहुत से सवाल कर रहे हैं, इस प्रकार apache-spark के डिजाइनर/देखरेख किसी भी map-reduce आपरेशन के अंदर print बयान (इस में शामिल हैं accumulators और यहां तक ​​कि broadcast चर) के लिए किसी भी समर्थन ड्रॉप करने तार्किक फैसला किया।

यह भी समझ में आता है क्योंकि स्पार्क एक भाषा बहुत बड़ी डेटासेट के लिए डिज़ाइन की गई है। जबकि प्रिंटिंग परीक्षण और डिबगिंग के लिए उपयोगी हो सकती है, आप डेटाफ्रेम या आरडीडी की हर पंक्ति मुद्रित नहीं करना चाहेंगे क्योंकि उन्हें लाखों या अरबों पंक्तियों के लिए बनाया गया है! तो इन जटिल प्रश्नों का सामना क्यों करें जब आप पहली जगह प्रिंट नहीं करना चाहेंगे?

आदेश में इस साबित करने के लिए आप उदाहरण के लिए इस स्केला कोड चला सकते हैं में:

// Let's create a simple RDD 
val rdd = sc.parallelize(1 to 10000) 

def printStuff(x:Int):Int = { 
    println(x) 
    x + 1 
} 

// It doesn't print anything! because of a logic design limitation! 
rdd.map(printStuff) 

// But you can print the RDD by doing the following: 
rdd.take(10).foreach(println) 
+6

मैं println काम करता है का मानना ​​है कि ठीक: यह सिर्फ स्पार्क निष्पादक चला रहे कंप्यूटर पर stdout/stderr पर जाता है। तो जब तक कि आपके पास उन लॉगों में कैप्चर करने का कोई तरीका न हो, आप इसे कभी नहीं देख पाएंगे। यदि आप यार्न का उपयोग कर रहे हैं तो आपके लिए इसे प्रिंट करने के लिए एक आदेश है। – David

+0

जबकि तर्क वैध है स्पार्क कोड ड्रॉप करने के लिए किसी प्रकार का स्थैतिक विश्लेषण नहीं करता है। आउटपुट बस ड्राइवर 'STDOUT' पर नहीं जाता है जैसा कि @ डेविड –

संबंधित मुद्दे