Gzip संपीड़न डेटा की डुप्लिकेट विखंडू को समाप्त क्यों नहीं करता है?


30

मैंने अभी थोड़ा प्रयोग किया है जहाँ मैंने डुप्लिकेट फ़ाइलों के साथ एक टार आर्काइव बनाया है, यह देखने के लिए कि क्या यह संकुचित होगा, मेरे खौफ से, यह नहीं था! विवरण का पालन करें (खुशी पढ़ने के लिए प्रेरित परिणाम):

$ dd if=/dev/urandom bs=1M count=1 of=a
  1+0 records in
  1+0 records out
  1048576 bytes (1.0 MB) copied, 0.114354 s, 9.2 MB/s
$ cp a b
$ ln a c
$ ll
  total 3072
  -rw-r--r-- 2 guido guido 1048576 Sep 24 15:51 a
  -rw-r--r-- 1 guido guido 1048576 Sep 24 15:51 b
  -rw-r--r-- 2 guido guido 1048576 Sep 24 15:51 c
$ tar -c * -f test.tar
$ ls -l test.tar 
  -rw-r--r-- 1 guido guido 2109440 Sep 24 15:51 test.tar
$ gzip test.tar 
$ ls -l test.tar.gz 
  -rw-r--r-- 1 guido guido 2097921 Sep 24 15:51 test.tar.gz
$ 

पहले मैंने यादृच्छिक डेटा (ए) की 1MiB फ़ाइल बनाई। फिर मैंने इसे एक फ़ाइल b पर कॉपी किया और इसे c को भी लिंक कर दिया। टारबॉल बनाते समय, टार को स्पष्ट रूप से हार्डलिंक के बारे में पता था, क्योंकि टारबॉल केवल ~ 2MiB था और ~ 3Mib नहीं था।

अब मुझे उम्मीद है कि टारबॉल के आकार को कम करने के लिए gzip ~ 1MiB होगा क्योंकि a और b डुप्लिकेट हैं, और टारबॉल के अंदर लगातार 1MiB डेटा दोहराया जाना चाहिए, फिर भी ऐसा नहीं हुआ।

ऐसा क्यों है? और मैं इन मामलों में कुशलता से टारबॉल को कैसे संपीड़ित कर सकता हूं?

जवाबों:


24

Gzip gzip DEFLATE एल्गोरिथम पर आधारित है, जो LZ77 और हफ़मैन कोडिंग का संयोजन है। यह एक दोषरहित डेटा कम्प्रेशन अल्गोरिथम है जो इनपुट स्ट्रीम को एक डिक्शनरी में निर्मित डिक्शनरी का उपयोग करके और डुप्लिकेट के लिए देख कर संपीड़ित प्रतीकों में बदलकर काम करता है। लेकिन यह डुप्लिकेट को 32K से अधिक से अलग नहीं कर सकता है। उम्मीद है कि यह 1 एमबी डुप्लिकेट को अलग करने के लिए यथार्थवादी नहीं है।


काफी उचित! क्या आप किसी ऐसे विकल्प के बारे में जानते हैं जो धाराओं पर काम नहीं करता है?
गुइडो

1
मुझे आपकी समस्या का कोई भी हल नहीं पता है। अगर मुझे उम्मीद है कि यह एक आवर्ती, गंभीर समस्या होगी, तो मैं (व्यक्तिगत रूप से) एक स्क्रिप्ट के साथ उस पर हमला करूंगा, जिसने डुप्लिकेट खोजने के लिए एन-वे सीएमपी (तुलना) संचालन किया, सूची को एक फ़ाइल में लिखें, फिर टार + गज़िप केवल अद्वितीय आइटम + सूची। पुनर्स्थापित करने के लिए, मैं दूसरी स्क्रिप्ट का उपयोग करने के लिए ungzip और untar का उपयोग करूंगा, फिर सूची से डुप्स बनाएं। एक और विकल्प यह होगा कि आप हार्ड लिंक में डुबकी लगाएं, क्योंकि आपको पता है कि टार स्पॉट नहीं है। क्षमा करें, मुझे पता है कि शायद वह नहीं है जो आप उम्मीद कर रहे थे।
निकोल हैमिल्टन

