ネットワーク越しのファイルコピーにおなじみの rsync.
今回、クライアントもサーバも 3 に移行できた組み合わせがあったので試してみた。使ったのはクライアントもサーバも rpmforge の rsync 3.0
単純に軽い
ベンチとかないんですけど、
バージョン | CPU使用率(目測) |
rsync 2 同士 | 20 〜 40 % |
rsync 3 同士 | 1%未満 〜 3% |
残念ながらCPU性能も変わっているのでこの数字を出しても比較にならないんだけど、さすがに10倍も性能向上はしていないので、それを差し引いてもやはり CPU 負荷は数分の一以下になっていると見て間違いないと思う。
今までは結構簡単に跳ね上がっていた CPU 使用率が、ほんとに rsync は動いているのか?と疑いたくなるくらいに大人しいまま。これはすごい。
–iconv での文字コード変換
※ 文字コードなのかエンコーディングなのかというのはここでは問わないでください。
rsync --iconv=SOURCE,DEST
という形で文字コードを指定する1。例えばこんな感じ。
rsync --iconv=utf8,iso88591
と、マニュアルには書いてある。でもこのハイフン抜きの表記って iconv –list には出てこないんだけど大丈夫かなぁと気になったらどうもハイフンはあってもなくてもいいみたい2。
rsync --iconv=.
でシステムのデフォルトの文字コードを locale から推測する。
変換を無効にするには
rsync --iconv=-
や
rsync --no-iconv
とする。もちろん iconv 関連のオプションを付けないという方法でもいいんだけど、動的にオプションを生成することを考えると –iconv=- がいちばん楽かな。
daemon として動かす場合は module に charset 指定が必要
[MODULE]
path = /path/to/rsyncd_root
charset = REMOTE_CHARSET
って感じ。これを指定していない MODULE に対して
rsync --iconv=eucjp,utf8 rsync://HOST/MODULE
みたいに指定するとそんなオプションは許可されてねぇ、と怒られ、転送そのものに失敗する。
charset が指定したものに対して invalid である場合
[sender] cannot convert filename: FILENAME (Invalid or incomplete multibyte or wide character)
このようなエラーが出て該当ファイルの転送に失敗する。
分かりやすく言い換えると、charset の指定に失敗していると
日本語ファイル名のものだけ転送されなくなる
ということ。この動作は恐らく誰も期待していないと思う。
結論として
ファイル名の文字コードが「確実にこれになる」と言い切れない path を rsyncd の対象としている場合、iconv のオプションは利用しない方が無難。
例えば WinSCP で日本語ファイル名を転送する可能性のある領域には Shift JIS(たぶんCP932?) の名前のファイルができる。同じ場所を Netatalk 2 や Samba 3 でマウントしている場合、これらのサービス経由では普通 UTF-8 のファイル名で保存される。つまり、「Shift JIS の名前と UTF-8 の名前が混ざっている」状態になる。
この領域に対して rsyncd.conf で
[MODULES]
path = /path/to/rsyncd_root
charset = UTF8
と指定しても、
[MODULES]
path = /path/to/rsyncd_root
charset = CP932
と指定しても転送漏れが起きる可能性がある。
余談 - rsync の制限は rsyncd.conf で
いつも自動化している rsync を使ったファイルの転送は remote shell 上で rsync コマンドを叩く
rsync REMOTE LOCAL -e ssh
rsync LOCAL REMOTE -e ssh
という形ではなく、daemon として待機している rsync プロセスに接続する方法
rsync rsync://REMOTE LOCAL
rsync LOCAL rsync://REMOTE
を利用している。これならアクセスできるパスや read only にするなどの制限を簡単に掛けられるし、制限 shell の方の扱いも単純化できるし、rsync を叩く機械と ssh や Zebedee でトンネルを作る機械の分離も簡単にできる。個人的にはバッチ処理で rsync をトンネル越しに動かす場合は rsync –daemon + rsyncd.conf を使った方がいいんじゃないかと思っている。