ディスク/ディスクのコピーを遅くする


28

Linuxでコピープロセスを遅くする方法はありますか?

10GBなどの大きなファイルがあり、別のディレクトリにコピーしたいのですが、フルスピードでコピーしたくありません。もっと速くではなく、1mb / sの速度でコピーしたいとしましょう。標準のLinux cpコマンドを使用したいと思います。

これは可能ですか?(はいの場合、どのように?)

編集:だから、私は達成しようとしているものにもっとコンテキストを追加します。

USB経由で大きなファイルを(ペンドライブ、USBディスクなどに)コピーするときにArchLinuxシステムに問題があります。usbバッファーキャッシュがいっぱいになると、システムが応答しなくなります(マウスが停止することもあります;散発的にしか動きません)。コピー操作はまだ進行中ですが、ボックスの100%のリソースが必要です。コピー操作が完了すると、すべてが正常に戻ります。すべてが完全に応答します。

おそらくハードウェアエラーかもしれませんが、この問題を抱えているマシンが2台あることは知っています(両方ともArchLinux上にあり、1台はデスクトップボックス、2台目はラップトップです)。

これに対する最も簡単で最速の「解決策」は、USBドライブの平均書き込み速度でファイルをコピーすることにより、このバッファがいっぱいになるのを防ぐことです(「本当の」解決策ではなく、単なるい「ハック」です)それで十分でしょう。


7
システム内の他のI / Oバウンドプロセスに「ナイス」になろうとしてディスク間のコピー速度を制限しようとする場合は、おそらくI / Oスケジューリングを調整するカーネルの機能を利用することをお勧めします代わりに。具体的にioniceは、ディスクからディスクへのコピープロセスが通常のプロセスよりも低い優先度でスケジュールされたI / Oであることを確認するために使用できます。
スティーブン14

3
これは、古典的なXY問題の質問です。代わりに、ファイルをUSBデバイスにコピーするときにデスクトップが応答しなくなる理由について質問する必要があります。
マイケルハンプトン14年

4
Linuxには最近、途方もなく大きなI / Oバッファがあります。RAMサイズは、大容量ストレージの速度よりも速く成長しました。たぶん、dd(1)とsyncを使用してコピーを実行し、バッファリングされる代わりに実際に定期的に同期されるようにできますか?また、パイプビューアー(pv)にはレート制限オプションがあります。のようなものcat file | pv -L 3k > outfile。ただし、どちらもcp(1)を使用した場合と同じではありません。
ptman 14年

@ MichaelHampton、ArchLinuxのフォーラムにはこの問題に関する未解決のトピックがいくつかあるため、機能させるために別の方法で対処しようと考えました。
アントノン14年

@antononeしかしUnix.SEはArchLinuxのフォーラムではありません。ここの誰かが解決策を持っているかもしれません。
イズカタ14年

回答:


23

パイプを絞ることができますpv -qL(またはcstream -t同様の機能を提供します)

tar -cf - . | pv -q -L 8192 | tar -C /your/usb -xvf -

-q stderr進捗レポートを削除します。

-Lリミットはバイトです。

--rate-limit/-Lからのフラグの詳細man pv

-L RATE, --rate-limit RATE

    Limit the transfer to a maximum of RATE bytes per second.
    A suffix of "k", "m", "g", or "t" can be added to denote
    kilobytes (*1024), megabytes, and so on.

この回答はもともと指摘してthrottleいましたが、そのプロジェクトはもう利用できないため、一部のパッケージシステムから脱落しました。


cp速度を落とすことができない場合、カスタムコマンドを使用することが唯一のオプションです。
アントノン14年

1
と比較して複雑すぎるようですrsync
LinuxSecurityFreak

より複雑に見えますが、私にとっては使いやすいです。ファイルのロック機構をテストする必要があり、rsyncでは不可能と思われる数バイト/秒までのコピーを遅くする必要があります。それを試してみて、スロットルパイプを介してファイルを「猫化」します
cljk

悲しいことですが、プロジェクトは死んでいますbugs.debian.org/cgi-bin/bugreport.cgi?bug=426891
cljk

1
@cljkをに更新しましたpv。ありがとう。
マット

23

代わりに、必要に応じて帯域幅をcp -a /foo /bar使用rsyncおよび制限することもできます。

以下からrsyncのマニュアル:

--bwlimit=KBPS

I / O帯域幅を制限します。キロバイト/秒

したがって、actuallコマンドは、進行状況も表示して、次のようになります。

rsync -av --bwlimit=100 --progress /foo /bar

これは、私が勝ちたくない古いドライブをコピーするための良いアイデアのように聞こえます。
jeremyjjbrown

/dev/zeroまたは/dev/random
cdosborn

rsync -a --bwlimit=1500 /source /destination1.5 MB / sの速度で巨大なフォルダーをコピーするのに完全に機能します(サーバーの速度低下を避け、時間をかけすぎないこととのトレードオフです)
-lucaferrario

