web-dev-qa-db-ja.com

同時/同時ファイル転送でrsyncを高速化しますか?

15TBのデータをあるサーバーから別のサーバーにできるだけ早く転送する必要があります。現在rsyncを使用していますが、ネットワークが150Mb/siperfでテスト済み)に対応している場合、900+Mb/s程度の速度しか得られません。ディスク、ネットワークなどのテストを行ったところ、rsyncが一度に1つのファイルのみを転送していることが原因で、速度が低下していることがわかりました。

ディレクトリツリーの各フォルダーに対して異なるrsyncを実行するスクリプトを見つけました(x数に制限することができます)が、それを動作させることはできません。一度に1つのrsyncを実行するだけです。

scripthere (以下にコピー)が見つかりました。

ディレクトリツリーは次のようになります。

/main
   - /files
      - /1
         - 343
            - 123.wav
            - 76.wav
         - 772
            - 122.wav
         - 55
            - 555.wav
            - 324.wav
            - 1209.wav
         - 43
            - 999.wav
            - 111.wav
            - 222.wav
      - /2
         - 346
            - 9993.wav
         - 4242
            - 827.wav
      - /3
         - 2545
            - 76.wav
            - 199.wav
            - 183.wav
         - 23
            - 33.wav
            - 876.wav
         - 4256
            - 998.wav
            - 1665.wav
            - 332.wav
            - 112.wav
            - 5584.wav

したがって、私は、/ main/filesの各ディレクトリに対して、一度に最大5つまでのrsyncを作成することを望んでいます。したがって、この場合、/main/files/1/main/files/2、および/main/files/3に対して3つのrsyncが実行されます。

私はこのように試してみましたが、/main/files/2フォルダーに対して一度に1つのrsyncを実行するだけです。

#!/bin/bash

# Define source, target, maxdepth and cd to source
source="/main/files"
target="/main/filesTest"
depth=1
cd "${source}"

# Set the maximum number of concurrent rsync threads
maxthreads=5
# How long to wait before checking the number of rsync threads again
sleeptime=5

# Find all folders in the source directory within the maxdepth level
find . -maxdepth ${depth} -type d | while read dir
do
    # Make sure to ignore the parent folder
    if [ `echo "${dir}" | awk -F'/' '{print NF}'` -gt ${depth} ]
    then
        # Strip leading dot slash
        subfolder=$(echo "${dir}" | sed 's@^\./@@g')
        if [ ! -d "${target}/${subfolder}" ]
        then
            # Create destination folder and set ownership and permissions to match source
            mkdir -p "${target}/${subfolder}"
            chown --reference="${source}/${subfolder}" "${target}/${subfolder}"
            chmod --reference="${source}/${subfolder}" "${target}/${subfolder}"
        fi
        # Make sure the number of rsync threads running is below the threshold
        while [ `ps -ef | grep -c [r]sync` -gt ${maxthreads} ]
        do
            echo "Sleeping ${sleeptime} seconds"
            sleep ${sleeptime}
        done
        # Run rsync in background for the current subfolder and move one to the next one
        Nohup rsync -a "${source}/${subfolder}/" "${target}/${subfolder}/" </dev/null >/dev/null 2>&1 &
    fi
done

# Find all files above the maxdepth level and rsync them as well
find . -maxdepth ${depth} -type f -print0 | rsync -a --files-from=- --from0 ./ "${target}/"
41
BT643

これは簡単そうです:

ls /srv/mail | parallel -v -j8 rsync -raz --progress {} myserver.com:/srv/mail/{}
35
Manuel Riel

rsyncは、ネットワークを介してできるだけ速くファイルを転送します。たとえば、それを使用して、宛先にまったく存在しない1つの大きなファイルをコピーしてみてください。その速度は、rsyncがデータを転送できる最大速度です。 (たとえば)scpの速度と比較します。 rsyncは、宛先ファイルが存在する場合の生の転送ではさらに遅くなります。これは、両側でファイルのどの部分が変更されるかについて双方向のチャットを行う必要があるためです。

rsyncを並行して実行するより簡単な方法は、 parallel を使用することです。以下のコマンドは、最大5つのrsyncsを並行して実行し、それぞれが1つのディレクトリをコピーします。ボトルネックはネットワークではないかもしれませんが、CPUとディスクの速度、および物事を並行して実行すると、すべてが遅くなり、速くなりません。

run_rsync() {
    # e.g. copies /main/files/blah to /main/filesTest/blah
    rsync -av "$1" "/main/filesTest/${1#/main/files/}"
}
export -f run_rsync
parallel -j5 run_rsync ::: /main/files/*
26
Stuart Caie

一度に多くのプロセスの実行をサポートするxargsを使用できます。あなたの場合は次のようになります:

ls -1 /main/files | xargs -I {} -P 5 -n 1 rsync -avh /main/files/{} /main/filesTest/
12
Nickolay

これを行うための多くの代替ツールとアプローチがウェブ上にリストされています。例えば:

  • NCSAブログ には、xargsおよびfindを使用して、ほとんどの* nixシステムに新しいソフトウェアをインストールせずにrsyncを並列化する説明があります。

  • parsync は、並列rsync向けの機能豊富なPerlラッパーを提供します。

10
Bryan P

Parallel_syncという名前のpythonパッケージを開発しました

https://pythonhosted.org/parallel_sync/pages/examples.html

使用方法のサンプルコードを次に示します。

from parallel_sync import rsync
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'Host':'192.168.16.31'}
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds)

デフォルトの並列処理は10です。あなたはそれを増やすことができます:

from parallel_sync import rsync
creds = {'user': 'myusername', 'key':'~/.ssh/id_rsa', 'Host':'192.168.16.31'}
rsync.upload('/tmp/local_dir', '/tmp/remote_dir', creds=creds, parallelism=20)

ただし、sshでは通常、デフォルトでMaxSessionsが10に設定されているため、10を超えて増やすには、ssh設定を変更する必要があります。

4
max

私が見つけた最も簡単な方法は、シェルでバックグラウンドジョブを使用することです。

for d in /main/files/*; do
    rsync -a "$d" remote:/main/files/ &
done

ジョブの量を制限しないことに注意してください!ネットワークにバインドされている場合、これは実際には問題ではありませんが、Rustの回転を待っている場合、ディスクがスラッシングされます。

追加できます

while [ $(jobs | wc -l | xargs) -gt 10 ]; do sleep 1; done

ジョブ制御のプリミティブ形式のループ内。

0
sba