Hadoop में छोटी फाइलें एक बड़ी समस्या है - या, कम से कम, वे हैं यदि इस विषय पर उपयोगकर्ता सूची में प्रश्नों की संख्या कुछ भी हो। इस पोस्ट में मैं समस्या को देखूंगा, और कुछ सामान्य समाधानों की जांच करूंगा।
छोटी फ़ाइलों और HDFS के साथ समस्या
एक छोटी फ़ाइल वह होती है जो HDFS ब्लॉक आकार (डिफ़ॉल्ट 64MB) से काफी छोटी होती है। यदि आप छोटी फ़ाइलें संग्रहीत कर रहे हैं, तो संभवतः आपके पास उनमें से बहुत सी फ़ाइलें हैं (अन्यथा आप Hadoop की ओर नहीं मुड़ेंगे), और समस्या यह है कि HDFS बहुत सारी फ़ाइलों को संभाल नहीं सकता है।
एचडीएफएस में प्रत्येक फ़ाइल, निर्देशिका और ब्लॉक को नामेनोड की स्मृति में एक वस्तु के रूप में दर्शाया जाता है, जिनमें से प्रत्येक अंगूठे के नियम के रूप में 150 बाइट्स पर कब्जा कर लेता है। तो 10 मिलियन फाइलें, जिनमें से प्रत्येक एक ब्लॉक का उपयोग करती है, लगभग 3 गीगाबाइट मेमोरी का उपयोग करेगी। इस स्तर से बहुत आगे तक स्केलिंग करना वर्तमान हार्डवेयर के साथ एक समस्या है। निश्चित रूप से एक अरब फाइलें संभव नहीं हैं।
इसके अलावा, एचडीएफएस छोटी फाइलों को कुशलता से एक्सेस करने के लिए तैयार नहीं है:यह मुख्य रूप से बड़ी फाइलों की स्ट्रीमिंग एक्सेस के लिए डिज़ाइन किया गया है। छोटी फ़ाइलों के माध्यम से पढ़ने से आम तौर पर प्रत्येक छोटी फ़ाइल को पुनः प्राप्त करने के लिए डेटानोड से डेटानोड तक बहुत सारी खोज और बहुत सारी छलांग लगती है, जो सभी एक अक्षम डेटा एक्सेस पैटर्न है।
छोटी फ़ाइलों और MapReduce के साथ समस्या
मानचित्र कार्य आमतौर पर एक समय में इनपुट के एक ब्लॉक को संसाधित करते हैं (डिफ़ॉल्ट FileInputFormat
. का उपयोग करके) ) यदि फ़ाइल बहुत छोटी है और उनमें से बहुत सारे हैं, तो प्रत्येक मानचित्र कार्य बहुत कम इनपुट को संसाधित करता है, और बहुत अधिक मानचित्र कार्य होते हैं, जिनमें से प्रत्येक अतिरिक्त बहीखाता ओवरहेड लगाता है। 16 64MB ब्लॉक में टूटी हुई 1GB फ़ाइल और 10,000 या उससे अधिक 100KB फ़ाइलों की तुलना करें। 10,000 फाइलें एक-एक मानचित्र का उपयोग करती हैं, और कार्य का समय एकल इनपुट फ़ाइल वाले समकक्ष की तुलना में दसियों या सैकड़ों गुना धीमा हो सकता है।
बहीखाता पद्धति को कम करने में मदद करने के लिए कुछ विशेषताएं हैं:कार्य JVM एक JVM में कई मानचित्र कार्यों को चलाने के लिए पुन:उपयोग करता है, जिससे कुछ JVM स्टार्टअप ओवरहेड से बचा जाता है (देखें mapred.job.reuse.jvm.num.tasks
) कोड> संपत्ति), और MultiFileInputSplit
जो प्रति मानचित्र एक से अधिक विभाजन चला सकता है।
छोटी फ़ाइलें क्यों बनाई जाती हैं?
कम से कम दो मामले हैं
- फ़ाइलें एक बड़ी तार्किक फ़ाइल के टुकड़े हैं। चूंकि एचडीएफएस ने हाल ही में एपेंड का समर्थन किया है, असीमित फाइलों (जैसे लॉग फाइल) को सहेजने के लिए एक बहुत ही सामान्य पैटर्न उन्हें एचडीएफएस में टुकड़ों में लिखना है।
- फ़ाइलें स्वाभाविक रूप से छोटी हैं। छवियों के एक बड़े कोष की कल्पना करें। प्रत्येक छवि एक विशिष्ट फ़ाइल है, और उन्हें एक बड़ी फ़ाइल में संयोजित करने का कोई स्वाभाविक तरीका नहीं है।
इन दो मामलों के लिए अलग-अलग समाधान की आवश्यकता होती है। पहले मामले के लिए, जहां फ़ाइल रिकॉर्ड से बनी है, HDFS के sync()
को कॉल करके समस्या से बचा जा सकता है विधि हर बार बड़ी फ़ाइलों को लगातार लिखने के लिए। वैकल्पिक रूप से, छोटी फ़ाइलों को एक साथ जोड़ने के लिए प्रोग्राम लिखना संभव है।
दूसरे मामले के लिए, फ़ाइलों को किसी तरह से समूहित करने के लिए किसी प्रकार के कंटेनर की आवश्यकता होती है। Hadoop यहां कुछ विकल्प प्रदान करता है।
HAR फ़ाइलें
नामेनोड की मेमोरी पर दबाव डालने वाली बहुत सारी फाइलों की समस्या को कम करने के लिए Hadoop आर्काइव्स (HAR फाइलें) को HDFS में 0.18.0 में पेश किया गया था। एचएआर फाइलें एचडीएफएस के शीर्ष पर एक स्तरित फाइल सिस्टम बनाकर काम करती हैं। hadoop archive
. का उपयोग करके एक HAR फ़ाइल बनाई जाती है कमांड, जो कम संख्या में एचडीएफएस फाइलों में संग्रहित की जा रही फाइलों को पैक करने के लिए मैपरेडस जॉब चलाता है। HAR फ़ाइल सिस्टम का उपयोग करने वाले क्लाइंट के लिए कुछ भी नहीं बदला है:सभी मूल फ़ाइलें दृश्यमान और पहुंच योग्य हैं (यद्यपि har:// का उपयोग करके) यूआरएल)। हालांकि, एचडीएफएस में फाइलों की संख्या कम कर दी गई है।
एचएआर में फाइलों के माध्यम से पढ़ना एचडीएफएस में फाइलों के माध्यम से पढ़ने से अधिक कुशल नहीं है, और वास्तव में धीमा हो सकता है क्योंकि प्रत्येक एचएआर फाइल एक्सेस के लिए दो इंडेक्स फाइल पढ़ने के साथ-साथ डेटा फाइल पढ़ने की आवश्यकता होती है (आरेख देखें)। और यद्यपि HAR फ़ाइलों का उपयोग MapReduce के इनपुट के रूप में किया जा सकता है, कोई विशेष जादू नहीं है जो नक्शे को HDFS ब्लॉक पर HAR सह-निवासी की सभी फ़ाइलों पर संचालित करने की अनुमति देता है। एक इनपुट प्रारूप बनाना संभव होना चाहिए जो एचएआर में फाइलों के बेहतर इलाके का लाभ उठा सके, लेकिन यह अभी तक अस्तित्व में नहीं है। ध्यान दें कि MultiFileInputSplit, HADOOP-4565 में सुधार के साथ ही नोड लोकल में विभाजित फ़ाइलों को चुनने के लिए, प्रति छोटी फ़ाइल की तलाश की आवश्यकता होगी। सीक्वेंसफाइल की तुलना में इसका प्रदर्शन देखना दिलचस्प होगा, कहते हैं। वर्तमान समय में HARs संभवत:पूरी तरह से अभिलेखीय उद्देश्यों के लिए उपयोग किए जाते हैं।
अनुक्रम फ़ाइलें
"छोटी फ़ाइलों की समस्या" के बारे में प्रश्नों की सामान्य प्रतिक्रिया है:एक SequenceFile का उपयोग करें। यहां विचार यह है कि आप फ़ाइल नाम को कुंजी के रूप में और फ़ाइल सामग्री को मान के रूप में उपयोग करते हैं। यह व्यवहार में बहुत अच्छा काम करता है। 10,000 100केबी फाइलों पर वापस जाकर, आप उन्हें एक सीक्वेंसफाइल में डालने के लिए एक प्रोग्राम लिख सकते हैं, और फिर आप उन्हें सीक्वेंसफाइल पर चल रहे स्ट्रीमिंग फैशन (सीधे या मैपरेडस का उपयोग करके) में संसाधित कर सकते हैं। कुछ बोनस भी हैं। SequenceFiles विभाजित करने योग्य हैं, इसलिए MapReduce उन्हें विखंडू में तोड़ सकता है और प्रत्येक खंड पर स्वतंत्र रूप से काम कर सकता है। वे HARs के विपरीत, संपीड़न का भी समर्थन करते हैं। ज्यादातर मामलों में ब्लॉक कंप्रेशन सबसे अच्छा विकल्प है, क्योंकि यह कई रिकॉर्ड्स (प्रति रिकॉर्ड के बजाय) के ब्लॉक को कंप्रेस करता है।
मौजूदा डेटा को SequenceFiles में बदलना धीमा हो सकता है। हालाँकि, समानांतर में SequenceFiles का संग्रह बनाना पूरी तरह से संभव है। (स्टुअर्ट सिएरा ने टार फाइल को सीक्वेंसफाइल में बदलने के बारे में एक बहुत उपयोगी पोस्ट लिखी है - इस तरह के उपकरण बहुत उपयोगी हैं, और उनमें से अधिक देखना अच्छा होगा)। आगे बढ़ते हुए, छोटी फ़ाइलों को मध्यवर्ती चरण के रूप में लिखने के बजाय, यदि संभव हो तो स्रोत पर डेटा को सीधे एक SequenceFile में लिखने के लिए अपनी डेटा पाइपलाइन को डिज़ाइन करना सबसे अच्छा है।
HAR फ़ाइलों के विपरीत, अनुक्रम फ़ाइल में सभी कुंजियों को सूचीबद्ध करने का कोई तरीका नहीं है, पूरी फ़ाइल के माध्यम से पढ़ने की कमी। (MapFiles, जो क्रमबद्ध कुंजियों के साथ SequenceFiles की तरह हैं, एक आंशिक अनुक्रमणिका बनाए रखते हैं, इसलिए वे अपनी सभी कुंजियों को सूचीबद्ध नहीं कर सकते हैं - आरेख देखें।)
SequenceFile बल्कि जावा-केंद्रित है। TFile को क्रॉस-प्लेटफ़ॉर्म होने के लिए डिज़ाइन किया गया है, और SequenceFile के लिए एक प्रतिस्थापन है, लेकिन यह अभी तक उपलब्ध नहीं है।
HBase
यदि आप बहुत सी छोटी फाइलें तैयार कर रहे हैं, तो एक्सेस पैटर्न के आधार पर, एक अलग प्रकार का भंडारण अधिक उपयुक्त हो सकता है। HBase डेटा को MapFiles (अनुक्रमित SequenceFiles) में संग्रहीत करता है, और यह एक अच्छा विकल्प है यदि आपको कभी-कभार रैंडम लुक अप के साथ MapReduce स्टाइल स्ट्रीमिंग विश्लेषण करने की आवश्यकता है। यदि विलंबता एक समस्या है, तो कई अन्य विकल्प हैं - रिचर्ड जोन्स का महत्वपूर्ण-मूल्य वाले स्टोर का उत्कृष्ट सर्वेक्षण देखें।