1
gzip और bzip2 दोनों को अपने डिजाइन के कारण अपेक्षाकृत "स्ट्रीम फ्रेंडली" होना चाहिए - यह एक पाइप के हिस्से के रूप में काम करने में सक्षम होने के लिए बिल्कुल आवश्यक है। आप यहां जो देख रहे हैं, वह वास्तव में समर्पण है और सिर्फ संपीड़न नहीं है। चूंकि टार प्रक्रिया को दो भागों में तोड़ती है - केवल टार के साथ संग्रहित करना, और फिर संपीड़ित करने के लिए एक फिल्टर के रूप में दूसरे कार्यक्रम का उपयोग करना। मुझे अपनी खोजों में कोई भी संक्षिप्त संग्रह नहीं मिला, लेकिन मुझे इससे संबंधित प्रश्न मिला। superuser.com/questions/286414/…
स्टेफ़नी

2
@ स्टेफ़नी, निकोल हैमिल्टन: en.wikipedia.org/wiki/Lrzip#Lipzip है
मैकेनिकल घोंघा

1
@ कुछ भी नहीं के डुप्लिकेट को हटा सकते हैं कुछ भी एक स्ट्रीम में याद नहीं है, लेकिन कुछ की तरह xz -9 -M 95%, या यहां तक ​​कि कोशिश करो xz -M 95% --lzma2=preset=9,dict=1610612736। यह तेज़ नहीं होगा, लेकिन परिणाम में आपके डुप्लिकेट को छोड़े जाने की संभावना नहीं है।
एरन

39

निकोल हैमिल्टन सही ढंग से नोट करते हैं कि gzipइसके छोटे शब्दकोश आकार के कारण दूर के नकली डेटा नहीं मिलेंगे।

bzip2 समान है, क्योंकि यह 900 KB मेमोरी तक सीमित है।

इसके बजाय, कोशिश करें:

LZMA / LZMA2 एल्गोरिथ्म ( xz, 7z)

LZMA एल्गोरिथ्म Deflate के रूप में एक ही परिवार में है, लेकिन एक बहुत बड़ा शब्दकोश आकार का उपयोग करता है (अनुकूलन, डिफ़ॉल्ट 384 एमबी की तरह कुछ है)। xzउपयोगिता है, जो हाल ही में Linux distros पर डिफ़ॉल्ट रूप से स्थापित किया जाना चाहिए, के समान है gzipऔर LZMA उपयोग करता है।

जैसा कि LZMA अब तक की अतिरेक क्षमता का पता लगाता है, यह आपके डेटा को यहां प्रदर्शित करने में सक्षम होगा। हालाँकि, यह Gzip से धीमा है।

एक अन्य विकल्प 7-ज़िप (है 7z, में p7zipपैकेज) है, जो एक archiver (बजाय एक एकल स्ट्रीम कंप्रेसर की तुलना में) है डिफ़ॉल्ट (LZMA के लेखक द्वारा लिखित) द्वारा LZMA का उपयोग करता है। 7-ज़िप अभिलेखागार अपने .7zप्रारूप में संग्रह करते समय फ़ाइल स्तर पर (उसी एक्सटेंशन के साथ फ़ाइलों को देखते हुए) अपना समर्पण चलाता है । इसका मतलब यह है कि यदि आप के tarसाथ प्रतिस्थापित करने के लिए तैयार हैं 7z, तो आप समान फ़ाइलों को काट लें। हालाँकि, 7z नैनोसेकेंड टाइमस्टैम्प, अनुमतियाँ, या xattrs को संरक्षित नहीं करता है, इसलिए यह आपकी आवश्यकताओं के अनुरूप नहीं हो सकता है।

lrzip

