ハードウェアリソースを無駄にせずに動的ストリーム圧縮を行いますか?

ハードウェアリソースを無駄にせずに動的ストリーム圧縮を行いますか?

200GBの空きディスク容量、16GBのRAM(デスクトップとカーネルが約1GBを占める)、6GBのスワップ領域があります。

240GBの外付けSSDがあり、そのうち70GBを使用し、残りは無料なので、ディスクにバックアップする必要があります。

通常、dd if=/dev/sdb of=Desktop/disk.img最初にディスクを作成してから圧縮しますが、最初にイメージを作成することはオプションではありません。これは、圧縮段階で空き容量が圧縮され、最終イメージが圧縮されても必要以上のディスク容量が必要になるためです。アーカイブは私のディスクに簡単に入れることができます。

ddデフォルトでは、STDOUTに書き込んでgzipSTDINから読み取ることができるので、理論的には書き込むことができますが、バイトをdd if=/dev/sdb | gzip -9 -生成するよりも読み込むgzipのにはるかに時間がかかります。dd

~からman pipe:

パイプの書き込みの終わりに書き込まれたデータは、パイプの読み取りの最後から読み取られるまでカーネルによってバッファリングされます。

私は|パイプラインを実際のパイプラインとして想像しています。あるアプリケーションはデータをパイプラインキューにプッシュし、他のアプリケーションはできるだけ早くパイプラインキューからデータを取得します。

パイプの反対側で処理できるデータよりも左側のプログラムがより速くデータを書き込むとどうなりますか?過度のメモリやスワップ領域の使用は発生しますか?または、カーネルはディスクにFIFOを作成してディスクを埋めようとしますか?それともSIGPIPE Broken pipeバッファが大きすぎると失敗しますか?

デフォルトでは、これは2つの質問に帰結します。

  1. 一度に読み取ることができるよりも多くのデータがパイプにプッシュされると、どのような影響と結果が発生しますか?
  2. 圧縮されていないデータストリーム全体をディスクに保存せずにデータストリームをディスクに圧縮する安定した方法は何ですか?

注 1: 断片化やその他の要因によってコンテンツ全体が破損しないようにするため、最初に使用した 70 GB の正確なコピーを作成して動作するシステムやファイルシステムを取得することは期待できません。

ベストアンサー1

ddデータブロックは一度に1つずつ読み書きし、未解決のデータブロックは1つだけです。だから

valgrind dd if=/dev/zero status=progress of=/dev/null bs=1M

dd1MBのメモリが使用されます。チャンクのサイズを変更して削除すると、valgrind速度に与える影響を確認できます。dd

gzip入力するときはdd一致速度を遅くしてくださいgzip。メモリ使用量が増えず、カーネルがディスクにバッファを保存することもできません(カーネルはこれを行う方法がわかりません)。渡す交換)。チューブ破裂signal(7)は、チューブの一端が死んだときにのみ発生しますwrite(2)

だから

dd if=... iconv=fullblock bs=1M | gzip -9 > ...

欲しいものを達成する安全な方法です。

パイピング中に読み取りプロセスが維持されない場合、最終的に書き込みプロセスはカーネルによってブロックされます。これを実行すると見ることができます

strace dd if=/dev/zero bs=1M | (sleep 60; cat > /dev/null)

1MBの読み取りが表示されddたら、aを実行しwrite()、実行中にしばらく待ちますsleep。これがパイプの両側がバランスをとる方法です。書き込みプロセスが速すぎる場合、カーネルは書き込みをブロックし、読み取りプロセスが速すぎるとカーネルは読み取りをブロックします。

おすすめ記事