補足:マニュアルページでは、ユニットに文字を使用できると書かれている場合でも、たとえば20m、すべてのプラットフォームでサポートされているわけではないため、KBytes表記を使用することをお勧めします。
ヒューバート・グジェスコヴィアック

私の一日を救った!cgroupはcgexec -g ... cp /in /outすべての時間を働いていませんでした(端末からスクリプトから、いくつかの時間を決して働いていない)と私は考え、なぜ...持っていない
アクエリアスパワー

13

私はあなたが他の活動を妨げないようにしていると思います。Linuxの最近のバージョンには、ionice、IOのスケジューリングを制御できるものがています。

さまざまな優先順位を許可することに加えて、ディスクがアイドル状態の場合にIOを制限する追加オプションがあります。コマンドman ioniceはドキュメントを表示します。

次のようなコマンドを使用してファイルをコピーしてみてください。

ionice -c 3 cp largefile /new/directory

2つのディレクトリが同じデバイス上にある場合、ファイルをリンクすると目的の動作が行われることがあります。バックアップのためにコピーする場合は、このオプションを使用しないでください。 lnファイル自体はコピーされないため、非常に高速です。試してください:

ln largefile /new/directory

または、別のデバイス上のディレクトリからアクセスしたいだけの場合:

ln -s largefile /new/directory

ioniceはLinuxでうまく機能しますか?私はそれを「エミュレート」するだけで読んだのですが、本当の違いはありませんか?リンクの+1
ニック

1
@Nick使用したとき、期待どおりに動作しました。ioniceを適用したプロセスは大幅に遅くなり、I / Oを必要とする他のプロセスは期待どおりに実行できました。他のプロセスからの適度なI / O負荷で、期待どおりに最大限の「ナイスネス」を適用することで、高I / Oプロセスを効果的に中断することができました。競合するI / Oがなくなると、イオン化プロセスは通常どおり実行されました。
BillThor

400MBのファイルで、HDからSSDにコピーしていましたが、最初の10秒間は完全に機能していましたが、突然IOの負荷が高くなり、1分間マシンがフリーズするまで待たなければなりませんでした:/。私はcgroup write ioスロットルで同じ問題を抱えています。
アクエリアスパワー

7

場合ioniceソリューションが(whyever)は十分ではありませんし、あなたが本当に絶対値にI / Oを制限するいくつかの可能性があります。

  1. おそらく最も簡単な:ssh。帯域幅制限が組み込まれています。例えばtar(代わりにcp)またはscp(それで十分な場合、シンボリックリンクとハードリンクをどのように扱うかわかりません)またはを使用しrsyncます。これらのコマンドは、データをパイプ処理できますssh。以下の場合はtarあなたに書く/dev/stdout(または-)とパイプそれにssh別のものを実行し、クライアントtar「リモート」の側に。

  2. エレガントですが、バニラカーネル(AFAIK)ではありません:デバイスマッパーターゲットioband。もちろん、これは、ソースボリュームまたはターゲットボリュームのいずれかをアンマウントできる場合にのみ機能します。

  3. 自己記述的な楽しみ:grep "^write_bytes: " /proc/$PID/ioプロセスが書き込んだデータ量を提供します。cpバックグラウンドで開始し、たとえば1/10秒スリープし、バックグラウンドcpプロセスを停止し(kill -STOP $PID)、書き込まれた量を確認し(この場合は同じ値について読み取ります)、どれくらいの時間を計算するスクリプトを書くことができますcp平均転送速度を意図した値に下げるために一時停止する必要があり、その時間スリープし、ウェイクアップcpkill -CONT $PID)するなど。


はい、通常はlftpを使用してscp経由でローカルホストに接続し、そこからバンドウィッチを制限しています。
アントノン14年

5

あなたの問題はおそらくあなたのコンピューターにあるのではなく、おそらくそれで問題ないでしょう。しかし、そのUSBフラッシュ遷移層には、書き込みのすべてをマッピングして、90%の欠陥のあるフラッシュチップを補うための独自のプロセッサがあります。あなたはそれをあふれさせ、それからあなたのバッファをあふれさせ、そしてあなたはバス全体をあふれさせ、そしてあなたは立ち往生します、男-結局のところ、それはすべてのものがどこにあるかです。直感に反するように聞こえるかもしれませんが、本当に必要なのはI / Oをブロックすることです。FTLにペースを設定させてから、遅れないようにする必要があります。

(FTLマイクロコントローラーのハッキングについて:http ://www.bunniestudios.com/blog/ ? p=3554

上記の答えはすべて機能するはずなので、これは「私もです!」他の何よりも:私は完全にそこにいました、男。rsyncの--bwlimitで問題を解決しました argを使用(2.5 MBは、エラーのない単一の実行のスイートスポットであるように思われました-それ以上の場合、書き込み禁止エラーが発生します)。私はファイルシステム全体で作業していたので、rsyncは私の目的に特に適していました-そのため、多くのファイルがありました-単にrsyncを2回実行すると、最初の実行の問題がすべて修正されます2.5MBを超えてランプアップする)。

