ネットワーク負荷をかけずにデータを転送する(robocopyでの帯域制御)

Windows全般
スポンサーリンク

データ転送時のネットワーク帯域制御をrobocopyで行う話です。別記事でもっと簡単な方法を紹介していますが、その方法が適さないケースで有効な方式です。「理屈はいいからすぐやる方法は?」という方向けに、なるべく即戦力で使えるバッチを用意しました。ぜひお役立て下さい。

要件例

遠隔地のWindows共有フォルダから、10GBの大容量データをこちら側に転送する必要がある。途中経路には100Mbps程度の転送能力をもつ回線がある。何も考えずにデータ転送すると、ネットワーク帯域を圧迫してしまい、他の通信に支障が生じるため、負荷を抑えてデータを転送したい。なお、遠隔地の共有フォルダ側の設定は変更できない

方式概要

ここでは、Windows標準のrobocopyコマンドを、帯域制御オプション付きで使います。下記のバッチファイルで、通信速度をおおむね8Mbps(1MB/秒)に絞っています。

Windowsの帯域制御としては、QoSポリシーを使う方式もあり、こちらの方が設定しやすいでしょう。しかし、こちらは送信方向しか制御できません。また、ポリシーの設定変更が必要です。今回の要件例は、受信方向かつ共有フォルダ側の設定変更ができないケースですので、この方式は使えません。

実現方法

バッチファイルのダウンロード

手っ取り早く実現したい人は、以下からバッチファイル一式をダウンロードしてお使い下さい。ZIPファイルを解凍したフォルダを任意の場所に置き、「robocopy_slow.bat」を環境に合わせて編集して下さい。

バッチファイルの中身

@rem 帯域制限付きのコピーバッチ https://se-abeaver.com/


@rem コピー元のパスを指定
set COPY_FROM=\\192.168.50.1\share

@rem コピー先のパスを指定
set COPY_TO=receive

@rem 資格情報 コピー元or先に接続するためのユーザー名 
set USER_NAME=contoso\user1

@rem 資格情報 コピー元or先に接続するためのパスワード
set USER_PASS=P@ssw0rd

@rem 帯域制御の指定値 詳細は下記<参考>に
set WAIT_TIME=53

@rem <参考>64KB転送するごとにウェイトする時間(ミリ秒)を指定。大きくするほど転送速度が遅くなります。
@rem  ●WAIT_TIME(/IPG: オプション)指定値のスループット目安
@rem       1000 :  0.5Mbps前後
@rem        500 :  1Mbps前後
@rem        150 :  3Mbps前後
@rem         90 :  5Mbps前後
@rem         53 :  8Mbps前後
@rem         40 : 10Mbps前後
@rem         30 : 12.5Mbps前後
@rem         23 : 15Mbps前後
@rem         15 : 20Mbps前後
@rem          7 : 30Mbps前後
@rem ※制限なしで50Mbps、各種オーバーヘッド考慮しない理論値。環境により変動するため実測し調整して下さい。


cd %~dp0
net use %COPY_FROM% /user:%USER_NAME% %USER_PASS%

robocopy %COPY_FROM% %COPY_TO% /E /R:3 /W:10 /LOG:log-robocopy_slow.txt /TEE /Z /IPG:%WAIT_TIME%
@rem 補足:「/NP」オプション(ログに余分な進捗率を吐かない)をつけると帯域制御が機能しない模様(不具合か)

pause;

解説

robocopy 帯域制御の仕組み(/IPG オプション)

robocopyコマンドの「/IPG」オプションで通信速度を下げるわけですが、クセがあります。「1MB/秒に制限」のようには指定できません。できるのは「1ブロック転送した後に、〇ミリ秒ウェイトする」というものです。

robocopy {...途中省略...} /Z /IPG:53

上記の場合、1ブロック転送したら53ミリ秒転送を止めるということです。これが何Mbps相当なのか、普通すぐには分かりません。なので、バッチの中身に転送速度の目安をコメントで書いておきました。環境によってかなりずれる(特にIPGの値が小さい場合)ので、実測で調整して下さい。

「/Z」オプションをつけることで、1ブロックが64KBの転送になります。デフォルトは1MBですが、64KBとした方が、狙った速度にしやすいです。それに、例えば1GBのファイルのコピー中に中断した場合、再試行時は途中から転送できるという利点もあります。通常「/Z」オプションは付けませんが、この要件には適しています。

robocopyオプション

今回のrobocopyコマンドは次のようにオプションを指定しています。それぞれを簡単に解説します。

robocopy {コピー元パス} {コピー先パス} /E /R:3 /W:10 /LOG:{ログファイルパス} /TEE /Z /IPG:53

  • /E
    • サブフォルダ(空フォルダ含む)をコピーします。
  • /R:3
    • コピー失敗したファイルについて、再試行回数を3回にします。
    • デフォルトの100万回(ご乱心?)だと、一つ失敗すると実質動作停止するため。
  • /W:10
    • コピー失敗時の再試行までの待ち時間を10秒にします。
    • デフォルトは30秒で、このままでいいかもしれませんが、少し短くしています。
  • /LOG:{ログファイルパス}
    • コピー結果をログファイルに出力します。
    • 今回はバッチファイルと同じフォルダに「log-robocopy_slow.txt」という固定ファイル名で、毎回上書きします。
  • /TEE
    • ログ出力もしつつ、コマンドプロンプトにもコピー状況を表示します。
    • 上記「/LOG」オプションだけを指定すると、画面でコピー状況が分からないため。
  • /Z
    • 前項参照
  • /IPG
    • 前項参照

その他のバッチコマンド

cd %~dp0

カレントディレクトリを「このバッチファイルがあるフォルダ」にします。こうすると、このバッチと同じフォルダに「receive」フォルダがある場合、相対パスのフォルダ名だけで指定できます(C:\script\copybatch\receive みたいに書かなくて済みます)。

補足

この方式では、狙った転送速度(○○Mbps)にキレイに固定することはできません。ファイル数や個々のサイズによって、速度はかなりバラつきが出てしまいます。タスクマネージャーでネットワーク転送量のグラフを見ると分かりますが、かなりギザギザしていて、瞬間的には狙った転送速度以上が出てしまいます。

これは帯域制御の方式上、仕方ありません。帯域制御の目的は、他の通信を阻害しないためだと思います。高い転送速度が出たとしても、瞬間的であれば他の通信に悪影響を与える可能性は低いので、目的は果たせるでしょう。

おわりに

今回の記事は以上です。ご質問やご意見等ありましたら、下のコメント欄やtwitterからお願いします。

当サイトでは、ITインフラ関連の知識やノウハウをメインに紹介しています。下の関連記事にも役立つ情報があるかもしれませんので、ぜひご覧下さい。

また、知識やノウハウを効率的に学ぶ方法として、Udemy の「ながらセミナーもおすすめです。三日坊主にならず、普段の生活の中でスキルアップする方法です。これについては下の記事で紹介していますので、良ければご覧下さい。

もとだて
もとだて

最後まで読んでいただき、ありがとうございました。

フィードバック

コメント

タイトルとURLをコピーしました