स्पार्क, एक एकल RDD को दो में विभाजित करना


10

मेरे पास एक बड़ा डेटासेट है जिसे मुझे विशिष्ट मापदंडों के अनुसार समूहों में विभाजित करने की आवश्यकता है। मैं चाहता हूं कि नौकरी यथासंभव कुशलता से संसाधित हो। मैं ऐसा करने के दो तरीकों की कल्पना कर सकता हूं

विकल्प 1 - मूल आरडीडी और फिल्टर से मानचित्र बनाएं

def customMapper(record):
    if passesSomeTest(record):
        return (1,record)
    else:
        return (0,record)

mappedRdd = rddIn.map(lambda x: customMapper(x))
rdd0 = mappedRdd.filter(lambda x: x[0]==0).cache()
rdd1 = mappedRdd.filter(lambda x: x[1]==1).cache()

विकल्प 2 - मूल आरडीडी को सीधे फ़िल्टर करें

def customFilter(record):
    return passesSomeTest(record)

rdd0 = rddIn.filter(lambda x: customFilter(x)==False).cache()
rdd1 = rddIn.filter(customFilter).cache()

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


मैं भी एक बहुत ही इसी तरह की समस्या के साथ अपने आप को पाया, और वास्तव में एक समाधान नहीं मिला। लेकिन वास्तव में जो होता है वह इस कोड से स्पष्ट नहीं होता है, क्योंकि स्पार्क में 'आलसी मूल्यांकन' होता है और यह केवल वही क्रियान्वित करने में सक्षम होता है, जिसे वास्तव में निष्पादित करने की आवश्यकता होती है, और नक्शे, फ़िल्टर के संयोजन और जो कुछ भी एक साथ किया जा सकता है। तो संभवतः आप जो वर्णन करते हैं, वह एकल पास में हो सकता है। हालांकि यह बताने के लिए आलसी मूल्यांकन तंत्र के साथ पर्याप्त परिचित नहीं है। वास्तव में मैंने सिर्फ .cache () पर ध्यान दिया। हो सकता है कि केवल एक .cache () करने और पूर्ण परिणाम प्राप्त करने का एक तरीका है?
user3780968

जवाबों:


9

सबसे पहले मैं आपको बता दूं कि मैं स्पार्क विशेषज्ञ नहीं हूं; मैं पिछले कुछ महीनों में इसका काफी उपयोग कर रहा हूं, और मुझे विश्वास है कि मैं अब इसे समझ गया हूं, लेकिन मैं गलत हो सकता हूं।

तो, अपने सवालों का जवाब दे:

a।) वे समान हैं, लेकिन उस तरीके से नहीं जैसे आप इसे देख रहे हैं; स्पार्क ग्राफ को अनुकूलित नहीं करेगा यदि आप आश्चर्यचकित हैं, लेकिन customMapperफिर भी दोनों मामलों में दो बार निष्पादित किया जाएगा; यह इस तथ्य के कारण है कि स्पार्क के लिए, rdd1और rdd2दो पूरी तरह से अलग RDD हैं, और यह लीफ़्स से शुरू होने वाले ट्रांसफ़ॉर्मेशन ग्राफ़ को नीचे-ऊपर बनाएगा; इसलिए विकल्प 1 में अनुवाद होगा:

rdd0 = rddIn.map(lambda x: customMapper(x)).filter(lambda x: x[0]==0).cache()
rdd1 = rddIn.map(lambda x: customMapper(x)).filter(lambda x: x[0]==1).cache()

जैसा कि आपने कहा, customMapperदो बार निष्पादित किया गया है (इसके अलावा, दो बार भी rddInपढ़ा जाएगा, जिसका अर्थ है कि यदि यह डेटाबेस से आता है, तो यह धीमा भी हो सकता है)।

बी।) एक तरीका है, आपको बस cache()सही जगह पर चलना है:

mappedRdd = rddIn.map(lambda x: customMapper(x)).cache()
rdd0 = mappedRdd.filter(lambda x: x[0]==0)
rdd1 = mappedRdd.filter(lambda x: x[0]==1)

ऐसा करने से, हम स्पार्क बता रहे हैं कि यह आंशिक परिणामों को संग्रहीत कर सकता है mappedRdd; यह तब rdd1और इन दोनों के लिए आंशिक परिणामों का उपयोग करेगा rdd2। स्पार्क दृष्टिकोण से यह इसके बराबर है:

mappedRdd = rddIn.map(lambda x: customMapper(x)).saveAsObjectFile('..')
# forget about everything
rdd0 = sc.objectFile('..').filter(lambda x: x[0]==0)
rdd1 = sc.objectFile('..').filter(lambda x: x[0]==1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.