Zrównoleglanie rsync przy użyciu GNU Parallel

18

Używam rsyncskryptu do synchronizacji danych na jednym hoście z danymi na innym hoście. Dane zawierają wiele małych plików, które przyczyniają się do prawie 1,2 TB.

Aby zsynchronizować te pliki, użyłem rsyncpolecenia w następujący sposób:

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/

Zawartość proj.lst jest następująca:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *

Jako test wybrałem dwa z tych projektów (8,5 GB danych) i wykonałem powyższe polecenie. Jest to proces sekwencyjny, którego ukończenie zajmuje 14 minut 58 sekund. Tak więc dla 1,2 TB danych zajmie to kilka godzin.

Jeśli bym mógł wiele rsyncprocesów równolegle (z użyciem &, xargsalbo parallel), byłoby zaoszczędzić swój czas.

Próbowałem z poniższym poleceniem z parallel(po cdprzejściu do katalogu źródłowego) i wykonanie go zajęło 12 minut 37 sekund:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .

Powinno to zająć 5 razy mniej czasu, ale tak nie było. Myślę, że gdzieś się mylę.

Jak mogę uruchomić wiele rsyncprocesów, aby skrócić czas wykonywania?

Mandar Shinde
źródło
1
Czy jesteś ograniczony przepustowością sieci? Iops dysku? Przepustowość dysku?
Ole Tange
Jeśli to możliwe, chcielibyśmy wykorzystać 50% całkowitej przepustowości. Ale równoległość wielu rsyncs jest naszym priorytetem.
Mandar Shinde,
Czy możesz dać nam znać: przepustowość sieci, operacje na dysku, przepustowość dysku i przepustowość faktycznie wykorzystywaną?
Ole Tange
W rzeczywistości nie wiem o powyższych parametrach. Na razie możemy pominąć część dotyczącą optymalizacji. Wiele rsyncrównoległych jest teraz głównym celem.
Mandar Shinde,
Nie ma sensu iść równolegle, jeśli ograniczeniem nie jest procesor. Może / nawet pogorszy sprawę (konfliktowe ruchy ramion dysku na dysku źródłowym lub docelowym).
ksenoid

Odpowiedzi:

16

Wykonałem dla mnie następujące czynności:

  1. Uruchom rsync --dry-runpierwszy, aby uzyskać listę plików, których to dotyczy.
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
    --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
  1. Podałem wyjście cat transfer.logdo parallel, aby rsyncrównolegle uruchomić 5 s, jak następuje:
$ cat /tmp/transfer.log | \
    parallel --will-cite -j 5 rsync -avzm --relative \
      --stats --safe-links --ignore-existing \
      --human-readable {} REMOTE-HOST:/data/ > result.log

Tutaj --relativeopcja ( link ) zapewniła, że ​​struktura katalogów dla plików, których dotyczy problem, w źródle i miejscu docelowym, pozostaje taka sama (w /data/katalogu wewnętrznym ), więc polecenie należy uruchomić w folderze źródłowym (na przykład /data/projects).

Mandar Shinde
źródło
5
To zrobiłoby rsync na plik. Prawdopodobnie bardziej efektywne byłoby podzielenie całej listy plików przy użyciu spliti podawanie tych nazw plików równolegle. Następnie użyj rsync, --files-fromaby pobrać nazwy plików z każdego pliku i zsynchronizować je. rm backup. * split -l 3000 backup.list backup. kopie zapasowe ls. * | równoległy --line-buffer --verbose -j 5 rsync --progress -av --files-from {} / LOCAL / PARENT / PATH / REMOTE_HOST: REMOTE_PATH /
Sandip Bhattacharya
1
Jak drugie polecenie rsync obsługuje linie w pliku wynikowym.log, które nie są plikami? tj receiving file list ... done created directory /data/.
Mike D
1
W nowszych wersjach rsync (3.1.0+) możesz użyć --info=namezamiast nich -v, a otrzymasz tylko nazwy plików i katalogów. Możesz także użyć opcji --protect-args do 'wewnętrznego' transferu rsync, jeśli w plikach mogą znajdować się spacje lub metaznaki powłoki.
Gepard
13

Osobiście używam tego prostego:

ls -1 | parallel rsync -a {} /destination/directory/

Przydaje się to tylko wtedy, gdy masz więcej niż kilka prawie pustych katalogów, w przeciwnym razie skończy się prawie każde rsynczakończenie, a ostatni sam wykona całą robotę.

Julien Palard
źródło
Działa to świetnie - trudno wiedzieć, czy coś robi, więc od -v do równoległego sprawia, że ​​jest bardziej gadatliwy. Ponadto, -j 30 na równolegle (tj. Przed komendą rsync) powoduje, że uruchamia on 30 zadań, a nie tylko jedno na rdzeń procesora, który jest domyślny.
Criggie
12