lrzipएक कंप्रेसर है जो डेटा को लंबी दूरी की अतिरेक को हटाने के लिए पहले से ही पारम्परिक एल्गोरिथ्म जैसे कि Gzip / Deflate, bzip2, lzop, या LZMA जैसे खिलाता है। आपके द्वारा दिए गए नमूना डेटा के लिए, यह आवश्यक नहीं है; यह तब उपयोगी है जब इनपुट डेटा मेमोरी में फिट हो सकता है।

इस तरह के डेटा (डुप्लिकेट किए गए अतुलनीय विखंडू) के लिए, आपको lzopकम्प्रेशन (बहुत तेज़) का उपयोग करना चाहिए lrzip, क्योंकि डिडुप्लिकेट होने के बाद पूरी तरह से यादृच्छिक डेटा को संपीड़ित करने के लिए कठिन प्रयास करने का कोई लाभ नहीं है।

बप और ओबनम

आप प्रश्न में चिह्नित के बाद से , यदि यहां अपने लक्ष्य के डेटा का बैकअप है, की तरह एक deduplicating बैकअप प्रोग्राम का उपयोग करने पर विचार करें Bup या Obnam


यह लार्ज़िप दिलचस्प लग रहा है। यहां तक ​​कि यह एक लेखक भी है जो गैर-पारंपरिक समाधानों के लिए जाना जाता है। अब मुझे अपनी बैकअप स्क्रिप्ट को संशोधित करना होगा। फिर।
एरोन

3
+1 वाह, क्या ज्ञान का एक फव्वारा / वहाँ अनुभव। की सराहना की। क्या मैं मिश्रण में डिडअप सक्षम फाइल सिस्टम जोड़ सकता हूँ? ZFS (और, मुझे लगता है कि Btrfs के लिए यह निर्धारित है) - ब्लॉक संरेखित दोहराव के साथ काम करेगा
sehe

LZMA2 संपीड़न और एक 1536Mb डाइसेक्शनरी आकार (विंडोज जीयूआई में उपलब्ध अधिकतम आकार) का उपयोग करके 7Zip मेरे लिए बहुत अच्छा काम करता है!
लियोपोल्डो सैंसिएक

2

बैकअप के मामले में, संभवतः छोटी फ़ाइलों के लार्ज सेट के साथ, एक चाल जो आपके लिए काम कर सकती है वह है एक्सटेंशन द्वारा टार में फ़ाइलों को सॉर्ट करना:

find archive_dir -type f | rev | sort | rev | tar czf my_archive.tar.gz -I -

मैं सभी को काट दूंगाrev (क्यों रिवर्स भी और फिर सॉर्ट?) और sortविकल्प "-r, --reverse" को देखें (हालांकि मुझे यकीन नहीं है कि आप किसी भी रिवर्स को क्यों चाहते हैं)। लेकिन मुझे लगता है कि आपका tarविकल्प " -I" वह नहीं करता है जो आप सोचते हैं कि यह " -I, --use-compress-program PROG" करता है , आप शायद चाहते हैं "-T,
--files

मेरा मानना ​​है कि | tar czf my_archive.tar.gz -I -होना चाहिए| xargs tar Azf my_archive.tar.gz
ओलिवियर दुलैक

@ Xen2050, revप्रत्येक पंक्ति में वर्णों के क्रम को उलट देता है, धारा में रेखा का क्रम नहीं। इस वजह से, sortफ़ाइलों को उनके एक्सटेंशन द्वारा समूहित करता है। मुझे संदेह -I -होना चाहिए था -T -, जो स्टड पर फ़ाइल सूची प्रदान करता है।
billyjmc

@billyjmc मैं देख रहा हूँ, कि revविस्तार द्वारा व्यवस्था की तरह, नहीं है कि वैसे भी लिनक्स में कई एक्सटेंशन हैं। मैं कल्पना करूँगा कि आकार के अनुसार छँटाई करने की संभावना अधिक होगी
3:20 पर Xen2050

2

gzipडुप्लिकेट नहीं मिलेगा, यहां तक xzकि एक विशाल शब्दकोश आकार भी नहीं होगा। आप क्या कर सकते हैं उपयोग करें mksquashfs- यह वास्तव में डुप्लिकेट के स्थान को बचाएगा।

