robocopyが異常に遅い、なぜか速度が出ない、というときに確認すべき3つのポイントを紹介します。
この記事で紹介している以下のポイントを実践することで確実に速度がアップします。
- Robocopyプロセスの優先度を確認
- 再試行オプションを確認
- Robocopyを実行するサーバ(コピー元かコピー先)を確認
Robocopyプロセスの優先度を確認
Robocopyを実行する状況としては、タスクスケジューラに登録して定期的に実行させる場合が多いと思います。
実行されるプロセスには優先度が設定されますが、以下画像は、
- タスクスケジューラに登録したRobocopyのタスクを実行
- タスクマネージャーからRobocopyプロセスの優先度を確認
したものです。
画像の通りタスクスケジューラに登録されたタスクで実行されるプロセスは通常以下という優先度で実行されてしまっています。
どういうことかというと、
自動的に優先度が低く設定されてしまうために、Robocopyプロセスに割り当てられるリソースが制限されてしまうのです。割り当てられるリソースというのは、CPUやメモリなどだけでなく、ネットワーク帯域やディスクIOなどもそれに含まれます。
つまり、Robocopyプロセスが通常以下という優先度で実行されているため、使用できるリソース(CPUやメモリ領域、ネットワーク帯域やディスクIO)が制限されてしまい速度が抑えられていると考えられます。
この問題の解決策として、そのプロセスの優先度を高く設定することで使えるリソースも増えて速度がアップします。ただ、タスクスケジューラにタスクを登録する設定画面には優先度の設定箇所はありません。。。
優先度の設定方法は、以下の手順が必要になりますので、その手順を説明します。
- 一度登録したタスクをXML形式でエクスポート
- エクスポートしたXMLファイルを編集
- 編集したXMLファイルをタスクスケジューラにインポート
タスクスケジューラの優先度設定方法
まず、通常のやり方でタスクスケジューラにRobocopyのタスクを登録します。
次に、登録したRobocopyのタスクを右クリックして、エクスポートをクリック → デスクトップなどに保存します。
保存したXMLファイルをメモ帳などのテキストエディタで開きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
: 略 : <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>PT72H</ExecutionTimeLimit> <Priority>7</Priority> ★ </Settings> <Actions Context="Author"> <Exec> <Command>C:\Users\Admin\TOOLs\FileBackup.bat</Command> </Exec> </Actions> </Task> |
Priority の項目が優先度の設定になります。設定値と内容は以下の通りです。(情報元はMicrosoftのサイトより)
0 | リアルタイム |
1 | 高 |
2 | 通常以上 |
3 | 通常以上 |
4 | 通常 |
5 | 通常 |
6 | 通常 |
7 | 通常以下 |
8 | 通常以下 |
9 | 低 |
エクスポートしたものは、Priority が 7 となっているはずです。これを6より小さい値に編集します。
編集が完了したら、タスクスケジューラにインポートします。以下の画像の通り、タスクスケジューラを開いて、空白箇所で右クリック → タスクのインポートをクリック → 編集したXMLファイルを指定します。
通常に変更するだけでも効果はありますが、深夜に実行する場合などでコピー以外にリソースを確保する必要がなければ、通常以上 や 高 に変更してどのくらい変わるのか確認しながらチューニングしていってもよいと思います。
ぴぐろぐが試した結果としては、高やリアルタイムに変更しても通常と比較してそんなに速度のアップはみられませんでした。ただ、通常以下→通常に変えるだけでかなり速度はアップしましたので、少なくとも 通常 には変更することをおすすめします。
再試行オプションを確認
処理にかかる時間の点において、必ず指定をすべきオプションがふたつあります。
- /R:<n>
コピーに失敗した場合に再試行(リトライ)する回数を指定します。
<n>のデフォルト値は1,000,000となっています。
つまり、コピーに失敗し続けた場合、100万回リトライを行うということになります。 - /W:<n>
コピーに失敗した場合の再試行(リトライ)の間隔を「秒」で指定します。
<n>のデフォルト値は30となっています。
つまり、コピーに失敗した場合は、30秒待機してからリトライを行うということになります。
例えば、何かしらのエラーによってコピーが失敗し続けた場合は、
100万回×30秒=3000万秒
の時間がかかることになります。「3000万秒」は 約8333時間となり、日に換算すると 約347日 となります。。。
このあたりの設計思想をぜひマイクロソフトさんに伺ってみたいものです。Robocopy自体がかなり昔に開発され、現役で使われ続けているにもかかわらず改修されないということは、この設計が正しいものだと認識されているのでしょうか。。。
・・・という話は置いておいて、こういう 仕様 であることを理解してデフォルトでは使わず必ず値を指定することをおすすめします。
例えば、Robocopyを利用してバックアップを取得する環境という点で、そこまでSLAが高くないバックアップ要件であると仮定してのぴぐろぐ推奨値としては以下になります。
/R:1 | リトライ回数1回 |
/W:0 | 待機時間0秒 |
例えば社内ファイルサーバのバックアップなどを日次で行っている場合(その日がダメでも次の日に取れるはずと想定)などですかね。
Robocopyを実行するサーバ(コピー元かコピー先)を確認
Robocopyを実行するのは、コピー元とコピー先のどちらがよいと思いますか?
動きとしては、転送元と転送先でファイルの存在有無やファイルサイズ、タイムスタンプを比較してコピーするか否かを判断するため、処理能力の高いサーバで実行したほうがコピー要否の判断が早いと考えられます。
そのため、転送元と転送先のサーバスペックを比較して、スペックの高いほうでRobocopyを実行したほうが良いということになります。
サーバのリプレイスで古いサーバと新しいサーバのスペックがほとんど変わらないという場合は、世代が新しいほうが処理能力は上がっているはずなので、新しい方のサーバで実行させたほうが良いはずです。
3つのポイントで改善しない場合
ここまでで紹介した3つのポイントで改善しない場合に、どこにボトルネックがあるのか、確認してみると良い点を記載しておきます。
- 転送元/転送先の間のネットワーク機器の帯域やスペック
- 物理ディスクのステータス
└ 転送先のディスクが古すぎないか
└ RAIDを構成している1本が故障していないか - 他のコピー(書き込み)が重複していないか
まとめ
Robocopyが遅いときに確認すべき3つのポイントを紹介しましたがいかがでしたでしょうか。
1つ目と2つ目の項目については、タスクスケジューラ(Windows)やRobocopyの仕様を理解すすることで自ずと見えてくるかと思います。3つ目の項目については「ツール」というよりも「インフラ」という観点で考えた際のポイントですね。
考え方のポイントとしてはRobocopyに限ったことではないので試行錯誤して自分なりのやり方を見つけていただければと思います。
他にも良い方法があればコメントお願いします!
↓↓↓ 持っていると便利な一冊 ↓↓↓