2台のPC間でファイルを高速にコピーしたい
MacBook で VMware Fusion 上のゲストOSに保存されているファイル (約20万ファイル、7GBくらい)を外部ストレージにバックアップしようと考えたのですが、数時間単位で時間が掛かりそうだったので、別の方法でバックバックすることにしました。
ただし、ここで紹介する方法はmacOSのターミナルやWindows10のWSLでコマンドを入力するやりかたなので、この手の操作に慣れていない方には向かない方法です。
基本的なアイデア
- MacBookに接続する外部ストレージは、macOSでハンドリングさせるほうが高速なはずである
- しかし macOS 側で認識しているストレージに VMware Fuision のゲスト側から直接アクセスできないようである
- よって macOS 側で簡易的な受けプログラムを用意し、ゲストOS側から受けプログラムにファイルを渡せば良い
- ディレクトリ構造含めて渡したいので、ホスト側とゲスト側のデータは tar のフォーマットで受け渡そう
- nc (netcat) を使えば、tar の結果をネットワーク側に渡したり、ネットワーク側から受け取って tar で展開したりできる
- 低速回線は使わないので、途中でネットワークの問題で切れても気にしない、というか、考えない
- 最終的なコピー先は exFAT でフォーマットしたUSBストレージなので、パーミッションについては細かく問わない
このアイデアの注意事項
通信経路上のデータは暗号化されず、平文のままで流れます。信用できないネットワークではこの方法は使えません。素直に ssh とかを使いましょう。
ループバックネットワークなら問題ありません。また、自宅ネットワークのように利用者が限定されるローカルネットワークならギリギリ許容範囲でしょう。
実際の方法
nc を準備する
Windows 側では WSL をインストールしているなら、そこに nc を追加するだけです。sudo apt install nc
するだけと思います。
macOS 側は標準で nc コマンドが使えると思います。
nc で相互通信できることを確かめる。
macOS 側で nc -l 10080
と実行し、ゲストOS側から nc [macOSのIPアドレス] 10080
のように実行します。
10080 はTCPポート番号です。ゲストOS側でキーボードを適当に叩いた結果が macOS 側に表示されていたら通信はできています。
nc を介して tar のデータを受け渡す
macOS 側で、ファイルを出力したいディレクトリで nc -l 10080 | tar xf -
のように実行します。
ゲストOS側では、ファイルをコピーしたいディレクトリで tar cf - | nc [ホスト名] 10080
のように実行します。
疎通テストの nc コマンドの出力を tar に引き渡したり、tar の結果を疎通テストの nc コマンドに渡すだけです。
もし、macOS側に PV (pipe viewer) をインストールしている場合は nc -l 10080 | pv | tar xf -
のように実行すれば、macOS側で受信したデータ量や、リアルタイムのデータ転送レートが分かります。
実際にやってみた例
これはPVを組み合わせた例ですが、macOS側で受け取っているデータの合計と、処理時間、瞬間的な受信レートが表示されています。出力先ストレージは2.5inch USB-HDDです。このケースではファイル数が多い(=ファイル1つあたりのファイルサイズが小さい)ので、ものすごく速いという感じではありませんが、MWare Fusion でUSBデバイスをマウントして書き込むのに比べたら高速ではないかと思います。
% nc -l 10080 | pv | tar xf - 6.72GiB 0:35:42 [6.75MiB/s] [ <=> ]
ちなみに、ファイル数がもっと少ない別のフォルダをバックアップしてみると、こんな感じでバックアップが進むので、もうちょっと速くなっています。
% nc -l 10080 | pv | tar xf - 2.00GiB 0:04:03 [13.6MiB/s] [ <=> ]