Jaki jest najlepszy sposób na wykonanie równoległej kopii na Uniksie?

18

Rutynowo muszę skopiować zawartość folderu w sieciowym systemie plików na komputer lokalny. W folderze zdalnym znajduje się wiele plików (1000), które są względnie małe, ale ze względu na obciążenie sieci zwykłe kopiowanie cp remote_folder/* ~/local_folder/zajmuje bardzo dużo czasu (10 minut).

Uważam, że dzieje się tak, ponieważ pliki są kopiowane sekwencyjnie - każdy plik czeka na zakończenie poprzedniego, zanim rozpocznie się kopiowanie.

Jaki jest najprostszy sposób na zwiększenie prędkości tej kopii? (Zakładam, że należy wykonać kopię równolegle.)

Spakowanie plików przed kopiowaniem niekoniecznie przyspieszy, ponieważ wszystkie mogą być zapisane na różnych dyskach na różnych serwerach.

dsg
źródło
Spakowanie plików przed kopiowaniem znacznie przyspieszy, ponieważ nie będzie już potrzeby „czy dostałeś ten plik”, „tak, zrobiłem”, „oto następny”, „ok”,… To są te „zwroty”, które spowalniają cię.
David Schwartz
Prawdopodobnie jest to prędkość dysku, a nie prędkość sieci, co jest twoim czynnikiem ograniczającym, a jeśli tak, to robienie tego równolegle dla pliku spowoduje, że operacja będzie wolniejsza , a nie szybsza, ponieważ zmusisz dysk do ciągłego wyszukiwania do przodu i do tyłu między plikami.
Joel Coehoorn,
Chociaż kompresowanie może nie być dobrym pomysłem (uruchomienie kompresji ponad 1000 plików może trochę potrwać), tar może być opłacalny.
Rob
@JoelCoehoorn wciąż istnieją przypadki, gdy tak nie jest: np. Wiele wrzecion + małe pliki (lub po prostu losowe odczyty). W tym scenariuszu pomocne byłoby „równoległe cp”.
CAFxX
serverfault.com/questions/152331/parallel-file-copy
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Odpowiedzi:

8

Dopóki ograniczysz uruchamiane polecenia kopiowania, prawdopodobnie możesz użyć skryptu takiego jak ten opublikowany przez Scrutinizer

SOURCEDIR="$1"
TARGETDIR="$2"
MAX_PARALLEL=4
nroffiles=$(ls "$SOURCEDIR" | wc -w)
setsize=$(( nroffiles/MAX_PARALLEL + 1 ))
ls -1 "$SOURCEDIR"/* | xargs -n "$setsize" | while read workset; do
  cp -p "$workset" "$TARGETDIR" &
done
wait
OldWolf
źródło
1
Uwaga dotycząca ostrzeżenia: ten skrypt łamie nazwy plików zawierające spacje lub znaki globowania.
slhck
@OldWolf - Czy możesz wyjaśnić, jak działa ten skrypt? Na przykład, która część wykonuje równoległość?
dsg
3
@dsg: Na &końcu cppolecenia pozwala na whilekontynuowanie pętli i uruchomienie następnego polecenia cp bez czekania. xargsPolecenie przekazuje pliki w grupach 4 (MAX_PARALLEL) do whilepętli.
RedGrittyBrick
Nie działa dla mnie. Nie jestem pewien, czy można przyspieszyć cp. Oczywiście możesz przyspieszyć obliczenia poprzez wielowątkowość. Ale nie sądzę, że to samo dotyczy kopiowania danych na dysku twardym.
Adobe
9

Jeśli masz zainstalowany GNU Parallel http://www.gnu.org/software/parallel/, możesz to zrobić:

parallel -j10 cp {} destdir/ ::: *

Możesz zainstalować GNU Parallel po prostu przez:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh

Obejrzyj filmy wprowadzające do GNU Parallel, aby dowiedzieć się więcej: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Ole Tange
źródło
3

Jednym ze sposobów byłoby użycie rsync, który skopiuje tylko zmiany - nowe pliki i zmienione części innych plików.

http://linux.die.net/man/1/rsync

Uruchomienie dowolnej formy równoległej operacji kopiowania prawdopodobnie spowoduje zalanie sieci, a operacja kopiowania po prostu zatrzyma się lub wystąpią wąskie gardła na dysku źródłowym lub docelowym.

Linker3000
źródło
2

Szczerze mówiąc, najlepszym narzędziem jest gsutil Google. Obsługuje kopie równoległe z rekurencją katalogu. Większość innych metod, które widziałem, nie obsługuje rekursji katalogów. W swoich dokumentach nie wspominają o lokalnym systemie plików o kopiach lokalnego systemu plików, ale działa to jak urok.

Jest to kolejny plik binarny do zainstalowania, ale prawdopodobnie taki, który mógłbyś już uruchomić, biorąc pod uwagę wszystkie obecnie przyjęte usługi chmurowe.

diq
źródło
2

Równoległe rsync przy użyciu find:

export SOURCE_DIR=/a/path/to/nowhere
export DEST_DIR=/another/path/to/nowhere

# sync folder structure first
rsync -a -f'+ */' -f'- *' $SOURCE_DIR $DEST_DIR

# cwd
cd $SOURCE_DIR

# use find to help filter files etc. into list and pipe into gnu parallel to run 4 rsync jobs simultaneously
find . -type f | SHELL=/bin/sh parallel --linebuffer --jobs=4 'rsync -av {} $DEST_DIR/{//}/'

w korporacyjnej sieci LAN pojedynczy rsync wykonuje około 800 Mb / s; przy 6-8 zadaniach jestem w stanie uzyskać ponad 2,5 Gb / s (kosztem dużego obciążenia). Ograniczone przez dyski.

yee379
źródło
0

Jest wiele rzeczy, które należy rozważyć w zależności od posiadanej topologii. Ale zanim zaczniesz myśleć o złożonych rozwiązaniach, możesz po prostu spróbować podzielić zadanie na dwa zadania i sprawdzić, czy potrzebny czas znacznie się skróci:

Następnym razem spróbuj:

  cp remote_folder/[a-l]* ~/local_folder/ &
  cp remote_folder/[!a-l]* ~/local_folder/ &
  wait
  wait

(możesz zamienić [al] * na coś, co pasuje do około połowy plików - może [0-4] * - w zależności od zawartości folderu)

Jeśli czas nie poprawi się radykalnie, ważniejsze może być sprawdzenie, czy konieczne jest skopiowanie wszystkich plików (jaki jest stosunek zmienionych plików do wszystkich plików?)

ktf
źródło