Java 기반 picard 도구를 사용하여 중복을 표시하기 위해 BAM 파일을 처리하기 위해 GNU 병렬을 사용하고 있습니다. 병렬 유틸리티를 사용하는 이유는 picard 도구가 멀티 스레드가 아니고 데이터 세트가 매우 방대하기 때문입니다. 그래서 GNU 병렬로 다음 명령을 사용하고 있습니다.
ls *.bam | sed 's/.bam.*//' | parallel --eta -j 12 "java -jar picard.jar MarkDuplicates I={}.bam O=/bam1/{}.bam M=/bam1/{}_dup_matrices.txt"
기대 내 서버에는 40개의 스레드와 126GB RAM이 있으므로 위 명령이 한 번에 12개의 bam을 처리하면서 현재 디렉터리에 있는 모든 bam 파일을 처리하기를 바랐습니다.
실제 출력
결국 현재 디렉터리에는 약 15개의 BAM 파일이 있는 반면 처리된 BAM 파일은 4~5개만 얻게 됩니다. 또한 메모리 오버플로 오류가 발생합니다(명령을 사용하여 메모리 할당을 확인했는데 ulimit
무제한으로 표시되었음에도 불구하고).
메모리 문제 없이 현재 디렉터리에 있는 모든 파일을 자동으로 처리하도록 GNU 병렬 유틸리티를 사용할 수 있습니까?
편집-1: 여기에 출력을 추가합니다 ulimit -a
.
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 514974
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 514974
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
답변1
java
종종 사용하는 것보다 훨씬 더 많은 메모리를 예약합니다. 10배는 흔하지 않습니다. 따라서 picard
실제로 3GB를 사용하지만 30GB를 예약한다고 가정하면 스왑 공간을 추가하지 않는 한 메모리가 부족해지기 전에 4개의 작업만 병렬로 실행할 수 있습니다.
메모리를 예약한다고 해서 java
메모리에 접근하는 것은 아닙니다.
내 제안은 1TB의 스왑 공간을 추가하는 것입니다.
Linux 커널에 메모리 오버커밋을 요청할 수도 있습니다. 하지만 그렇게 할 때 예기치 않은 서버 충돌이 발생하는 나쁜 경험이 있으므로 해당 솔루션을 사용하지 않는 것이 좋습니다.
하지만 당신은~할 수 있다zswap을 사용하세요. 이렇게 하면 스왑에 무엇인가 기록될 경우 커널은 먼저 이를 압축하여 RAM에 유지하려고 시도합니다. 그렇게 하지 못한 경우에만 메모리가 디스크에 기록됩니다. 디스크의 1TB(느린) 스왑 공간과 결합하면 매우 효율적으로 작동합니다.