के साथ कुछ त्वरित परीक्षण के परिणाम xzऔर mksquashfsतीन यादृच्छिक बाइनरी फ़ाइलें (64MB) जिनमें से दो ही हैं साथ:

सेट अप:

mkdir test
cd test
dd if=/dev/urandom of=test1.bin count=64k bs=1k
dd if=/dev/urandom of=test2.bin count=64k bs=1k
cp test{2,3}.bin
cd ..

स्क्वैशएफएस:

mksquashfs test/ test.squash
> test.squash - 129M

XZ:

XZ_OPT='-v --memlimit-compress=6G --memlimit-decompress=512M --lzma2=preset=9e,dict=512M --extreme -T4 ' tar -cJvf test.tar.xz test/
> test.tar.xz - 193M

क्या mksquashfs केवल फ़ाइल-स्तर पर डुप्लिकेट पाता है, या क्या यह छोटे विखंडू पर भी काम करता है? अर्थात: क्या यह थोड़ी अलग-अलग-लेकिन-अधिकतर-समान फ़ाइलों को संपीड़ित करेगा?
Chaos_99

यह फाइल-आधार पर ही काम करता है। आप देख सकते हैं कि जब उन तीन परीक्षण-फाइलों को गैर-संकुचित टार संग्रह में टारगेट करते हैं और बाद में उन्हें mksquashfs के साथ संपीड़ित करते हैं। दूसरी ओर, mksqashfs रिपोर्ट करेंगे, जब स्टैडआउट Number of duplicate files foundमें डुप्लिकेट ढूंढते हैं ।
इज़ी

1

मेरे सिस्टम lzma test.tarमें 106'3175 बाइट्स (1.1M) test.tar.lzma फ़ाइल है


1

'यांत्रिक घोंघा के जवाब के अलावा:

यहां तक ​​कि xz (या lzma) को डुप्लिकेट नहीं मिलेगा अगर फ़ाइल का आकार असम्पीडित एकल फ़ाइल (या, अधिक सटीक रूप से, डुप्लिकेट के बीच की दूरी) शब्दकोश आकार से अधिक है। उच्चतम सेटिंग पर भी xz (या lzma) इसके -9eलिए केवल 64MB ही सुरक्षित रखता है।

सौभाग्य से आप विकल्प के साथ अपना खुद का तानाशाही आकार निर्दिष्ट कर सकते हैं --lzma2=dict=256MB (केवल --lzma1=dict=256MBकमांड के लिए लज़मा उर्फ ​​का उपयोग करते समय अनुमति दी जाती है)

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


-2

बिना कमांड लाइन स्विच वाला गज़िप संपीड़न के लिए सबसे कम संभव एल्गोरिथ्म का उपयोग करता है।

प्रयोग करके देखें:

gzip -9 test.tar

आपको बेहतर परिणाम प्राप्त करने चाहिए


1
वास्तव में, अंतर न्यूनतम नहीं है। मैंने भी इसी तरह के परिणामों के साथ bzip2 की कोशिश की।
गुइडो

बिना कमांड लाइन स्विच वाला गज़िप संपीड़न के लिए सबसे कम संभव एल्गोरिथ्म का उपयोग करता है। => यह सच नहीं है - "मैन गज़िप" में कहा गया है कि "(t) वह डिफ़ॉल्ट संपीड़न स्तर है -6 (जो गति की कीमत पर उच्च संपीड़न के लिए पक्षपाती है)।" यह सभी gzip संस्करण के लिए सच है, मुझे पता है, अगर संकलित-डिफ़ॉल्ट सेटिंग्स GZIP पर्यावरण चर द्वारा ओवरराइड नहीं की जाती हैं। यहां तक ​​कि स्तर "-9" यहां आपकी मदद नहीं करेगा, जैसा कि पहले ही दिए गए उत्तरों में बताया गया है।
गुंटर ओह्रनर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.