rsyncの並列化


30

引っ越して、試行錯誤の結果、自宅とリモートサーバーの間のどこかで調整が行われていることを発見しました...しかし、調整はあまりインテリジェントではありません。個々の接続のみを調整します。そのため、1 GBのファイルを1つコピーすると、150 kBpsで楽に進みます。しかし、10個のコピーを初期化すると、それぞれが150 kBpsになります(つまり、複数の接続でより高い総帯域幅が得られます)。

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

回答:


13

バックアップ/復元機能なしで、1つのNASから別のNASに数TBを移動しなければならないという同様の問題が発生しました。

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

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

思い浮かぶ他の可能なオプションは、-list-onlyモードでrsyncを実行することです。

これにより、更新する必要があるすべてのファイルが提供されます。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}/%/

2
これは機能します-機能を大幅に改善できますが、xargsを使用してアプリケーションを並列化するという概念は非常に斬新です。
マットパーク

6

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

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

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

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/

1
「例:rsyncの並列化」セクションを回答に貼り付けてください。将来リンクが切れた場合に備えて。
ピコビット

3

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

説明した機能を提供するpsshというユーティリティがあります。

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

  • 並列ssh(pssh)
  • 並列scp(pscp)
  • 並列rsync(prsync)
  • 並列核(pnuke)
  • 並列丸lurみ(pslurp)

設定がどれほど簡単かはわかりませんが、うまくいくかもしれません!


26
psshユーティリティは、1つのサーバーで同じコマンドを何度も実行するのではなく、複数のサーバーにコマンドを分散するために使用されます。特に、prsyncは、ローカルマシン上のファイルの複数の外部マシンへの送信のみをサポートします。複数の接続があるリモートファイルのダウンロードはサポートしていません。
デレクダーマー

1
@DerekDahmerのコメントを考えると、この回答のポスターはそれを撤回したいと思うかもしれません。
mc0e

3

コメントできないので、新しい回答を追加しました。以前の(素敵でスマートな)コードよりも少し優れたコードです。

rsyncオプションの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
DST_BASE=user@hostname.domain.local:/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

2

誰かがこのユーティリティを作成してくれたようです。転送を並列チャンクに分割します。これは、GNU Parallelの下にリストされている「parallel big file」バージョンよりも優れた実装です。

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

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


これは機能しますが、同じファイルをダウンロードするために複数の接続を使用しているだけではないため、大量のディスクの断片化をすばやく引き起こす可能性があります。
bparker

1

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

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


4
多くの場合、これらの制限はComcastのようなISPからのものです。幸運なことに、彼らと何らかの合理的な会話をすることができます。
ジェームズムーア

1

同時にいくつかのディレクトリ(多くのファイル)を転送したかったので、この小さなスクリプトを作成しました。

#!/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
DST_BASE=user@example.com:/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."

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


0

次のスクリプトを作成して、写真のある多くのフォルダーを並行してアップロードします。最初に同期ターゲットで実行し、次にコピーするすべてのフォルダー名で実行します。

#!/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コンソール出力に黄色のフォルダー名のプレフィックスを付けます。


-1

Aria2は、多くのミラーからの多くの接続を使用してデータをダウンロードするための優れたクライアントプログラムです。SFTPはサポートしていません。そこで、FTPサーバー-vsftpdをインストールしました。私の3g接続は、FTPサーバーへの5つの接続でフルパワーで動作します。


1
あなたの答えが役に立つように、それを拡張してくれませんか?
Tog
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.