Мне нужно scp файлы из machineB
и machineC
в machineA
. Я запускаю свой скрипт оболочки ниже из 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
В настоящее время у меня есть 5 файлов в PARTITION1 и PARTITION2, но в целом там будет около 420 файлов, так что это означает, что он будет перемещать файлы по одному, что, я думаю, может быть довольно медленно. Есть ли способ ускорить процесс?
Я использую 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
или bzip2
, а затем scp
полученные архивы (затем подключиться с помощью ssh
и выполнить распаковку).
решение3
У меня уже была проблема с SCP: две машины в одной сети с гигабитным соединением передавали данные по SCP очень медленно.
Если вам НЕ нужно шифрование, то наверняка немного поможет использование ftp или nfs.
Я выяснил, что проблема была в том, что у одной из машин была медленная оперативная память, а шифрование ssh было очень требовательным для этой машины. Использование ftp или nfs решило мою проблему, я поднял скорость с 15-20 МБ/с до 100+ МБ/с.
[РЕДАКТИРОВАТЬ]
Я только что нашел это, которое использует отличный rsync вместо scp. Это не решит всю вашу проблему, но может помочь.