LZMA/LZMA2 알고리즘( xz, 7z)

LZMA/LZMA2 알고리즘( xz, 7z)

나는 중복된 파일이 포함된 tar 아카이브를 생성하여 압축되는지 확인하는 간단한 실험을 수행했습니다. 놀랍게도 압축되지 않았습니다! 자세한 내용은 다음과 같습니다(읽는 즐거움을 위해 결과를 들여쓰기함).

$ 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 파일을 만들었습니다(a). 그런 다음 이를 b 파일에 복사하고 c에도 연결했습니다. 타르볼을 생성할 때 타르볼은 ~3Mib가 아니라 ~2MiB에 불과했기 때문에 tar는 분명히 하드링크를 인식했습니다.

이제 a와 b가 중복되고 tarball 내부에 1MiB의 연속 데이터가 반복되어야 하기 때문에 gzip이 tarball의 크기를 ~1MiB로 줄일 것으로 예상했지만 이런 일은 발생하지 않았습니다.

왜 이런거야? 이런 경우 어떻게 타르볼을 효율적으로 압축할 수 있습니까?

답변1

Gzip gzip은 LZ77과 Huffman 코딩을 결합한 DEFLATE 알고리즘을 기반으로 합니다. 이는 즉석에서 구축된 사전을 사용하여 입력 스트림을 압축 기호로 변환하고 중복 항목을 감시하는 방식으로 작동하는 무손실 데이터 압축 알고리즘입니다. 하지만 32K 이상으로 구분된 중복 항목은 찾을 수 없습니다. 1MB 간격으로 중복된 항목을 발견할 것으로 기대하는 것은 현실적이지 않습니다.

답변2

니콜 해밀턴이 정확하게 지적했습니다.gzip사전 크기가 작기 때문에 먼 중복 데이터를 찾지 않습니다 .

bzip2메모리가 900KB로 제한되어 있기 때문에 비슷합니다.

대신 다음을 시도해 보세요.

LZMA/LZMA2 알고리즘( xz, 7z)

LZMA 알고리즘은 Deflate와 동일한 계열에 속하지만 훨씬 더 큰 사전 크기(사용자 정의 가능, 기본값은 384MB 정도)를 사용합니다. xz최신 Linux 배포판에 기본적으로 설치되어야 하는 이 유틸리티는 gzipLZMA와 유사하며 이를 사용합니다.

LZMA는 장거리 중복성을 감지하므로 여기에서 데이터 중복을 제거할 수 있습니다. 그러나 Gzip보다 속도가 느립니다.

또 다른 옵션 은 기본적으로 LZMA(LZMA 작성자가 작성)를 사용하는 아카이버(단일 스트림 압축기가 아님)인 7-zip( 7z패키지에 있음 )입니다. p7zip7-zip 아카이버는 해당 형식으로 보관할 때 파일 수준에서 자체 중복 제거를 실행합니다(확장자가 동일한 파일 확인) .7z. 즉, tar으로 대체하려는 경우 7z동일한 파일이 중복 제거됩니다. 그러나 7z는 나노초 타임스탬프, 권한 또는 xattrs를 보존하지 않으므로 사용자의 요구에 적합하지 않을 수 있습니다.

lrzip

lrzipGzip/Deflate, bzip2, lzop 또는 LZMA와 같은 기존 알고리즘에 데이터를 공급하기 전에 데이터를 사전 처리하여 장거리 중복성을 제거하는 압축기입니다. 여기에 제공되는 샘플 데이터의 경우에는 필요하지 않습니다. 입력 데이터가 메모리에 들어갈 수 있는 것보다 클 때 유용합니다.

lzop이러한 유형의 데이터(중복된 비압축 청크)의 경우 와 함께 압축(매우 빠름)을 사용해야 합니다. lrzip중복이 제거된 후에는 완전히 임의의 데이터를 압축하기 위해 더 열심히 노력해도 이점이 없기 때문입니다.

법앤오브남

질문에 태그를 지정했으므로, 여기서 목표가 데이터 백업이라면 다음과 같은 중복 제거 백업 프로그램을 사용하는 것이 좋습니다.부프또는오브남.

답변3

gzipxz사전 크기가 크 더라도 중복 항목을 찾을 수 없습니다 . 당신이 할 수 있는 것은 사용하는 것입니다 mksquashfs. 이것은 실제로 중복 공간을 절약할 것입니다.

xz3개의 임의 바이너리 파일(64MB)을 사용한 몇 가지 빠른 테스트 결과( mksquashfs이 중 2개는 동일함):

설정:

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

답변4

'기계식 달팽이'의 답변에 추가로:

압축되지 않은 단일 파일의 파일 크기(더 정확하게는 중복 파일 간의 거리)가 사전 크기를 초과하는 경우 xz(또는 lzma)도 중복 파일을 찾지 못합니다. xz(또는 lzma)는 최고 설정에서도 -9e이를 위해 64MB만 예약합니다.

운 좋게도 옵션을 사용하여 자신만의 사전 크기를 지정할 수 있습니다 --lzma2=dict=256MB ( --lzma1=dict=256MB명령에 lzma 별칭을 사용할 때만 허용됨)

불행하게도 위의 예에서처럼 사용자 정의 압축 체인으로 설정을 재정의할 때 다른 모든 매개변수의 기본값은 -9e와 동일한 수준으로 설정되지 않습니다. 따라서 단일 파일의 경우 압축 밀도가 높지 않습니다.

관련 정보