web-dev-qa-db-ja.com

scpコマンドを並列化する方法は?

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

ファイルが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を実行しています

4
arsenal

両側がSSDで実行されない限り、SCPの並列化は逆効果です。 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 ) &
3

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

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

最善のアプローチは、特にrsyncなどのバッチファイル転送を実行するツールを使用することです。これは、プレーンなsshでも機能します。

Rsyncが利用できない場合は、代わりにZip、またはtargzipまたはbzip2を使用してから、scp結果のアーカイブ(次にsshで接続し、解凍する)。

3
cnst

私はすでにscpに問題がありました。scpを介して非常にゆっくりと転送していた、ギガビット接続の同じネットワーク上の2台のマシンです。

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

問題は、マシンの1つが遅いRAMであり、ssh暗号化部分がこのマシンに対して非常に要求が厳しいことであることがわかった。ftpまたはnfsを使用して問題を解決したので、15から20に進みました。 MB/sから100+ MBpsまで。

[編集]

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

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

0
Johnride