ऑन-द-फ्लाई स्ट्रीम संपीड़न जो हार्डवेयर संसाधनों में नहीं फैलता है?


23

मेरे पास 200 जीबी मुक्त डिस्क स्थान है, 16 जीबी रैम (जिनमें से ~ 1 जीबी डेस्कटॉप और कर्नेल द्वारा कब्जा कर लिया गया है) और 6 जीबी स्वैप है।

मेरे पास एक 240 जीबी बाहरी एसएसडी है, जिसमें 70 जीबी 1 और बाकी मुफ्त है, जिसे मुझे अपनी डिस्क पर बैकअप लेने की आवश्यकता है।

आम तौर पर, मैं dd if=/dev/sdb of=Desktop/disk.imgडिस्क को पहले करूँगा , और फिर उसे संपीड़ित करूँगा , लेकिन छवि बनाना पहला विकल्प नहीं है क्योंकि ऐसा करने के लिए मेरे पास कहीं अधिक डिस्क स्थान की आवश्यकता होगी, भले ही संपीड़न कदम के परिणामस्वरूप मुक्त स्थान को स्क्वैश किया जाएगा। अंतिम संग्रह आसानी से मेरी डिस्क पर फिट हो सकता है।

ddडिफ़ॉल्ट रूप से STDOUT को लिखता है, और gzipSTDIN से पढ़ सकता है, इसलिए सिद्धांत रूप में मैं लिख सकता हूं dd if=/dev/sdb | gzip -9 -, लेकिन gzipबाइट को पढ़ने में अधिक समय लगता है , जितना कि ddवे उत्पादन कर सकते हैं।

से man pipe:

पाइप के राइट एंड को लिखे गए डेटा को कर्नेल द्वारा बफ़र किया जाता है जब तक इसे पाइप के रीड एंड से पढ़ा नहीं जाता है।

मैं |एक वास्तविक पाइप की तरह होने के रूप में कल्पना करता हूं - एक आवेदन में डेटा shoving और दूसरा पाइप की कतार से डेटा जितनी जल्दी हो सके।

क्या होगा जब बाईं ओर का प्रोग्राम पाइप के दूसरे पक्ष की तुलना में अधिक तेज़ी से अधिक डेटा लिखता है, यह प्रक्रिया करने की उम्मीद कर सकता है? क्या यह चरम मेमोरी या स्वैप उपयोग का कारण होगा, या कर्नेल डिस्क पर एक फीफो बनाने की कोशिश करेगा, जिससे डिस्क को भरना होगा? या क्या यह SIGPIPE Broken pipeतभी विफल होगा जब बफर बहुत बड़ा हो?

मूल रूप से, यह दो प्रश्नों को उबालता है:

  1. एक समय में एक डेटा को पढ़ने के एक पाइप में अधिक डेटा shoving के निहितार्थ और परिणाम क्या हैं?
  2. डिस्क पर संपूर्ण असम्पीडित डेटास्ट्रीम डाले बिना डिस्क पर डेटास्ट्रीम को संपीड़ित करने का विश्वसनीय तरीका क्या है?

नोट 1: मैं सिर्फ पहले इस्तेमाल किए गए 70 जीबी का ठीक से कॉपी नहीं कर सकता हूं और विखंडन और अन्य चीजों के कारण एक कार्य प्रणाली या फाइल सिस्टम प्राप्त करने की अपेक्षा करता हूं, जिसके लिए पूर्ण सामग्री को बरकरार रखने की आवश्यकता होगी।


आप केवल उपयोगकर्ता निर्देशिकाओं और शायद स्थापित किए गए गैर-मानक सॉफ़्टवेयर की सूची के बजाय इस तरह का संपूर्ण फ़ाइल सिस्टम वापस क्यों करेंगे?
jamesqf

5
@jamesqf एग। क्योंकि इसे बहाल करना बहुत आसान है ...
deviantfan

4
@jamesqf क्योंकि तब मुझे बूट सेक्टर, और स्वैप पार्टीशन भी मिलता है, जिससे मैं डिस्क को एक बिलियन कष्टप्रद फाइल करने के बजाय फिर से बना सकता हूं।
बिल्ली

3
यादृच्छिक टिप: के lzopबजाय में देखो gzip; यह केवल एक अपेक्षाकृत कम संपीड़न अनुपात के साथ बहुत तेजी से संपीड़ित करता है। मुझे यह डिस्क छवियों के लिए आदर्श लगता है जहां संपीड़न गति एक वास्तविक अड़चन हो सकती है।
मार्सेल

