私は、Java ベースの picard ツールを使用して重複をマークするための BAM ファイルを処理するために GNU parallel を使用しています。parallel ユーティリティを使用する理由は、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 があるため、上記のコマンドで、一度に 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
実際に 3 GB を使用し、30 GB を予約すると仮定すると、スワップ領域を追加しない限り、メモリが不足する前に 4 つのジョブしか並列実行できません。
java
メモリを予約したからといって、必ずメモリにアクセスするというわけではありません。
私の提案は、1 TB のスワップスペースを追加することです。
Linux カーネルにメモリのオーバーコミットを依頼することもできます。ただし、これを行うとサーバーが予期せずクラッシュするという悪い経験があるため、この解決策はお勧めしません。
でもあなたはできるzswap を使用します。この方法では、スワップに何かが書き込まれると、カーネルはまずそれを圧縮して RAM に保持しようとします。それが失敗した場合にのみ、メモリはディスクに書き込まれます。ディスク上の 1 TB (低速) のスワップ領域と組み合わせると、これは非常に効率的に機能します。