Git .git / ऑब्जेक्ट्स / फ़ोल्डर को कई SHA- उपसर्ग फ़ोल्डर में क्यों विभाजित किया गया है?


21

Git आंतरिक रूप से ऑब्जेक्ट्स (ब्लॉब्स, ट्री) को .git/objects/फ़ोल्डर में संग्रहीत करता है । प्रत्येक ऑब्जेक्ट को SHA1 हैश द्वारा संदर्भित किया जा सकता है जो ऑब्जेक्ट की सामग्री से गणना की जाती है।

हालाँकि, ऑब्जेक्ट .git/objects/सीधे फ़ोल्डर के अंदर संग्रहीत नहीं होते हैं। इसके बजाय, प्रत्येक ऑब्जेक्ट एक फ़ोल्डर के अंदर संग्रहीत किया जाता है जो उसके SHA1 हैश के उपसर्ग के साथ शुरू होता है। तो हैश के साथ एक वस्तु b7e23ec29af22b0b4e41da31e868d57226121c84पर संग्रहीत किया जाएगा.git/objects/b7/e23ec29af22b0b4e41da31e868d57226121c84

Git अपनी वस्तु भंडारण को इस तरह से क्यों घटाता है?

मैं जिन संसाधनों को पा सकता था, जैसे कि जीआईटी-स्कैम पर जीआईटी के इंटर्नल्स पर पेज , केवल यह बताया गया है कि कैसे , क्यों नहीं ।

जवाबों:


33

सभी फ़ाइलों को एक निर्देशिका में रखना संभव है, हालांकि कभी-कभी यह थोड़ा बड़ा हो सकता है। कई फाइल सिस्टम की एक सीमा होती है । आप USB स्टिक पर एक FAT32 स्वरूपित ड्राइव पर गिट रिपॉजिटरी लगाना चाहते हैं? आप केवल एकल निर्देशिका में 65,535 फ़ाइलों को संग्रहीत कर सकते हैं। इसका मतलब यह है कि निर्देशिका संरचना को वश में करना आवश्यक है ताकि किसी एक निर्देशिका को भरने की संभावना कम हो।

यह भी अन्य फ़ाइल सिस्टम और बड़े गिट रिपॉजिटरी के साथ एक समस्या बन जाएगा। एक अपेक्षाकृत छोटा गिट रेपो जिसे मैंने बाहर लटका दिया है (लगभग 360MiB) और इसमें 11k फ़ाइलों के लिए 181,546 ऑब्जेक्ट हैं। खींचेंलिनक्स रेपो और आपको 4,374,054 ऑब्जेक्ट मिले हैं। यदि आप इन सभी को एक निर्देशिका में रखते हैं, तो यह देखना असंभव होगा और फ़ाइल सिस्टम के लिए क्रैश ('क्रैश' के कुछ अर्थ के लिए) होगा।

इसलिए? आप इसे बाइट से विभाजित करते हैं। इसी तरह के दृष्टिकोण FireFox जैसे अनुप्रयोगों के साथ किए जाते हैं:

~/Li/Ca/Fi/Pr/7a/Cache $ ls
0/           4/           8/           C/           _CACHE_001_
1/           5/           9/           D/           _CACHE_002_
2/           6/           A/           E/           _CACHE_003_
3/           7/           B/           F/           _CACHE_MAP_

इसके अलावा, यह प्रदर्शन के सवाल पर भी जाता है। कई लंबे फ़ाइलनामों के साथ NTFS प्रदर्शन पर विचार करें :

Windows NT एक लंबे समय के लिए Windows NT फ़ाइल सिस्टम (NTFS) स्वरूपित ड्राइव पर निर्देशिका संचालन करने में एक लंबा समय लेता है जिसमें लंबी फ़ाइल नाम (8.3 सम्मेलन में अनुरूप नहीं होने वाले नाम) के साथ बड़ी संख्या में फाइलें होती हैं।

जब NTFS एक डायरेक्टरी में फाइलों को एन्यूमरेट करता है, तो उसे लंबे फाइल नामों से जुड़े 8.3 नामों को देखना पड़ता है। क्योंकि NTFS निर्देशिका को एक क्रमबद्ध अवस्था में बनाए रखा जाता है, इसी प्रकार लंबी फ़ाइल नाम और 8.3 नाम आमतौर पर निर्देशिका लिस्टिंग में एक दूसरे के बगल में नहीं होते हैं। तो, एनटीएफएस हर फाइल के लिए निर्देशिका की रैखिक खोज का उपयोग करता है। नतीजतन, निर्देशिका लिस्टिंग करने के लिए आवश्यक समय की मात्रा निर्देशिका में फ़ाइलों की संख्या के वर्ग के साथ बढ़ जाती है। फाइलों की छोटी संख्या (कुछ सौ से कम) के लिए समय की देरी नगण्य है। लेकिन जैसा कि एक निर्देशिका में फ़ाइलों की संख्या कई हजार तक बढ़ जाती है, लिस्टिंग करने के लिए आवश्यक समय मिनट, घंटे या दिन भी बढ़ सकता है। यदि लंबे फ़ाइल नाम बहुत समान हैं - केवल कुछ अंतिम वर्णों में भिन्न होने पर समस्या बढ़ जाती है।

