綾小路龍之介の素人思考

[rsync] 同期を並列に行う

単純にrsyncしたら、50GBの同期に3日くらいかかった。送信元で見ると10Mbpsの帯域が1.2Mbps程度しか使われていない。同期スピードが遅すぎるので、試しに並列でrsyncするシェルスクリプトをざっくりと書いてみた。テストはしていない。

/home/hoge/以下を/home/fugaにバックアップする場合、以下のようにかける。

$ rsync -avv --checksum --backup --backup-dir=/home/fuga_bkup /home/hoge/ /home/fuga

これを並列に行う。ざっくりと言って、/home/hoge/以下のディレクトリがほとんど同じサイズだとすれば、以下のようにかける。ほとんど書き捨て。

$ cat rsync.sh
#!/bin/sh -x

DEBUG=1

SRC=/home/hoge/
DST=/home/fuga/
BKUP=/home/fuga_bkup
RSYNC="rsync -avv --checksum --backup"

mkdir -p "${DST}"

for i in `find "${SRC}" -depth -maxdepth 1 ! -regex "${SRC}"`
do
    if [ "${DEBUG}" = "1" ];
    then
        echo ${RSYNC} --backup-dir="${BKUP}" "${i}" "${DST}" &
    else
        ${RSYNC} --backup-dir="${BKUP}" "${i}" "${DST}" &
    fi
done

wait
ls -R "${BKUP}"

上のスクリプトだと、ディレクトリに空白文字が含まれる場合に失敗する。そこで以下。ざっくりとこれでおk。10Mbpsの帯域を5.8Mbps程度使うようになった。

$ eval `find /home/hoge/ -depth -maxdepth 1 ! -regex /home/hoge/ -exec echo rsync -avv --checksum --backup --backup-dir=/home/fuga_bkup \"{}\" /home/fuga/ \& \;`
$ eval `find /home/hoge/ -depth -maxdepth 1 ! -regex /home/hoge/ -exec echo rsync -avv --checksum --backup --backup-dir=/home/fuga_bkup/ \"{}\" /home/fuga/ 2\>\&1 \& \;`

各ディレクトリ内に含まれるファイルだけの同期をとることで、高速化を狙う。

$ find \
	/path/to/src/ \
	-depth \
	-type d \
	-printf '/path/to/src/./%P\0' \
| xargs \
	-0 \
	-r \
	-n 1 \
	-P 16 \
	-I{} \
	rsync \
	--archive \
	--no-recursive \
	--relative \
	{} \
	/path/to/dst/ \
;

リファレンス

  1. rsyncの-R(--relative)オプション
  2. Does the -depth option of find imply depth-first tree traversal? - Unix & Linux Stack Exchange

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2010-06-19T18:56:25+09:00
  2. Modified: 2010-06-19T18:56:25+09:00
  3. Generated: 2018-07-01T23:09:11+09:00