scp コマンドを並列化するにはどうすればいいですか?

scp コマンドを並列化するにはどうすればいいですか?

から へmachineBファイルを scp する必要があります。 から以下のシェル スクリプトを実行しています。 ssh キーを適切に設定しました。machineCmachineAmachineA

ファイルが にない場合はmachineB、 にあるはずですmachineC。シェル スクリプトで以下に示すように、PARTITION1 および PARTITION2 ファイルをすべて machineA のそれぞれのフォルダーに移動する必要があります。

#!/bin/bash

readonly PRIMARY=/export/home/david/dist/primary
readonly SECONDARY=/export/home/david/dist/secondary
readonly FILERS_LOCATION=(machineB machineC)
readonly MAPPED_LOCATION=/bat/data/snapshot
PARTITION1=(0 3 5 7 9)
PARTITION2=(1 2 4 6 8)

dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)

length1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} "ls '$dir1' | wc -l")
length2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} "ls '$dir2' | wc -l")

if [ "$dir1" = "$dir2" ] && [ "$length1" -gt 0 ] && [ "$length2" -gt 0 ]
then
    rm -r $PRIMARY/*
    rm -r $SECONDARY/*
    for el in "${PARTITION1[@]}"
    do
        scp david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp david@${FILERS_LOCATION[1]}:$dir2/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/.
    done
    for sl in "${PARTITION2[@]}"
    do    
        scp david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$sl"_200003_5.data $SECONDARY/. || scp david@${FILERS_LOCATION[1]}:$dir2/t1_weekly_1680_"$sl"_200003_5.data $SECONDARY/.
    done
fi

現在、PARTITION1 と PARTITION2 に 5 つのファイルがありますが、一般的には約 420 個のファイルがあるため、ファイルを 1 つずつ移動することになり、かなり遅くなると思います。プロセスを高速化する方法はありますか?

私はUbuntu 12.04を使用しています

答え1

SCP を並列化するのは、両側が SSD 上で実行されていない限り、逆効果です。SCP の最も遅い部分はネットワークであり、その場合並列化はまったく役に立ちません。または、両側にディスクがある場合、並列化によって状況が悪化し、シーク時間が長くなります。

machineA は SSD 上にあるとのことなので、マシンごとに並列化すれば十分なはずです。これを行う最も簡単な方法は、最初の forloop をサブシェルでラップし、バックグラウンドで実行することです。

( for el in "${PARTITION1[@]}"
do
    scp david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp david@${FILERS_LOCATION[1]}:$dir2/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/.
done ) &

答え2

GNU Parallel を使用すると、複数のタスクを並列に実行できます。

ただし、あなたの状況では、ファイル転送ごとに個別の安全な接続を確立しているように見えますが、特に他のマシンがローカル ネットワーク上にない場合は、これは非常に非効率的である可能性があります。

最善のアプローチは、バッチ ファイル転送を専門に行うツール (たとえば、rsyncプレーンな ssh でも機能する ) を使用することです。

rsync が利用できない場合は、代わりに、zip、またはtarと、および結果のアーカイブgzipを使用できます(その後 に接続し、解凍します)。bzip2scpssh

答え3

すでに scp で問題が発生しており、ギガビット接続の同じネットワーク上にある 2 台のマシンが scp 経由で非常に低速で転送されていました。

暗号化が必要ない場合は、ftp または nfs を使用すると確かに少しは役立ちます。

問題は、マシンの 1 台の RAM が遅く、SSH 暗号化部分がこのマシンに非常に負荷をかけていることにあることがわかりました。ftp または nfs を使用することで問題は解決し、速度が 15 ~ 20 MB/秒から 100 MB/秒以上に向上しました。

[編集]

scp の代わりに優れた rsync を使用するこれを見つけました。問題全体が解決されるわけではありませんが、役に立つかもしれません。

https://gist.github.com/KartikTalwar/4393116

関連情報