SHA1 चेकसम के नाम वाली फाइलों के साथ, यह आपदा और घृणित प्रदर्शन के लिए एक नुस्खा हो सकता है।

जबकि ऊपर Windows NT 3.5 (और NTFS 1.2 - आमतौर पर 1995 से 2000 के दशक तक उपयोग किया जाता है) से एक तकनीकी नोट से है, यह EXT3 जैसी चीजों में भी देखा जा सकता है , जिसमें फाइल सिस्टम के कार्यान्वयन के साथ O (n) लुकअप की आवश्यकता है। । और उस बी-ट्री परिवर्तन के साथ भी:

जबकि HTree एल्गोरिथ्म ने लुकअप समय में काफी सुधार किया, यह वर्कलोड के लिए कुछ प्रदर्शन प्रतिगमन का कारण बन सकता है जो एक बड़ी निर्देशिका में सभी फाइलों के कुछ ऑपरेशन को करने के लिए रीडडीर () का उपयोग करता है।
...
इस प्रदर्शन के मुद्दे को कम करने के लिए एक संभावित समाधान, जो डैनियल फिलिप्स और एंड्रियास दिलगर द्वारा सुझाया गया है, लेकिन अभी तक लागू नहीं किया गया है, जिसमें कर्नेल को फ्री इनोड चुनना शामिल है, जिनके इनोड नंबर एक संपत्ति को पूरा करते हैं जो इनोड्स को उनके फ़ाइलनाम हैश द्वारा समूहबद्ध करते हैं। डैनियल और एंड्रियास, डायरेक्टरी के आकार के आधार पर इनोड्स की एक सीमा से इनोड को आवंटित करने का सुझाव देते हैं, और फिर फ़ाइल नाम हैश के आधार पर उस रेंज से एक फ्री इनोड का चयन करते हैं। यह सिद्धांत में होना चाहिए कि पठन क्रम में निर्देशिका में संदर्भित आयतों का उपयोग करते समय थ्रेशिंग की मात्रा कम हो जाती है। हालांकि यह स्पष्ट नहीं है कि इस रणनीति के परिणामस्वरूप गति आएगी; वास्तव में यह इनोड ब्लॉक की कुल संख्या को बढ़ा सकता है जिसे संदर्भित करना पड़ सकता है, और इस तरह रीडडीर () + स्टेट () वर्कलोड का प्रदर्शन बदतर हो सकता है। स्पष्ट रूप से,

संयोग से, 2005 से प्रदर्शन में सुधार करने के लिए इस बिट, उसी वर्ष गिट जारी किया गया था।

जैसा कि फ़ायरफ़ॉक्स और कई अन्य अनुप्रयोगों के साथ देखा गया है जिसमें बहुत सारी हैश कैश्ड फाइलें हैं, जो बाइट द्वारा कैश को विभाजित करने का डिज़ाइन है। इसमें नगण्य प्रदर्शन लागत होती है, और जब पुराने के साथ थोड़ा सा हो सकता है, सिस्टम के साथ क्रॉस प्लेटफॉर्म का उपयोग किया जाता है, तो कार्यक्रम के काम करने या न करने के बीच का अंतर बहुत अच्छा हो सकता है।


1
आपने ध्यान दिया कि NTFS के प्रदर्शन लेख से आप NT 3.5 पर लागू होते हैं, जो 1994 में जारी किया गया था, है ना?
अवनेर शाहर-काश्तन

1
@ अवनरशहर-कश्तन येप। Git 2005 में जारी किया गया था। मुझे पता है कि मैं कॉर्पोरेट वातावरण में 2000 के दशक की शुरुआत में (एक टेक कंपनी में फिर भी) एनटीएफएस v1.2 आधारित फाइल सिस्टम का उपयोग कर रहा था। उस समय निश्चित रूप से उपलब्ध सिस्टम पर git और फ़ाइल सिस्टम की आवश्यकताओं के बीच निश्चित रूप से ओवरलैप होता है।