Zdecydowanie odradzam każdemu korzystanie z zaakceptowanej odpowiedzi, lepszym rozwiązaniem jest przeszukanie katalogu najwyższego poziomu i uruchomienie proporcjonalnej liczby operacji rync.

Mam duży wolumin ZFS, a moim źródłem było CIFS Mount. Oba są powiązane z 10G, aw niektórych testach porównawczych mogą nasycić link. Wydajność oceniono za pomocą zpool iostat 1.

Napęd źródłowy został zamontowany w następujący sposób:

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0

Za pomocą jednego rsyncprocesu:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod

licznik io wskazuje:

StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.62K      0   130M

W syntetycznych testach porównawczych (dysk kryształowy) wydajność sekwencyjnego zapisu dochodzi do 900 MB / s, co oznacza, że ​​łącze jest nasycone. 130 MB / s nie jest zbyt dobra, a różnica między oczekiwaniem na weekend a dwoma tygodniami.

Zbudowałem więc listę plików i próbowałem ponownie uruchomić synchronizację (mam 64-rdzeniowy komputer):

cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log

i miał taką samą wydajność!

StoragePod  29.9T   144T      0  1.63K      0   130M
StoragePod  29.9T   144T      0  1.62K      0   130M
StoragePod  29.9T   144T      0  1.56K      0   129M

Alternatywnie po prostu uruchomiłem rsync w folderach głównych:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell

To faktycznie zwiększyło wydajność:

StoragePod  30.1T   144T     13  3.66K   112K   343M
StoragePod  30.1T   144T     24  5.11K   184K   469M
StoragePod  30.1T   144T     25  4.30K   196K   373M

Podsumowując, jak wychował @Sandip Bhattacharya, napisz mały skrypt, aby uzyskać katalogi i to równolegle. Alternatywnie, przekaż listę plików do rsync. Ale nie twórz nowych instancji dla każdego pliku.

Michaił
źródło
5

Testowanym sposobem wykonania zsynchronizowanego rsync jest: http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync

rsync jest doskonałym narzędziem, ale czasami nie zapełni dostępnej przepustowości. Jest to często problem podczas kopiowania kilku dużych plików przez szybkie połączenia.

Następujące uruchomienie rsync na duży plik w src-dir do dest-dir na serwerze fooserver:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{} 

Utworzone katalogi mogą mieć złe uprawnienia i mniejsze pliki nie będą przesyłane. Aby naprawić te uruchamianie rsync po raz ostatni:

rsync -Havessh src-dir/ fooserver:/dest-dir/ 

Jeśli nie możesz wypchnąć danych, ale musisz je pobrać, a pliki nazywa się digits.png (np. 000000.png), możesz zrobić:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/
Ole Tange
źródło
Jakaś inna alternatywa, aby tego uniknąć find?
Mandar Shinde,
1
Ogranicz -maxdepth znalezienia.
Ole Tange
Jeśli użyję --dry-runopcji in rsync, będę mieć listę plików, które zostaną przesłane. Czy mogę podać tę listę plików parallel, aby zrównoleglić proces?
Mandar Shinde,
1
pliki kota | równolegle -v ssh fooserver mkdir -p / dest-dir / {//} \; rsync -s -Havessh {} fooserver: / dest-dir / {}
Ole Tange
Czy możesz wyjaśnić tę mkdir -p /dest-dir/{//}\;część? Zwłaszcza {//}sprawa jest nieco myląca.
Mandar Shinde,
1

Używam do synchronizacji wielu miejsc docelowych

parallel rsync -avi /path/to/source ::: host1: host2: host3:

Wskazówka: wszystkie połączenia ssh są ustanawiane z kluczami publicznymi w ~/.ssh/authorized_keys

ingopingo
źródło
1

Zawsze szukam w Google równoległego rsync, ponieważ zawsze zapominam o pełnej komendzie, ale żadne rozwiązanie nie działało dla mnie tak, jak chciałem - albo zawiera wiele kroków, albo wymaga instalacji parallel. Skończyło się na tym, że zsynchronizowałem wiele folderów:

find dir/ -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo dir/%/ host:/dir/%/)'

-P 5 to ilość procesów, które chcesz odrodzić - użyj 0 dla nieograniczonej liczby (oczywiście nie jest to zalecane).

--bwlimit aby uniknąć korzystania z całej przepustowości.

-I % argument dostarczony przez find (katalog znaleziony w dir/ )

$(echo dir/%/ host:/dir/%/)- drukuje katalogi źródłowe i docelowe, które są odczytywane przez rsync jako argumenty. % zostaje zastąpione przez xargsnazwę katalogu znalezioną przezfind .

Załóżmy, że mam dwa katalogi w /home: dir1i dir2. Biegnę find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ host:/home/%/)'. Tak więc komenda rsync będzie działać jako dwa procesy (dwa procesy, ponieważ /homema dwa katalogi) z następującymi argumentami:

rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
Sebastjanas
źródło