1
"क्या होगा जब बाईं तरफ का प्रोग्राम पाइप के दूसरे पक्ष की तुलना में अधिक तेज़ी से अधिक डेटा लिखता है, क्या इसे संसाधित करने की उम्मीद कर सकता है?" कर्नेल लेखन प्रक्रिया का कारण तब तक सोएगा जब तक कि पाइप में अधिक जगह न हो।
तवियन बार्न्स

जवाबों:


16

तकनीकी रूप से भी आपको आवश्यकता नहीं है dd:

gzip < /dev/drive > drive.img.gz

आप उपयोग करते हैं dd, तो आप हमेशा की तरह डिफ़ॉल्ट ब्लॉकसाइज से बड़ा के साथ जाना चाहिए dd bs=1Mया syscall नरक भुगतना ( ddके डिफ़ॉल्ट ब्लॉकसाइज 512 बाइट्स, है, क्योंकि यह read()है और write()रों है कि 4096प्रति syscalls MiB, बहुत अधिक भूमि के ऊपर)।

gzip -9इसके लिए दिखाने के लिए बहुत कम के साथ बहुत अधिक सीपीयू का उपयोग करता है। यदि gzipआप धीमा कर रहे हैं, तो संपीड़न स्तर कम करें, या एक अलग (तेज) संपीड़न विधि का उपयोग करें।

