我正在使用 GNU parallel 处理 BAM 文件,以便使用基于 Java 的 picard 工具标记重复项。使用并行实用程序的原因是 picard 工具不是多线程的,而且数据集非常庞大。所以我使用以下命令和 GNU parallel:
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 个线程和 126 GB RAM,我希望上述命令能够处理当前目录中存在的所有 bam 文件,同时一次处理 12 个 bam。
实际产量
最后,我只得到了 4 或 5 个已处理的 BAM 文件,而当前目录有大约 15 个 BAM 文件。我还收到了内存溢出错误(尽管我已经使用命令检查了内存分配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
实际使用 3 GB,但预留 30 GB,那么在内存耗尽之前,您只能并行运行 4 个作业 - 除非您添加交换空间。
仅仅因为java
保留了内存,并不意味着它会触碰它。
我的建议是您添加 1 TB 的交换空间。
您还可以要求 Linux 内核过度使用内存。但是我有过这样的经历:服务器意外崩溃,所以我不建议采用这种解决方案。
但是你能使用 zswap。这样,如果有任何内容要写入交换,内核将首先尝试压缩它并将其保存在 RAM 中。只有当它无法这样做时,内存才会写入磁盘。结合磁盘上的 1 TB(慢速)交换空间,这种方法非常有效。