जवाबों:
यह मूल रूप से समस्याएं हैं जो बहुत बड़ी हैं, लेकिन कठिन नहीं हैं। ट्रैवलिंग सेल्समैन किसी भी दिए गए शहरों के बीच की दूरी पर महत्वपूर्ण रूप से निर्भर करता है, इसलिए जब इसे कई हिस्सों में तोड़ा जा सकता है, तो आंशिक परिणाम नहीं मिल सकते हैं ताकि वैश्विक रूप से इष्टतम समाधान निकल जाए (ठीक है, शायद नहीं; यदि आप एक तरीका जानते हैं; कृपया अपने फील्ड्स मेडल के लिए आवेदन करें)।
दूसरी ओर, एक विशालकाय कोष में शब्दों की बारंबारता की गणना तुच्छ रूप से विभाजन योग्य है, और तुच्छ रूप से पुन: संयोजनीय है (आप बस वाहिनी को धनिया के खंडों के लिए अभिकलित करते हैं), इसलिए मानचित्र-घटा स्पष्ट समाधान है।
व्यवहार में, अधिक समस्याएं आसानी से नहीं की तुलना में पुनर्संयोजित होती हैं, इसलिए यह निर्णय कि किसी कार्य को समानांतर करना है या नहीं, कार्य कितना बड़ा है और इससे कितना कम कठिन है।
वितरित कंप्यूटिंग का उपयोग करके समस्या को कुशलता से हल किया जा सकता है?
यदि इस प्रश्न का उत्तर हां है, तो आपके पास MapReduce के लिए एक उम्मीदवार की समस्या है। ऐसा इसलिए है क्योंकि समस्या पैटर्न स्वयं को छोटी पृथक समस्याओं में विभाजित होने के लिए उधार देता है।
आपका कार्य: इस पुस्तक को पार करें
एक उदाहरण इस ilustrate के लिए अच्छी तरह से काम करता है। आपके पास एक बड़ा दस्तावेज़ है ( हर्मन मेलविल द्वारा मोबी डिक ) और आपका काम इसमें इस्तेमाल किए गए सभी शब्दों का एक आवृत्ति विश्लेषण करना है।
अनुक्रमिक दृष्टिकोण
आप इस क्रमिक रूप से अपना सबसे तेज़ मशीन प्राप्त कर सकते हैं (आप चारों ओर बहुत झूठ बोल रहे हैं) और पाठ से शुरू करके हर शब्द के हैश मानचित्र (कुंजी) को बनाए रखने और हर बार आवृत्ति (मान) बढ़ाते हुए। आप एक शब्द को पार्स करते हैं। सरल, सीधा और धीमा।
MapReduce दृष्टिकोण
एक अलग दृष्टिकोण से इसे स्वीकार करते हुए, आप ध्यान दें कि आपके पास ये सभी अतिरिक्त मशीनें पड़ी हैं और आप इस कार्य को विखंडू में विभाजित कर सकते हैं। प्रत्येक मशीन को हैश मैप में पार्स करने के लिए टेक्स्ट का 1Mb ब्लॉक दें और फिर सभी हैश मैप्स को एक सिंगल रिजल्ट में से मिलाएं। यह एक स्तरित MapReduce समाधान है।
पाठ की एक पंक्ति को पढ़ने और शब्दों को इकट्ठा करने की प्रक्रिया मैप चरण है (आप अपनी आवृत्ति 1,2,3 आदि के साथ लाइन में शब्दों का प्रतिनिधित्व करने वाला एक सरल नक्शा बनाते हैं), फिर Reduce चरण वह होता है जब प्रत्येक मशीन अपनी लाइन से टकराती है एक एकल नक्शे में नक्शे।
समग्र समाधान एक और कमी चरण से आता है जहां सभी कुल मानचित्रों को एक अंतिम मानचित्र में एकत्र किया जाता है (वह शब्द फिर से)। थोड़ा और अधिक जटिल, व्यापक रूप से समानांतर और त्वरित।
सारांश
इसलिए, संक्षेप में बताएं, यदि आपकी समस्या कुंजी में उन मूल्यों, मूल्यों, कुल संचालनों का प्रतिनिधित्व करती है जो अलगाव में हैं, तो आपको MapReduce के लिए एक उम्मीदवार की समस्या है।
MapReduce पैटर्न कार्यात्मक प्रोग्रामिंग की दुनिया से लिया गया है। यह समानांतर में डेटा-संरचना पर एक कैटामोर्फिज़्म नामक कुछ को लागू करने के लिए एक प्रक्रिया है। फंक्शनल प्रोग्रामर कैटामोफ़िज़म का उपयोग बहुत अधिक हर साधारण परिवर्तन या संक्षेपण के लिए करते हैं।
अपने डेटा को एक पेड़ मानते हुए, निर्णायक कारक यह है कि क्या आप नोड के लिए केवल उस नोड में निहित डेटा और उसके बच्चों के लिए गणना किए गए मूल्यों का उपयोग करके एक मान की गणना कर सकते हैं।
उदाहरण के लिए आप एक कायापलट का उपयोग करके एक पेड़ के आकार की गणना कर सकते हैं; आप सभी बच्चों के लिए गणना किए गए मानों की राशि को जोड़ेंगे।
यह डब्लूपीआई - मैप रिड्यूस (पीपीटी) के अनुप्रयोग आपके लिए रूचिकर हो सकते हैं। यह एमआर के विभिन्न अनुप्रयोगों पर चर्चा करता है, और चर्चा किए गए मामलों में से एक के रूप में, यह दिखाता है कि 100 EC2 उदाहरणों और 24 घंटों का उपयोग करते हुए, न्यूयॉर्क टाइम्स स्कैन किए गए लेखों के 4TB को PDF दस्तावेज़ों के 1.5TB में बदलने में सक्षम था।
उदाहरणों का एक और सेट जहां एमआर ने प्रदर्शन को तेज करने में मदद की: एस्टर - एसक्यूएल मैप रिड्यूस एसक्यूएल-मैप रिड्यूस टेक्नोलॉजी के कुछ केस स्टडीज को दिखाता है जिसमें फ्रॉड डिटेक्शन, ट्रांसफॉर्मेशन और अन्य शामिल हैं।
मैप / रिड्यूस एक विशिष्ट प्रकार के एल्गोरिदम का एक विशिष्ट रूप है। आप इसका उपयोग एक विशाल डेटा सेट को दूसरे डेटा सेट में बदलने के लिए करते हैं। (परिणाम डेटासेट भारी हो सकता है या नहीं भी हो सकता है।) यदि आप स्थिर डेटा इनपुट के परिणामस्वरूप स्थिर डेटा आउटपुट सेट नहीं करना चाहते हैं, तो मैप / रिड्यूस उचित नहीं है। मैप / रिड्यूस आपको आसानी से बता सकता है कि मैनहट्टन फोन बुक में कितने जॉन स्मिथ हैं, लेकिन यह वेब सर्वर बनाने के लिए अच्छी तरह से अनुकूल नहीं है।
मैप / कम करने का तरीका है:
परिणाम यह है कि (k1, v1) जोड़े की एक सूची (v3) s की सूची में तब्दील हो जाती है। (बेशक, मूल्य "v3" एक समग्र हो सकता है जिसमें k2 शामिल है, जिसे k1 के बराबर परिभाषित किया जा सकता है।)
तो आप इसका उपयोग करें:
यदि आपके पास इतना डेटा है कि इसे एक या दो सर्वरों के माध्यम से क्रमिक रूप से चलाने के साथ शुरू करने में बहुत लंबा समय लगेगा, और
आप मूल्यों या प्रमुख मूल्य जोड़े की सूची होने के आउटपुट डेटा की कल्पना कर सकते हैं (आम तौर पर बहुत मुश्किल नहीं है जब आपको याद है "कुंजी" केवल "अद्वितीय लेबल" का मतलब है), और
जो भी संबंध है, आप सुनिश्चित हैं कि इनपुट डेटा का प्रत्येक टुकड़ा केवल एक आउटपुट कुंजी के लिए आउटपुट मूल्य को प्रभावित करता है।
यदि आपके डेटा को सभी एकल सर्वर द्वारा क्रमिक रूप से संसाधित किया जा सकता है, तो चूंकि वह प्रमुख कंप्यूटिंग प्रतिमान है (जो सर्वर के लिए बनाया गया है और प्रोग्रामर को प्रशिक्षित किया जाता है), एकल सर्वर का उपयोग करें।
मैप चरण में आउटपुट कुंजी द्वारा सभी इनपुट डेटा को विभाजित करना है। इसे आउटपुट कुंजी से जुड़े आउटपुट मान का उत्पादन नहीं करना पड़ता (जो कि कम चरण द्वारा किया जाता है), लेकिन इसे प्रत्येक इनपुट कुंजी मूल्य जोड़ी को अधिकतम एक आउटपुट कुंजी के मूल्य पर योगदान करने के लिए विशिष्ट रूप से असाइन करना पड़ता है। यदि डेटा बहुत अधिक परस्पर संबंधित है, तो नक्शा कम करना समस्या को संभालने में सक्षम नहीं हो सकता है। दूसरी ओर, यह सिर्फ यह हो सकता है कि आपको कई राउंड मैप का उपयोग करने / कम करने की आवश्यकता है।
यदि आप यह पता नहीं लगा सकते हैं कि अपने डेटा ट्रांसफ़ॉर्मेशन को मैप में कैसे बदलें / कम करें, तो निश्चित रूप से इसका कोई हल नहीं है।
यह पता लगाने की एक वास्तविक कला है कि क्या किसी समस्या को किसी चीज़ में विघटित किया जा सकता है / नक्शा कम कर सकता है। उदाहरण के लिए, v1 और v2 इनपुट या आउटपुट डेटा सेट में बिल्कुल भी नहीं हो सकता है। यदि आप केवल इनपुट डेटा में अद्वितीय आइटम गिनना चाहते हैं, तो k1 = k2 = एक आइटम और v1 = v2 = 1 या 0 या वास्तव में कुछ भी। कम करें बस v3 का उत्पादन करता है क्योंकि k2 की संख्या का योग दिया गया था।
इसलिए यह कहना मुश्किल है कि मैप / रिड्यूस का उपयोग करके डेटा परिवर्तन नहीं किया जा सकता है, लेकिन ऊपर आपको कुछ गाइडपोस्ट दिए गए हैं।
MapReduce किसी भी समस्या पर काम करता है जो अमूर्तन के कुछ स्तर पर ठीक 2 कार्यों से बना होता है। पहला फ़ंक्शन इनपुट सेट में प्रत्येक आइटम पर लागू होता है, और दूसरा फ़ंक्शन परिणामों को एकत्र करता है।
इसलिए, जब भी आप (एन) इनपुट्स से (1) परिणाम प्राप्त करना चाहते हैं, और सभी इनपुट्स (1) फ़ंक्शन द्वारा जांच / उपयोग किए जा सकते हैं, आप मैपरेड का उपयोग कर सकते हैं। फिर, यह अमूर्तता के कुछ विशिष्ट स्तर पर है। (1) फ़ंक्शन कुछ ग्रुपिंग फ़ंक्शन हो सकता है जो इनपुट की जांच करता है और निर्णय लेता है कि कौन से अन्य कार्यों का उपयोग करना है।
यह तब उपयोगी होता है जब आप पहले से नहीं जानते हैं कि आपके पास कितना इनपुट होगा, जब आपको काम की "इकाइयों" को साझा करने की आवश्यकता होती है, या जब आप पूरे परिणाम का प्रतिनिधित्व करने के लिए एक ही रिटर्न चाहते हैं (IE पांच हजार यूनिट परीक्षण चल रहा है , और यदि x% से कम विफल रहता है, तो सफलता लौटाएं)।
यहाँ अधिकांश उत्तर यह समझाने के लिए भिन्न हैं कि मानचित्र क्या घटाता है, जो मान्य है। लेकिन इस सवाल का जवाब देने के लिए कि कौन सा पैटर्न संकेत करेगा कि आप मानचित्र को कम करने में सक्षम हो सकते हैं, वास्तव में इसका पता नहीं है।
यदि भोली, गैर कार्यात्मक, जिस समस्या को आप देख रहे हैं, उसके क्रियान्वयन में कुछ पर लूपिंग शामिल है और फिर लूप के अंदर से कुछ स्थिति के साथ लूप के बाहर कुछ अद्यतन करना, संभावना है कि आपके पास कुछ ऐसी चीजें हैं जो पोर्ट मैप को कम करने के लिए अच्छी तरह से हैं। विशेष रूप से यदि आप केंद्रीय राज्य के अद्यतन को केवल दो मापदंडों के साथ काम करने वाले फ़ंक्शन के लिए सामान्य कर सकते हैं और गारंटी दे सकते हैं कि यह फ़ंक्शन सराहनीय और साहचर्य है।
यदि आप सही है, तो मानचित्र को कम करने का उपयोग करना चाहते हैं, तो यह दो गुना है: 1) यदि आप नक्शे में चीजों को तोड़ते हैं और कार्यों को कम करते हैं, तो यह थोड़ा क्लीनर और परीक्षण और डिबग करना आसान हो सकता है। 2) मानचित्र कम करने वाले कार्य स्टेटलेस होते हैं और समवर्ती रूप से चलाए जा सकते हैं, जो चीजों को गति देते हैं यदि आपके पास कई सीपीयू उपलब्ध हैं और कुछ ऐसा हैडूप या स्पार्क है जो क्लस्टर में चीजों को चलाने के लिए इसका उपयोग करता है।
यह बहुत अच्छा है यदि आप बहुत सारे सामानों पर लूपिंग कर रहे हैं, लेकिन आपका माइलेज आपके नक्शे / कॉम्प्लेक्स के आधार पर भिन्न हो सकता है। यह अनुक्रमिक श्रृंखला या मैप रिडक्शन के पेड़ के साथ समाप्त होने के लिए काफी आम है, जहां अंत में सब कुछ अभी भी श्रृंखला के अंत में कुछ जटिल कटौती कदम पर अड़चन है। उदाहरण के लिए, कई ग्राफ़ एल्गोरिदम केवल मानचित्र को कम करने के साथ कुशलतापूर्वक स्केल करना मुश्किल है।
सरलतम उदाहरण जो नक्शे को कम करने के साथ अच्छी तरह से काम करता है, सामान की गिनती कर रहा है, जो कि बहुत सस्ती कमी है। यही कारण है कि शब्द गणना मानचित्र कम करने के लिए अक्सर उपयोग किया जाने वाला उदाहरण है। आप उस usecase के साथ प्रदर्शन के लिए रैखिक मापनीयता की बहुत उम्मीद कर सकते हैं: आपके द्वारा जोड़ा गया प्रत्येक सीपीयू इसे तेज बनाता है।
यदि आप बहुत कार्यात्मक प्रोग्रामिंग करते हैं, तो आप उन परिस्थितियों में दौड़ना शुरू कर देते हैं जो सामान्य मानचित्र के लिए कहते हैं और कम करते हैं। आप शायद उन्हें अनिवार्य प्रोग्रामिंग में भी देख सकते हैं, लेकिन उन्हें छोरों और संचायक के मुखौटे के पीछे नहीं पहचानते हैं।
हाल ही में मेरे लिए आया एक उदाहरण के रूप में, मैं हास्केल में एक पार्सर पर काम कर रहा हूं। अपने पार्सर का परीक्षण करने के लिए, मैं पार्सर के माध्यम से स्ट्रिंग के टुकड़े की एक सूची को पंप करता हूं, और फिर मैं एक भी स्ट्रिंग प्राप्त करना चाहता हूं जिसे मैं अपने परिणामों का आउटपुट देख सकता हूं कि क्या यह सही है। तो ऐसा दिखता है:
--my initial set of test data, a list
tests = ["string1", "string2", "string3", ...]
--Map Step: turn strings into parsed results
--note the type, which demonstrates the map
applyParser :: [String] -> [Token]
--The actual function
applyParser input = map parser input
--Second map, turn tokens into output
showTokens :: [Token] -> [String]
showTokens t = map show t
--Reduce step, concat the results
combineResults :: [String] -> String
--In haskell, reduce is the foldl function, which takes an operation to fold with, a starting element, and a list to fold on
combineResults strings = foldl concat "" strings
--Finished program
testParser = print (combineResults(showTokens(applyParser tests)))
बेशक, यह सिर्फ शैक्षणिक है। मेरा वास्तविक कोड थोड़ा अलग दिखता है, और अधिक आंतरिक कार्यों का उपयोग करता है (जैसे कि fold concat
हास्केल को पहले से ही ऐसा करने की आवश्यकता नहीं unlines
है[String]->String
)। मेरा मुख्य मुद्दा यह था कि जब मैंने शुरुआत की थी, तब मैंने मैप का उपयोग नहीं किया था / घटाया था, यह सिर्फ मेरी जरूरतों के अनुरूप था। मैं सूचियों के साथ कुछ सामान करना चाहता था, फिर मेरी सूची को आउटपुट के एक तत्व में बदल दिया। मानचित्र का उपयोग / कम स्वाभाविक रूप से उभरा।
स्ट्रिंग प्रसंस्करण (पार्सिंग की तरह) मानचित्र में कमी का एक बहुत स्पष्ट उपयोग है, मानचित्रण इनपुट पाठ पर विभिन्न परिवर्तनों का अनुप्रयोग है, और इसे परिणाम पाठ को फिर से आउटपुट के रूप में एक साथ रखना कम करता है। इसी तरह, एक कंपाइलर समान हो सकता है, जो एब्सट्रैक्ट सिंटैक्स ट्री तत्वों की धारा को एक बेहतर रूप (आशावादी) में बदलने के लिए सिलवटों का उपयोग कर सकता है।
क्या यह समानांतर है?
किसी भी समानांतर समस्या अनिवार्य रूप से नक्शा और गुना है; इसके विपरीत, नक्शा कदम स्वाभाविक रूप से समानांतर है (और तह कदम हो सकता है, जिस संरचना के आधार पर यह तह है), इसलिए यह एक द्विदिश संपत्ति है।
कहते हैं कि आप सर्वर का एक समूह खोज रहे हैं और कोई भी उस पल में प्रतिक्रिया देने में असमर्थ है। MapReduce क्या करेगा क्योंकि यह उस पेड़ के नोड को बड़े मानचित्र तक नहीं पहुंचा सकता है, यह बाद में इसके लिए पुनर्निर्धारित होगा और फिर या तो मैप या रिड्यूस का प्रदर्शन करेगा। अनिवार्य रूप से यह वातावरण में सॉफ्टवेयर और हार्डवेयर की अप्रत्याशितता के साथ उपलब्ध सभी सूचनाओं की गारंटी देने की कोशिश करता है।
यहाँ उन मुख्य प्रश्नों का उपयोग किया गया है, जिनका उपयोग करने के निर्णय की जांच करने के लिए मैं उपयोग करता हूं (या नहीं) MapReduce।
क्या मैं जिस समस्या को हल करने की कोशिश कर रहा हूं, वह मैप और रिड्यूस ऑपरेशन में है।
वास्तव में, यह एक सामान्य "विभाजित और जीतना" पैटर्न है, ताकि गणना को वितरित करने के समाधान को उदारतापूर्वक लिखा जा सके।
एक सरल उदाहरण एक बड़े दस्तावेज़ की तरह है। समस्या यह है कि आप उस दस्तावेज़ में कितने अक्षरों को गिनना चाहते हैं। एक मशीन पर चलने के बजाय, आप इसे दस्तावेज़ में सभी शब्दों की एक सरणी में तोड़ सकते हैं। तब आप प्रत्येक शब्द को व्यक्तिगत रूप से संसाधित कर सकते हैं, और परिणाम वापस एक साथ।
पैटर्न उपयोगी है, क्योंकि एक बार जब आप एक सामान्य नक्शा प्राप्त करते हैं / कार्यान्वयन को कम करते हैं, तो आप उसी सॉफ़्टवेयर परत का उपयोग करके किसी भी समस्या को हल कर सकते हैं, आपको बस इसके संदर्भ में अपनी समस्या को व्यक्त करने की आवश्यकता है।