पाइपिंग 'dd' को gzip के माध्यम से इतनी सीधी कॉपी से अधिक तेज़ क्यों है?


79

मैं अपने नेटवर्क में एक कंप्यूटर से दूसरे नेटवर्क में एक ही कंप्यूटर में 100 Mbit / s लाइन से अधिक बैकअप लेना चाहता था। इसके लिए मैंने किया

dd if=/local/path of=/remote/path/in/local/network/backup.img

जिसने मुझे 50 से 100 kB / s के बारे में कुछ बहुत कम नेटवर्क हस्तांतरण की गति प्रदान की, जो कि हमेशा के लिए हो जाती थी। इसलिए मैंने इसे बंद कर दिया और इसे बहुत छोटा बनाने के लिए इसे उड़ान भरने पर आज़माने का फैसला किया ताकि हस्तांतरण की मात्रा कम हो। तो मैंने किया

dd if=/local/path | gzip > /remote/path/in/local/network/backup.img.gz

लेकिन अब मुझे 1 एमबी / एस नेटवर्क ट्रांसफर स्पीड जैसी कोई चीज मिली है, इसलिए 10 से 20 का एक कारक तेज है। इसे नोट करने के बाद, मैंने कई रास्तों और फाइलों पर इसका परीक्षण किया, और यह हमेशा ऐसा ही था।

क्यों पाइप करता ddमाध्यम से gzipभी एक बड़ा कारक द्वारा स्थानान्तरण दरों में वृद्धि के बजाय केवल एक बड़ा कारक द्वारा धारा के bytelength को कम करने? मैं उच्चतर सीपीयू खपत के कारण संपीडन दर के बजाय स्थानांतरण दरों में थोड़ी कमी की उम्मीद कर रहा था, लेकिन अब मुझे एक डबल प्लस मिलता है। ऐसा नहीं है कि मैं खुश नहीं हूं, लेकिन मैं सिर्फ सोच रहा हूं। ;)


1
512 बाइट्स यूनिक्स के शुरुआती दौर में फ़ाइल स्टोरेज के लिए मानक ब्लॉक आकार था। चूंकि सब कुछ यूनिक्स / लिनक्स में एक फाइल है, इसलिए यह सब कुछ के लिए डिफ़ॉल्ट हो गया। अधिकांश उपयोगिताओं के नए संस्करणों में वृद्धि हुई है लेकिन डी.डी.
डॉकस्लेवगर

इसका सरल उत्तर यह है कि dd1MB / s पर आउटपुट कर रहा है ... सही वेटिंग gzipपाइप में। यह ब्लॉक आकार के साथ करने के लिए बहुत कम मिला है।
तुललो_एक्स

जवाबों:


100

ddडिफ़ॉल्ट रूप से एक बहुत छोटे ब्लॉक आकार का उपयोग करता है - 512 बाइट्स (!!)। यानि बहुत कुछ छोटे छोटे पढ़ते और लिखते हैं। ऐसा लगता है कि dd, अपने पहले उदाहरण में भोलेपन से इस्तेमाल किया गया था, बहुत कम पेलोड के साथ नेटवर्क पैकेट की एक बड़ी संख्या पैदा कर रहा था, इस प्रकार थ्रूपुट को कम करना।

दूसरी ओर, gzipबड़े बफ़र्स के साथ I / O करने के लिए पर्याप्त स्मार्ट है। यही है, नेटवर्क पर बड़ी संख्या में छोटे लेखन।

क्या आप ddएक बड़े bs=पैरामीटर के साथ फिर से कोशिश कर सकते हैं और देख सकते हैं कि क्या यह इस समय बेहतर काम करता है?


20
धन्यवाद, के बिना प्रत्यक्ष प्रतिलिपि की कोशिश की gzipऔर bs=10M3 या 4 एमबी / एस के बारे में -> का तेजी से नेटवर्क हस्तांतरण - का एक blockize । gzipछोटे ब्लॉकेज + की तुलना में उच्च अवरोधक + ने कुछ भी नहीं बदला gzip
फू बार

7
यदि आप देखना चाहते हैं कि हाई ब्लॉक साइज gzip के बाद एक और dd की कोशिश करता है।
यहोशू

क्या gzip अपना स्वयं का आउटपुट बफरिंग कर रहा है, या क्या यह केवल stdio का उपयोग करता है?
बरमार

@ बरमार अगर मैं स्रोत को सही ढंग से पढ़ रहा हूं, तो यह बस write(3)बफर के लिए है।

@CongMa आप भी कोशिश कर सकते हैं और gzip के बजाय पिग का उपयोग कर सकते हैं, यह और भी तेज़ी से काम करेगा
GioMac