शायद यह स्पष्ट हो जाएगा यदि आपने कहा कि यह प्रौद्योगिकी की स्थिति की एक ऐतिहासिक कलाकृति हो सकती है जब गिट को पेश किया गया था, क्योंकि यह खड़ा है, 2015 में पूछे गए एक प्रश्न के लिए, एक बीस साल पुरानी तकनीकी सीमा का हवाला देते हुए (उत्तर के लिए बड़ा जवाब देना) ) भ्रामक लगता है।
अवनर शहर-काश्तन

निष्पक्ष होने के लिए, git"एस" पैक "प्रणाली इन मुद्दों का एक बहुत कम कर देता है। सैद्धांतिक रूप से, gitकेवल एक ही निर्देशिका का उपयोग किया जा सकता है, और जब उस निर्देशिका में फ़ाइलों की संख्या एक निश्चित (संभवतः एफएस-निर्भर) सीमा से अधिक हो जाती है, तो केवल पुनरावृत्ति हो सकती है।
nnonneo

5
@ AvnerShahar-Kashtan यदि आप लिंक किए गए SO लेख को पढ़ते हैं, तो आप देख सकते हैं कि बड़ी संख्या में फ़ाइलों वाली निर्देशिकाओं के साथ काम करना NT फ़ाइल ही नहीं, कई फ़ाइल सिस्टम और ऑपरेटिंग सिस्टम पर भी समस्याग्रस्त है। फ़ाइल सीमाएं एक तरफ, यहां तक ​​कि फाइलों को सूचीबद्ध करने से भी बड़ी मात्रा में ओवरहेड हो सकता है।

8

यह वांछनीय क्यों है इसके दो कारण हैं।

निर्देशिकाएँ मनमाने ढंग से बड़ी नहीं हो सकतीं। उदा। कुछ (यथोचित आधुनिक!) फाइलसिस्टम एक निर्देशिका में 32000 प्रविष्टियों तक सीमित हैं। लिनक्स कर्नेल में कमिट की संख्या परिमाण के उस क्रम में है। अपने पहले दो हेक्स अंकों द्वारा कमिट को विभाजित करने से शीर्ष स्तर का आकार 256 प्रविष्टियों तक सीमित हो जाता है। उप-निर्देशिकाएं विशिष्ट गिट रिपोज के लिए बहुत छोटी होंगी।

निर्देशिकाएँ रैखिक रूप से स्कैन की जाती हैं। कुछ फ़ाइल सिस्टम (उदाहरण के लिए एक्सट्रीम * फैमिली) में, एक डायरेक्टरी एक लिंक की गई लिस्ट या एंट्री टेबल है। एक फ़ाइल देखने के लिए, पूरी सूची स्कैन की जाती है जब तक कि एक मिलान फ़ाइल नाम नहीं मिलता है। स्पष्ट रूप से, यह प्रदर्शन के लिए अवांछनीय है। कई आधुनिक फ़ाइल सिस्टम अतिरिक्त रूप से फास्ट लुक के लिए हैश टेबल या बी-ट्री का उपयोग करते हैं, लेकिन हर किसी के पास नहीं हो सकता है। प्रत्येक निर्देशिका को छोटा रखने का अर्थ है तेजी से पहुंच का समय।


1
"कुछ (यथोचित आधुनिक!) फाइलसिस्टम एक निर्देशिका में 32000 प्रविष्टियों तक सीमित हैं।" यदि वह सबसे कठोर सीमा Git मिल रही है, तो Git के लिए पहले दो के बजाय हैश के पहले तीन वर्णों का उपयोग करना बेहतर नहीं होगा ? इसका मतलब यह होगा कि निर्देशिका 256 तक सीमित होने के बजाय 4096 उपनिर्देशिकाओं तक पकड़ कर सकती है, ऊपर की आवश्यकता को पूरा करते हुए, लेकिन अतिरिक्त लाभ के साथ कि उन उपनिर्देशिकाओं को 16x कम होने की संभावना होगी जिसमें> 32000 फाइलें स्वयं शामिल होंगी। objects
सम्पाबल्कुप्पर

1

ये 256 बकेट git को फाइल सिस्टम पर बड़ी रिपोजिटरी स्टोर करने की अनुमति देते हैं जो एक डायरेक्टरी में नंबर फाइल्स को सीमित करते हैं और फाइल सिस्टम पर डिसेंट परफॉर्मेंस प्रदान करते हैं जो कई फाइलों वाली डायरेक्ट्री के साथ स्लो हो जाते हैं।


1

कुछ फाइल सिस्टम और / या फाइलसिस्टम कार्यान्वयन और / या libc कार्यान्वयन हैं, जहां प्रदर्शन बड़ी संख्या में निर्देशिका प्रविष्टियों के साथ खराब होते हैं।

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