यदि आप ddछवियों के बजाय फ़ाइल आधारित बैकअप कर रहे हैं , तो आपके पास कुछ तर्क हो सकते हैं जो यह तय करते हैं कि सभी को संकुचित करना है या नहीं (विभिन्न फ़ाइल प्रकारों के लिए ऐसा करने का कोई मतलब नहीं है)। dar( tarवैकल्पिक `) ऐसा करने के लिए विकल्प है एक उदाहरण है।

यदि आपका खाली स्थान शून्य है (क्योंकि यह एक एसएसडी है जो TRIM के बाद मज़बूती से शून्य लौटता है और आप दौड़ते fstrimऔर गिराते हैं) तो आप ध्वज के ddसाथ conv=sparseएक असम्पीडित, लूप-माउंटेबल, विरल छवि का उपयोग कर सकते हैं जो शून्य क्षेत्रों के लिए शून्य डिस्क स्थान का उपयोग करता है। । छवि फ़ाइल को एक फ़ाइल सिस्टम द्वारा समर्थित होने की आवश्यकता है जो विरल फ़ाइलों का समर्थन करता है।

वैकल्पिक रूप से कुछ फाइल सिस्टम के लिए उपयोग किए गए क्षेत्रों में केवल छवि के लिए सक्षम प्रोग्राम मौजूद हैं।


1
"यदि आप dd का उपयोग करते हैं, तो आपको हमेशा डिफ़ॉल्ट अवरोधक से बड़े के साथ जाना चाहिए जैसे dd bs=1M" - आप कर सकते हैं, लेकिन बहुत अधिक उम्मीद न करें। मेरे पीसी पर, dd512-बाइट ब्लॉक के साथ लगभग 2GB / s करेगा। वह अड़चन नहीं होगी; gzipहोगा।
मार्सेल

@marcelm हम कभी नहीं जानते कि लोग किस तरह की मशीन का उपयोग कर रहे हैं। यदि आप dd512-बाइट ब्लॉक के साथ 2GB / s जा रहे हैं, तो मुझे आश्चर्य होगा कि इस प्रक्रिया में एक CPU कोर 100% अधिकतम नहीं हुआ। अब यदि आपका बॉक्स एक क्वाडकोर है, जो वैसे भी बेकार बैठता है, तो आपको अंतर नजर नहीं आता। हर कोई अभी भी करता है, हालांकि।
ठंढकुट्ज़

9
आह। हर बार जब ddब्लॉकेज का उल्लेख किया जाता है, तो लोग नाइटपैकिंग करते हैं। gzipजा रहा है cpu गहन भी मेरे जवाब का हिस्सा था, ठीक है? और क्षमा करें, मैं "नगण्य" से असहमत हूं। यह केवल 1-2 गिग प्रति जोड़ सकता है gzip -9(लेकिन यह तब भी मिनटों की मात्रा में होता है जब सैकड़ों गिग्स को संसाधित करता है) लेकिन lzop -1यह आपकी सलाह के साथ 1s प्रति गीगा बनाम 4s प्रति गिग ले रहा है। एक आलू पर परीक्षण किया गया (सिंगल कोर vserver)। एक लेन जोड़ने से ddकुछ भी खर्च नहीं होता है और शून्य डाउनसाइड होता है। नाइटपिक न करें। बस कर दो। ymmv
frostschutz

19

ddडेटा को एक बार में एक ब्लॉक पढ़ता और लिखता है, और इसमें केवल एक ब्लॉक बकाया होता है। इसलिए

valgrind dd if=/dev/zero status=progress of=/dev/null bs=1M

ddलगभग 1MB मेमोरी का उपयोग करने वाले शो । आप ब्लॉक के आकार के साथ चारों ओर खेल सकते हैं, और ड्रॉप कर सकते हैं valgrind, ताकि इसकी ddगति पर प्रभाव देखा जा सके ।

जब आप पाइप करते हैं gzip, तो ddबस मैच gzipकी गति के लिए धीमा हो जाता है । इसकी स्मृति के उपयोग में वृद्धि नहीं करता, न ही यह गिरी (कर्नेल कि कैसे करना है, सिवाय इसके कि पता नहीं है डिस्क पर बफ़र्स स्टोर करने के लिए कारण नहीं है के माध्यम से अदला-बदली)। एक टूटा हुआ पाइप केवल तब होता है जब पाइप के सिरों में से एक मर जाता है; देखें signal(7)और write(2)विवरण के लिए।

इस प्रकार

dd if=... iconv=fullblock bs=1M | gzip -9 > ...

आप के बाद क्या कर रहे हैं करने के लिए एक सुरक्षित तरीका है।

यदि पाइपिंग, लेखन प्रक्रिया समाप्त हो जाती है तो कर्नेल द्वारा अवरुद्ध किया जा रहा है यदि रीडिंग प्रक्रिया नहीं चल रही है। आप इसे चलाकर देख सकते हैं

strace dd if=/dev/zero bs=1M | (sleep 60; cat > /dev/null)

आप देखेंगे कि dd1MB पढ़ता है, तो एक मुद्दा है write()जो वहाँ बैठता है, जबकि एक मिनट के लिए प्रतीक्षा करता है sleep। पाइप के दोनों किनारे इस तरह से संतुलन बनाते हैं: कर्नेल ब्लॉक लिखता है यदि लेखन प्रक्रिया बहुत तेज है, और यह रीडिंग प्रक्रिया को बहुत तेज होने पर ब्लॉक करता है।


1
यह बहुत मजेदार है। ddमैच gzipकी गति को धीमा करने के लिए कौन सा तंत्र जानता है ? यह स्वचालित है, जैसे कर्नेल द्वारा, या यह मेटाडेटा से इसकी आउटपुट फ़ाइल डिस्क्रिप्टर के बारे में गणना करता है?
बिल्ली

9
@ स्वत: यह स्वत: है; पाइप में डेटा डालने के लिए ddकॉल करता write()है। write()वास्तव में कर्नेल पर नियंत्रण स्थानांतरित करता है ताकि यह पाइप मेमोरी में हेरफेर कर सके। अगर कर्नेल देखता है कि पाइप भरा हुआ है, तो यह तब तक ("ब्लॉक") रहेगा जब तक पाइप में पर्याप्त जगह नहीं होगी। इसके बाद ही write()कॉल फ़िनिश होगी और वापस कंट्रोल ट्रांसफर ddहोगा, जो फिर से पाइप पर डेटा लिखेगा।
मार्सेल

9

प्रदर्शन के अलावा कोई नकारात्मक प्रभाव नहीं है: पाइप में एक बफर होता है, जो आमतौर पर 64K होता है, और उसके बाद, पाइप पर एक लेखन बस तब तक ब्लॉक रहेगा जब तक gzipकि कुछ और डेटा नहीं पढ़ता।


8

वास्तविक प्रश्न का उत्तर देते हुए कि यह कैसे काम करता है: "क्या होगा यदि बाईं ओर का प्रोग्राम पाइप के दूसरी तरफ की तुलना में अधिक तेज़ी से अधिक डेटा लिखता है, तो इसे संसाधित करने की उम्मीद कर सकते हैं?"

ऐसा नहीं होता है। पाइप में एक काफी छोटा, सीमित आकार का बफर है; देखें कि पाइप बफर कितना बड़ा है?

एक बार पाइप बफर भर जाने के बाद, भेजने का प्रोग्राम ब्लॉक हो जाता है । जब यह एक लिखित कॉल करता है, तो कर्नेल प्रोग्राम पर नियंत्रण वापस नहीं करेगा जब तक कि डेटा बफर में नहीं लिखा गया है। यह रीडिंग प्रोग्राम CPU समय देता है जिसमें बफर को खाली करना है।


3

हो सकता है कि आपको केवल फ़ाइलों की आवश्यकता हो, फिर टार का उपयोग करें। आप उन ब्लॉकों को जीरो से भर सकते हैं जिनमें कुछ भी नहीं है जो आप चाहते हैं, किसी ने पहले से ही इसके बारे में पूछा है। शून्य के साथ अप्रयुक्त स्थान (ext3, ext4)

फिर, वहाँ pigzजो आमतौर पर की तुलना में तेजी है gzip

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