ddを並列化する方法は?


10

現在dd、入力(if)としてスパースファイルを使用し、出力(of)としてファイルを使用して起動すると問題が発生しますconv=sparseddCPUの1つのコア(Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz4コア+ 4 Intelハイパースレッド)のみ(1コアの100%)を使用しているようなので、並列化が可能かどうか疑問に思っていましたdd。行ったことがある

  • 調べてみるinfo ddman dd、corutils 8.23のバージョンに組み込み関数があるようです。
  • (それが私のニーズに合っているかどうかを理解せずに)パッケージsgp_ddからチェックしsg3-utilsますが、スパースファイルを処理することができないようです
  • dcfldd 並列化機能がないようです

私の知る限り

  • 複数のスレッドでのプログラムパーツの内部処理を備えた拡張バージョン/フォーク(I / Oパフォーマンスを低下させるコンテキスト変更を回避する)が優先されます
  • parallelローカルで実行されているGNUのソリューションが優先されます
  • カスタム(テストされていない可能性がある)コードスニペット

I / O集中型操作のボトルネックとなるCPUを回避する方法 Linux 3.13を搭載したUbuntu 14.04でコマンドを実行し、スパースファイルをサポートする任意のファイルシステムでスパースファイルのディスクイメージを処理したいと思います(少なくとも、ソリューションは1つの特定のファイルシステムにバインドされるべきではありません)。

背景:私は、zfsに11 TBのスパースファイル(約2 TBのデータを含む)のコピーを作成しようとしています(zfsonlinux 0.6.4不安定バージョン、バグが多く、CPUボトルネックの原因(最終的には低速のホール検索))。(非常に一般的な方法で)ddを並列化する方法の問題については、何も変更されません。


この操作は極端な場合を除いてI / Oバウンドであるため、これから何が得られるかわかりません。私の意見では、最適なオプションは、スパース対応のプログラム、たとえばxfs_copyなどです。そのmanページには言及:「しかし、ファイルはXFSファイルシステム上に作成された場合、ファイルが消費するには、おおよそ実際にファイルシステムとXFSログでソースファイルシステムで使用されるスペースの量xfs_copyが空きブロックの上に追求するため、省スペースです。それらをコピーする代わりに、XF​​Sファイルシステムはスパースファイルを効率的にサポートします。
クリスティアンCiupitu 2014年

@mikeservコメントが理解できません...
Karl Richter、

@CristianCiupitu私の場合、CPUがボトルネックです-わからないので、理由を聞かないでください。あなたの答えは、ソリューションが複数のファイルシステム(スパースファイルを処理できる)をサポートする必要があることを私に認識させました(編集済み)
Karl Richter

CPUとファイルシステムは何ですか?ファイルのサイズはどれくらいですか(長さとブロック)?
クリスティアンCiupitu 2014年

4
ddブロックサイズが小さいため、デフォルトでCPUを占有します。のように大きくしbs=1Mます。
frostschutz 2014年

回答:


4

バッシュでテスト:

INFILE=in
seq 0 1000 $((`stat --format %s $INFILE` /100000 )) |
  parallel -k dd if=$INFILE bs=100000 skip={} conv=sparse seek={} count=1000 of=out

おそらく1000を調整する必要があります。


2

未テストのカスタムコードスニペットが1つ登場します。

dd if=oldf conv=sparse bs=1k                 count=3000000000                 of=newf &
dd if=oldf conv=sparse bs=1k skip=3000000000 count=3000000000 seek=3000000000 of=newf &
dd if=oldf conv=sparse bs=1k skip=6000000000 count=3000000000 seek=6000000000 of=newf &
dd if=oldf conv=sparse bs=1k skip=9000000000 count=3000000000 seek=9000000000 of=newf &
wait

これにより、ファイルが4つの3TBチャンクに論理的に分割され、並列に処理されます。(skip=入力ブロックをスキップしseek=、出力ブロックをシークします。)もちろん、4番目のコマンドは古いファイルの最後まで読み取ります。そのため、count=パラメーターは厳密には必要ありません。


私もそのようないくつかについて考えましたが、それを任意のサイズのファイルの一般的な解決策にする方法を理解できませんでした(質問の背景が一般的な解決策に対する私の要求に影響を与えるべきではありませんでした)
Karl Richter

あなたの言っていることが理解できません。私はちょうどあなたのファイルの指定されたサイズを取り、コアの数で割っただけです。これは簡単にスクリプトで実行できます。
G-Manは 'Reinstate Monica'を

3
おそらくまた必要conv=notrunc
frostschutz 2014年

@frostschutz:たぶん最初のものだけかもしれません。このドキュメントは見つかりませんが、私のテストでは、それconv=notruncseek=正の値で示されていることを示しています。
G-Manは 'Reinstate Monica'を

1
いいえ、シークはnotruncを意味しません。
frostschutz 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.