如何并行化 scp 命令?

如何并行化 scp 命令?

我需要将文件从 scp到machineB。我正在从 运行以下 shell 脚本。我已正确设置了 ssh 密钥。machineCmachineAmachineA

如果文件不在 中machineB,那么它应该在 中machineC。我需要将所有 PARTITION1 和 PARTITION2 文件移动到 machineA 相应的文件夹中,如下面我的 shell 脚本所示 -

#!/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 个文件,这意味着它会逐个移动文件,我认为这可能会很慢。有什么方法可以加快这个过程吗?

我正在运行 Ubuntu 12.04

答案1

除非两边都在 SSD 上运行,否则并行化 SCP 会适得其反。SCP 最慢的部分是网络,在这种情况下并行化根本无济于事,或者两边的磁盘,并行化只会让情况变得更糟:寻道时间会耗尽你的时间。

您说 machineA 位于 SSD 上,因此每台机器并行化应该足够了。最简单的方法是将第一个 forloop 包装在子 shell 中并将其置于后台。

( 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,甚至targzipbzip2,然后使用scp生成的档案(然后连接ssh,并进行解压)。

答案3

我在使用 scp 时已经遇到过一个问题,同一网络上的两台机器采用千兆连接,通过 scp 传输的速度非常慢。

如果您不需要加密,使用 ftp 或 nfs 肯定会有所帮助。

我发现问题在于其中一台机器的 RAM 很慢,而 ssh 加密部分对这台机器的要求很高。使用 ftp 或 nfs 解决了我的问题,我的速度从 15-20 MB/s 提高到了 100+ MBps。

[编辑]

我刚刚发现这个使用 rsync 而不是 scp 的程序。虽然不能解决你的全部问题,但可以提供帮助。

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

相关内容