4

यह करने के लिए देर से लेकिन मैं जोड़ सकता है ...

एक साक्षात्कार में मुझे एक बार पूछा गया था कि बिट-फॉर-बिट डेटा का क्लोनिंग के लिए सबसे तेज संभव तरीका क्या होगा और ( ddया डीओडी वित्त पोषित ) के उपयोग के साथ जवाब दिया गया । साक्षात्कारकर्ता पुष्टि की है कि पाइपिंग के लिए , और अधिक कुशल है के रूप में इस बस परमिट एक साथ पढ़ें / लिखें या प्रोग्रामर संदर्भ में , लिखने की गति इस प्रकार ultimatly दोहरीकरण और Halfing हस्तांतरण समय।dc3ddddddstdin/stdout

dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb

1
मुझे नहीं लगता कि यह सच है। मैंने अभी कोशिश की। dd status=progress if=/dev/zero count=100000 bs=1M of=/dev/null22.5GB / s dd status=progress if=/dev/zero count=100000 bs=1M | dd of=/dev/null bs=1Mथा , 2.7GB था। तो पाइप इसे धीमा कर देता है।
झूठे जेब

0

कॉंग सही है। आप डिस्क के ब्लॉक को दूरस्थ होस्ट से असम्पीडित कर रहे हैं। आपका नेटवर्क इंटरफ़ेस, नेटवर्क और आपका रिमोट सर्वर सीमा है। सबसे पहले आपको डीडी का प्रदर्शन बढ़ाने की जरूरत है। एक बी एस = पैरामीटर निर्दिष्ट करना जो डिस्क बफर मेमोरी के साथ संरेखित करता है उसे डिस्क से सबसे अधिक प्रदर्शन मिलेगा। उदाहरण के लिए bs = 32M कहें। यह तब ड्राइव बफर से sata या sas लाइन दर स्ट्रेट में gzip के बफर को भर देगा। डिस्क को पुट के माध्यम से बेहतर देने वाले अनुक्रमिक हस्तांतरण के लिए इच्छुक होगा। Gzip डेटा को स्ट्रीम में संपीड़ित करेगा और इसे आपके स्थान पर भेज देगा। यदि आप NFS का उपयोग कर रहे हैं जो nfs ट्रांसमिशन को न्यूनतम करने की अनुमति देगा। यदि आप SSH का उपयोग कर रहे हैं तो आप SSH इनकैप्सुलेशन और एन्क्रिप्शन ओवरहेड को एनकर कर देते हैं। यदि आप netcat का उपयोग करते हैं तो आपके पास सिर पर कोई एन्क्रिप्शन नहीं है।


0

मैं यहाँ मानता हूँ कि जिस "स्थानांतरण गति" का आप उल्लेख कर रहे हैं, उसके द्वारा रिपोर्ट की जा रही है dd। यह वास्तव में समझ में आता है, क्योंकि ddवास्तव में प्रति सेकंड 10x डेटा की मात्रा को स्थानांतरित कर रहा है ! हालाँकि, ddनेटवर्क पर स्थानांतरित नहीं हो रहा है - उस कार्य को gzipप्रक्रिया द्वारा नियंत्रित किया जा रहा है।

कुछ संदर्भ: gzipअपने इनपुट पाइप से डेटा की खपत जितनी तेजी से होगी, वह अपने आंतरिक बफर को साफ कर सकती है। जिस गति से gzipबफर खाली होता है वह कुछ कारकों पर निर्भर करता है:

  • I / O बैंडविड्थ लिखता है (जो नेटवर्क द्वारा अड़चन है, और निरंतर बनी हुई है)
  • I / O बैंडविड्थ पढ़ा (जो आधुनिक मशीन पर स्थानीय डिस्क से 1MB / s पढ़ने से कहीं अधिक होने वाला है, इस प्रकार संभावित अड़चन नहीं है)
  • इसका संपीड़न अनुपात (जिसे मैं आपके 10x स्पीडअप द्वारा 10% के आसपास मान लूंगा, यह दर्शाता है कि आप किसी तरह के अत्यधिक दोहराए गए पाठ को लॉग फ़ाइल या कुछ XML की तरह संपीड़ित कर रहे हैं)

तो इस स्थिति में, नेटवर्क 100kB / s को संभाल सकता है, और gzip10: 1 के आसपास डेटा को संपीड़ित कर रहा है (और सीपीयू द्वारा टोंटी नहीं डाली जा रही है)। इसका मतलब है कि जब यह 100kB / s आउटपुट gzipकर रहा है , तो 1MB / s का उपभोग कर सकता है , और खपत की दर वही है जो ddदेख सकता है।

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