それでも、私はそれが単一のファイルに対してそれほど実用的ではないと思います。あなたの場合、生の書き込みに設定されたddにパイプするだけです-あなたはそのように入力を処理できますが、一度に1つのターゲットファイルしか処理できません(もちろん、その単一のファイルはブロックデバイス全体になる可能性があります)。

## OBTAIN OPTIMAL IO VALUE FOR TARGET HOST DEV ##
## IT'S IMPORTANT THAT YOUR "bs" VALUE IS A MULTIPLE ##
## OF YOUR TARGET DEV'S SECTOR SIZE (USUALLY 512b) ##
% bs=$(blockdev --getoptio /local/target/dev)

## START LISTENING; PIPE OUT ON INPUT ##
% nc -l -p $PORT | lz4 |\ 
## PIPE THROUGH DECOMPRESSOR TO DD ## 
>    dd bs=$bs of=/mnt/local/target.file \
## AND BE SURE DD'S FLAGS DECLARE RAW IO ##
>        conv=fsync oflag=direct,sync,nocache

## OUR RECEIVER'S WAITING; DIAL REMOTE TO BEGIN ##
% ssh user@remote.host <<-REMOTECMD
## JUST REVERSED; NO RAW IO FLAGS NEEDED HERE, THOUGH ## 
>    dd if=/remote/source.file bs=$bs |\
>    lz4 -9 | nc local.target.domain $PORT
> REMOTECMD  

netcatを試してみると、データトランスポートでsshよりも少し高速であることがわかります。とにかく、他のアイデアはすでに採用されています。

[編集]:他の投稿でlftp、scp、sshについて言及していることに気づき、リモートコピーについて話していると思いました。ローカルの方がはるかに簡単です:

% bs=$(blockdev --getoptio /local/target/dev)
% dd if=/src/fi.le bs=$bs iflag=fullblock of=/tgt/fi.le \
>    conv=fsync oflag=direct,sync,nocache

[編集2]:当然のことながらクレジット:ptmanがコメントの5時間ほどで私にこれを打ち負かしたことに気付いた。

確かに、ここで乗数を使用してパフォーマンスのために$ bsを調整できますが、一部のファイルシステムでは、ターゲットfsのセクターサイズの倍数である必要があるため、そのことに留意してください。


私のマシンでは、フラグは--getioopt--getoptio
Michael Mior

2

問題は、コピーが「飛行中」のブロックでメモリをいっぱいにし、「有用な」データを押し出していることです。デバイス(この場合はUSB)を遅くするI / OのLinuxカーネル処理における既知の(および修正が非常に難しい)バグ。

おそらく、次のようなスクリプトによってコピーを分割しようとすることができます(概念実証のスケッチ、完全にテストされていません!)。

while true do
  dd if=infile of=outfile bs=4096 count=... seek=... skip=...
  sleep 5
done

調整seekskipによって、count各ラウンド。countメモリーがいっぱいになりすぎないように調整する必要があり5ます。


2

ダーティページの制限を下げます。デフォルトの制限は非常識です。

/etc/sysctl.d/99-sysctl.confを作成します:

vm.dirty_background_ratio = 3
vm.dirty_ratio = 10

次に、sysctl -pを実行するか、再起動します。

起こっているのは、データが宛先ディスクに書き込まれるよりも速く読み取られているということです。Linuxがファイルをコピーするとき、ファイルをRAMに読み込み、宛先に書き込むためにページをダーティとしてマークします。汚れたページはスワップアウトできません。したがって、ソースディスクがターゲットディスクよりも高速で、空きRAMよりも多くのデータをコピーしている場合、コピー操作は使用可能なすべてのRAM(または少なくともダーティページの制限は何でも)を使い果たしますダーティページはスワップアウトできず、クリーンページは使用され、解放されるとダーティとしてマークされるため、飢starを引き起こします。

彼が問題を完全に解決するわけではないことに注意してください... Linuxが本当に必要とするのは、ダーティページの作成を調停する方法であり、大量の転送が利用可能なRAM /許可されたすべてのダーティページを使い果たすことはありません


0

この問題は、ハードウェアまたはソフトウェアのエラーや障害とは関係ありません。カーネルがあなたに親切になり、プロンプトをバックグラウンドで戻してコピーしようとしているだけです(カーネル内キャッシュを使用します:RAM、キャッシュ、ただし、/ procのどこかに書き込むことで制限できます-推奨されません。フラッシュドライブは遅すぎるため、カーネルが書き込みを行っている間は、他のIO操作を十分に高速に実行できません。ionice他の答えで数回言及されていても大丈夫です。しかし-o sync、OSのバッファリングを避けるためにドライブをマウントするだけで試してみましたか?これはおそらく最も簡単なソリューションです。


-o syncを有効にすると、インターネットはこのUSBドライブへの書き込み速度よりも速くなります。私が理解していないのは、カーネルがキャッシュページのフラッシュ速度を追跡せず、それに基づいて将来のフラッシュをスケジュールしない理由です。この貧弱なドライブが速度に追いついていない場合でも、常にフルスピードになるようです。しかし、それは私が推測する別の質問のトピックです。
アントノン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.