--compress-program
나는 큰 파일(>100Go)을 정렬하고 있는데, 디스크에 쓰는 데 소요되는 시간을 줄이기 위해 GNU sort 매개변수를 사용하려고 합니다 . (관련된:대용량 파일을 정렬하는 방법은 무엇입니까?)
하지만 어떤 경우에는 첫 번째 임시 데이터만 압축되는 것 같습니다. 이유와 모든 임시 파일을 압축하기 위해 무엇을 할 수 있는지 알고 싶습니다.
나는 다음을 사용하고 있습니다 :
sort (GNU coreutils) 8.25
lzop 1.03
/LZO library 2.09
문제를 재현하는 단계:
잠시 동안 약 15Go의 여유 공간과 약 10Go의 메모리가 필요합니다.
먼저 다음 C 코드를 사용하여 10Go 파일을 만듭니다.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned long n;
unsigned char i;
srand(42);
for(n = 0; n < 1000000000; n++) {
for(i = 0; i < 3; i++) {
printf("%03d", rand() % 1000);
}
printf("\n");
}
fflush(stdout);
return 0;
}
그리고 실행하세요:
$ gcc -Wall -O3 -o generate generate.c
$ ./generate > test.input # takes a few minutes
$ head -n 4 test.input
166740881
241012758
021940535
743874143
그런 다음 정렬 프로세스를 시작합니다.
$ LC_ALL=C sort -T . -S 9G --compress-program=lzop test.input -o test.output
일정 시간이 지나면 프로세스가 일시 중지되고 동일한 폴더에 생성된 임시 파일이 나열됩니다(으로 인해 -T .
).
$ ls -s sort*
890308 sortc1JZsR
890308 sorte7O878
378136 sortrK37RZ
$ file sort*
sortc1JZsR: ASCII text
sorte7O878: ASCII text
sortrK37RZ: lzop compressed data - version 1.030, LZO1X-1, os: Unix
sortrK37RZ
(첫 번째 임시 생성된 것) 만 압축된 것 같습니다 .
[편집] 문제가 발생한 경우 동일한 sort
명령을 실행하고 -S
설정하면 7G
문제가 없었습니다(즉, 모든 임시 파일이 압축되었습니다).8G
[편집] lzop은 다른 임시로 호출되지 않습니다.
나는 다음 스크립트를 래퍼로 시도하고 사용했습니다 lzop
.
#!/bin/bash
set -e
echo "$$: start at $(date)" >> log
lzop $@
echo "$$: end at $(date)" >> log
log
여러 임시 파일이 디스크에 기록될 때 파일 내용은 다음과 같습니다.
11109: start at Sun Apr 10 22:56:51 CEST 2016
11109: end at Sun Apr 10 22:57:17 CEST 2016
그래서 내 생각에는 압축기가 전혀 호출되지 않는 것 같습니다.
답변1
여기 재현 안됐나요?
$ shuf -i1-10000000 > t.in
$ sort -S50M -T. t.in --compress-program=lzop # ^z
$ file sort* | tee >(wc -l) > >(grep -v lzop)
7
$ fg # ^c
$ sort --version | head -n1
sort (GNU coreutils) 8.25
문제는 큰 메모리 크기로 인해 압축 프로세스를 포크()한 다음 표준 쓰기로 돌아갈 수 없다는 것입니다. IE sort(1)는 이상적으로 압축 프로세스를 보다 효율적으로 분기하기 위해 posix_spawn()을 사용해야 할 때 fork()/exec()를 사용하고 있습니다. 이제 fork()는 CoW이지만 이러한 대규모 프로세스에 대한 관련 회계 구조를 준비하는 데 여전히 오버헤드가 있습니다. sort(1)의 향후 버전에서는 이 오버헤드를 피하기 위해 posix_spawn()을 사용할 것입니다(glibc는 버전 2.23부터 posix_spawn()의 사용 가능한 구현을 얻었습니다).
또한 더 작은 -S를 사용하는 것이 좋습니다. 어쩌면 - S1G 이하.