web-dev-qa-db-ja.com

rsyncの並列化

移動と試行錯誤の末、自宅とリモートサーバーの間のどこかでスロットルが実行されていることを発見しました。しかし、スロットルはあまりインテリジェントではありません。個々の接続のみを調整します。したがって、1 GBのファイルを1つコピーすると、150 kBpsで問題なく処理されます。ただし、10個のコピーを初期化すると、それぞれのコピーは150 kBpsになります(つまり、複数の接続で、より高い総帯域幅が得られます)。

私はかなりの頻度でrsyncを使用して、いくつかの大きなデータセットを仕事から家まで同期します(幸いにも多くのファイルの形式で)。複数の接続を使用してダウンロードするようにrsyncに指示する方法はありますか?理論的には、私が知る限り、rsyncは必要な変更を決定するために最初にパスを実行し、次に実際の送信を実行するため、可能であるはずです。 rsyncに個々のファイルをN個にスライスしてからスプライスするように指示する魔法の方法がある場合のボーナスポイント。私は、CuteFTPが実際にそれをうまくやるのに十分賢いと信じています。

31
stuyguy

いくつかのTBから1つNASを別のNASにバックアップ/復元なしで移動する必要がある1つのセットをもう1つのセットにフィードできるようにする機能。

そこで、このスクリプトを作成して、遭遇するディレクトリごとに1つのrsyncを実行しました。ソースディレクトリを一覧表示できるかどうかに依存します(ARG 3をエスケープするように注意してください)が、ファイルとディレクトリを適切なレベルにコピーするだけの非再帰的なrsyncでそのステージを設定できると思います。

また、プロセッサーの数に基づいて実行するrsyncの数も決定しますが、調整することもできます。

頭に浮かぶもう1つの可能なオプションは、rsyncを--list-onlyモードで実行することです。

これにより、更新する必要のあるすべてのファイルが得られます。xargsを使用してrsyncの数を管理している場合、リスト内の各ファイルに対して1 rsyncを実行すると、非常にエレガントになります。実際、おそらくここの私の小さなスクリプトよりもエレガントな解決策です...

#! /bin/bash
SRC_DIR=$1
DEST_DIR=$2
LIST=$3
CPU_CNT=`cat /proc/cpuinfo|grep processor |wc -l`
#  pseudo random heuristic
let JOB_CNT=CPU_CNT*4
[ -z "$LIST" ] && LIST="-tPavW --exclude .snapshot --exclude hourly.?"
echo "rsyncing From=$SRC_DIR To=$DEST_DIR DIR_LIST=$LIST"
mkdir -p /{OLD,NEW}_NAS/home
[ -z "$RSYNC_OPTS" ] && RSYNC_OPTS="-tPavW --delete-during --exclude .snapshot --exclude hourly.?"
cd $SRC_DIR
echo $LIST|xargs -n1 echo|xargs -n1 -P $JOB_CNT -I% rsync ${RSYNC_OPTS} ${SRC_DIR}/%/ ${DEST_DIR}/%/
13
kkron

GNU Parallelには解決策があります

15 TB= 1 Gbps移動しましたが、1 Gbpsリンクを飽和させる可能性があります。

次の例では、src-dirの大きなファイルごとに1つのrsyncを開始し、サーバーfooserverのdest-dirに移動します。

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{}

作成されたディレクトリが誤った権限で終了する可能性があり、小さいファイルは転送されません。それらを修正するには、最後にrsyncを実行します。

rsync -Havessh src-dir/ fooserver:/dest-dir/
6
Ole Tange

はい。このような機能が存在します。

説明された機能を提供する pssh と呼ばれるユーティリティがあります。

このパッケージは、opensshツールの並列バージョンを提供します。配布物に含まれるもの:

  • 並列ssh(pssh)
  • 並列scp(pscp)
  • パラレルrsync(prsync)
  • 並列核(pnuke)
  • 並列スラップ(pslurp)

簡単に設定できるかわかりませんが、うまくいくかもしれません。

3
Tim Bielawa

私はコメントできないので、少しだけ良いコードで新しい答えを追加しました 前のものより (ナイス&スマート)コード。

オプションのrsync Tweakが含まれているため、ionice行を確認してください。

#!/bin/bash
start_time=$(date +%s.%N)
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=6
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/user/public_html/images
[email protected]:/home/user/public_html/images
RSYNC_OPTS="-ah --partial"
# Main loop:
for FULLDIR in $SRC_BASE/*; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 1
    done
    DIR=`basename $FULLDIR`
    echo "Start: " $DIR
    ionice -c2 -n5 rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    # rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    sleep 5
done

execution_time=$(echo "$(date +%s.%N) - $start" | bc)
printf "Done. Execution time: %.6f seconds\n" $execution_time
3
Widmo

誰かがあなたのためにこのユーティリティを書いたようです。転送を並列のチャンクに分割します。これは、GNU Parallel:にリストされている「並列ビッグファイル」バージョンよりも優れた実装です。

https://Gist.github.com/rcoup/5358786

また、lftpはftp、ftps、http、https、hftp、fish、sftpを介したファイル転送を並列化できます。多くの場合、rsyncのアクセス許可やアクセス制限などの管理は困難な場合があるため、lftpを使用することにはいくつかの利点があります。

2
Erik Aronesty

いいえ。そのような機能はありません。本当に望めば、同期をrsyncへの複数の呼び出しに分割できます。

このレート制限を行っていることを何でも見つけて、それを維持/管理している人と真剣に話し合うことをお勧めします。

1
David Schwartz

複数のファイルを含む複数のディレクトリを同時に転送したかったので、次の小さなスクリプトを作成しました。

#!/bin/bash
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=10
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/sites
[email protected]:/var/www
RSYNC_OPTS="--stats -ilrtpog"
# Main loop:
for FULLDIR in $SRC_BASE/*/; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 10
    done
    DIR=`basename $FULLDIR`
    rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ & 
    sleep 1 
done
echo "Done."

私はこのスクリプトを非常に高速に実行したので、運用環境で使用する前に修正してテストしてください。

1
lepe

次のスクリプトを作成して、画像を含む多数のフォルダを並行してアップロードしました。最初に同期ターゲットを指定して実行し、次にコピーするすべてのフォルダー名を指定して実行します。

#!/bin/sh

dest="$1"
shift

if [ "$dest" = "" ]; then
    echo "USAGE: $0 TARGET:/foo/bar <dir1> [dir2] [dir3]"
    exit 1
fi

RCol='\x1B[0m' # Text Reset
BYel='\x1B[1;33m';

for i in "$@"; do
    prefix=`printf "$BYel%50s:$RCol" "$i"`
    echo "$prefix * Starting $i"
    echo "$prefix -> syncing '$i/' to '$dest/$i/'"
    (rsync -rv "$i/" "$dest/$i/") 2>&1 | sed "s/^/$prefix /g" &
    sleep 0.5
done

echo "* Waiting for all to complete"
wait

見栄えを良くするために、すべてのrsyncコンソール出力の前に黄色のフォルダー名を付けます。

0
konrad