2012年7月31日火曜日

ftp を使ってディスク丸ごとバックアップ

最近、カーネルやOSSソース, ISO イメージの収集蓄積を行うのに、ZFS on Linux を利用しています。 メイン PC のディスクを丸ごとバックアップすることも利用目的の1つです。

しかし、ネット上にいくつも情報があるように、ZFS on Linux + NFS アクセスする場合、どうにも性能が出ないようです。
わたしの環境では、書き込みスループットが 1 MB/s を下回るくらいです。とても実用にはなりません。GigaBit Ether で接続しており、ftp ならば 50MB/s くらいは出る環境なのに、NFS だと全然遅くなってしまうのです。残念。バックアップ対象の PC のディスクは 180GB であり、圧縮して 100GB になったとしても、1 MB/s ですから、100000 秒もかかる計算です。どうにかできないものか・・・

ディスク丸ごとバックアップするというと、次のように dd で NFS 領域へ書き込みというのが、わたしのお決まりのパターンなのですが。。。
# dd if=/dev/sda bs=1M | lzop -c > /mnt_nfs/sda.dd.lzo

ftp ならスループット 50MB/s 出るのだし、なんとかして ftp に dd + lzop の出力を渡して転送できないの?・・・とサーチしてみると、なんと超簡単ではありませんか!無知でした。
ftp> bin
200 Type set to I
ftp> put |"dd if=/dev/sda1 bs=1M | lzop -c" sda1.dd.lzo
local: |dd if=/dev/sda1 bs=1M | lzop -c remote: sda1.dd.lzo
227 Entering Passive Mode (192,168,xxx,xxx,128,22).
150 Opening BINARY mode data connection for sda1.dd.lzo
196+1 records in
196+1 records out
205599744 bytes (206 MB) copied, 11.0407 seconds, 18.6 MB/s
226 Transfer complete.
90549924 bytes sent in 11 seconds (8e+03 Kbytes/s)
なんと、Linux (に限らずかな?) の ftp コマンドでは、put の第一引数の先頭に | を指定すれば、パイプラインからデータを読み取ってくれるのですね。作った人に感謝。

2012-08-01追記
上のコンソールは、VMware 上での実験結果ですが、実際 180GB のディスクバックアップを実行してみました。
[root@livedvd Desktop]# ftp mypc
Connected to mypc (10.xx.yyy.zzz).
220 (vsFTPd 2.2.2)
Name (mypc:centoslive): user01
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> bin
200 Switching to Binary mode.
ftp> put |"dd if=/dev/sda bs=1M | lzop -c" user01.sda.backup-2012-08-01.lzo
local: |dd if=/dev/sda bs=1M | lzop -c remote: user01.sda.backup-2012-08-01.lzo
227 Entering Passive Mode (10,xx,yyy,zzz,uuu,vvv).
150 Ok to send data.
171705+1 records in
171705+1 records out
180045766656 bytes (180 GB) copied, 3891.19 s, 46.3 MB/s
226 Transfer complete.
127003147717 bytes sent in 3.89e+03 secs (32638.60 Kbytes/sec)
対象の PC は、普段は Windows XP が動いているマシンなのですが、CentOS 6.3 LiveDVD を利用してバックアップを行いました。Live 状態では、ftp と lzop が未導入なので、yum でインストールする必要がありました。
LiveDVD は初めて使いましたが、こういったケースでは便利なものですね。

結果として、圧縮後の転送レートは 32MB/s で、約1時間でバックアップが完了しました。
これは、わたしとしては十分に満足できる結果です。

2012-08-03追記
1時間でバックアップできるなら十分かと思いましたが、多少工夫の余地がありましたので、追試を行いました。
まず、圧縮率が低い (180G:127G) のは、ファイルシステム (NTFS) の空き領域に過去に書き込んだデータの痕跡があるためと考えられるので、空き領域にオールゼロデータを書き込んでからバックアップを実行すれば、もっと時間短縮できそうでしたので、次のような Ruby スクリプトを使って、ゼロ書き込みを行いました。Linux なら dd if=/dev/zero of=zerofile とすればいいわけですが、Windows XP なので、一筆。
#!/usr/bin/env ruby
#
# Name: zerofill.rb
#

f = open("zerofile", "wb")

z = [0].pack("N")

@z4 = []

for i in 0...1024
        @z4.push(z)
end

z4096 = @z4.join('')

begin
        while true
                f.write(z4096)
        end
end
なお、Windows XP 上の Ruby スクリプト実行には、Rumix を利用しています。

加えて、前回の実験の際に top で挙動を見ていたら、dd でディスクデータ読み出しを行うと、buffers の値が搭載物理メモリサイズの限界まで上昇し、メモリ回収のため kswapd カーネルスレッドが頻繁に動いていました。
でも、この場合は無駄な動きと思えますので、dd に iflag=direct オプションをつけて実行してみました。結果は次の通り。
ftp> put |"dd if=/dev/sda iflag=direct bs=1M | lzop -1 -c" user01.sda.backup-2012-08-02.lzo
local: |dd if=/dev/sda iflag=direct bs=1M | lzop -1 -c remote: user01.sda.backup-2012-08-02.lzo
227 Entering Passive Mode (10,xx,yyy,zzz,uuu,vvv).
150 Ok to send data.
171705+1 records in
171705+1 records out
180045766656 bytes (180 GB) copied, 2297.55 s, 78.4 MB/s
226 Transfer complete.
40910990817 bytes sent in 2.3e+03 secs (17806.37 Kbytes/sec)
期待どおり、約38分で完了しましたし、バックアップファイルのサイズもコンパクトになりました。

0 件のコメント:

コメントを投稿

人気ブログランキングへ にほんブログ村 IT技術ブログへ