rsync do wielu miejsc docelowych przy użyciu tej samej listy plików?

22

Zastanawiam się, czy rsync może skopiować jeden katalog do wielu zdalnych miejsc docelowych jednocześnie, a nawet równolegle. (nie jest to konieczne, ale byłoby przydatne).

Zwykle coś takiego działałoby dobrze:

$ rsync -Pav /junk user@host1:/backup
$ rsync -Pav /junk user@host2:/backup
$ rsync -Pav /junk user@host3:/backup

A jeśli to jedyna opcja, skorzystam z niej. Jednak / junk znajduje się na wolnym dysku z dużą liczbą plików, a przebudowywanie listy plików zawierającej około 12 000 plików za każdym razem jest agresywnie powolne (~ 5 minut) w porównaniu do faktycznego transferu / aktualizacji. Czy można zrobić coś takiego, aby osiągnąć to samo:

$ rsync -Pav /junk user@host1:/backup user@host2:/backup user@host3:/backup 

Dzięki za opiekę!

Jessie
źródło

Odpowiedzi:

12

Oto informacje ze strony podręcznika rsync dotyczące trybu wsadowego.

TRYB WSADOWY

Trybu wsadowego można użyć do zastosowania tego samego zestawu aktualizacji do wielu identycznych systemów. Załóżmy, że jeden ma drzewo, które jest replikowane na wielu hostach. Załóżmy teraz, że dokonano pewnych zmian w tym drzewie źródłowym i zmiany te należy propagować na innych hostach. Aby to zrobić w trybie wsadowym, rsync jest uruchamiany z opcją zapisu-wsadowania, aby zastosować zmiany dokonane w drzewie źródłowym do jednego z drzew docelowych. Opcja zapisu-partii powoduje, że klient rsync przechowuje w „pliku wsadowym” wszystkie informacje potrzebne do powtórzenia tej operacji względem innych, identycznych drzew docelowych.

Generowanie pliku wsadowego raz pozwala zaoszczędzić konieczności wykonywania statusu pliku, sumy kontrolnej i generowania bloku danych więcej niż raz podczas aktualizacji wielu drzew docelowych. Protokoły transportu multiemisji mogą służyć do równoległego przesyłania plików aktualizacji wsadowej do wielu hostów, zamiast wysyłania tych samych danych do każdego hosta z osobna.

Aby zastosować zarejestrowane zmiany do innego drzewa docelowego, uruchom rsync z opcją read-batch, określając nazwę tego samego pliku wsadowego i drzewo docelowe. Rsync aktualizuje drzewo docelowe za pomocą informacji zapisanych w pliku wsadowym.

Dla wygody tworzony jest również plik skryptu, gdy używana jest opcja zapisu wsadowego: zostanie nazwany tak samo jak plik wsadowy z dołączonym „.sh”. Ten plik skryptu zawiera wiersz polecenia odpowiedni do aktualizacji drzewa docelowego przy użyciu skojarzonego pliku wsadowego. Można go wykonać za pomocą powłoki Bourne'a (lub podobnej do Bourne'a), opcjonalnie przekazując alternatywną nazwę ścieżki drzewa docelowego, która jest następnie używana zamiast oryginalnej ścieżki docelowej. Jest to przydatne, gdy ścieżka drzewa docelowego na bieżącym hoście różni się od ścieżki użytej do utworzenia pliku wsadowego.

   Examples:

          $ rsync --write-batch=foo -a host:/source/dir/ /adest/dir/
          $ scp foo* remote:
          $ ssh remote ./foo.sh /bdest/dir/

          $ rsync --write-batch=foo -a /source/dir/ /adest/dir/
          $ ssh remote rsync --read-batch=- -a /bdest/dir/ <foo

W tych przykładach rsync jest używany do aktualizacji / adest / dir / from / source / dir /, a informacje o powtórzeniu tej operacji są przechowywane w „foo” i „foo.sh”. Host „zdalny” jest następnie aktualizowany partiami danych przechodzącymi do katalogu / bdest / dir. Różnice między tymi dwoma przykładami pokazują pewną elastyczność, jaką masz w sposobie radzenia sobie z partiami:

  • Pierwszy przykład pokazuje, że początkowa kopia nie musi być lokalna - możesz wypychać lub pobierać dane do / ze zdalnego hosta za pomocą składni powłoki zdalnej lub składni demona rsync, zależnie od potrzeb.

  • Pierwszy przykład wykorzystuje utworzony plik „foo.sh”, aby uzyskać odpowiednie opcje rsync podczas uruchamiania komendy read-batch na zdalnym hoście.

  • Drugi przykład odczytuje dane wsadowe za pomocą standardowego wejścia, dzięki czemu plik wsadowy nie musi być najpierw kopiowany na komputer zdalny. W tym przykładzie unika się skryptu foo.sh, ponieważ musiał on użyć zmodyfikowanej opcji --read-batch, ale można edytować plik skryptu, jeśli chcesz go użyć (po prostu upewnij się, że żadna inna opcja nie próbuje użyć standardowego dane wejściowe, takie jak opcja „--exclude-from = -”).

    Ostrzeżenia:

    Opcja odczytu-partii oczekuje, że drzewo docelowe, które aktualizuje, będzie identyczne z drzewem docelowym, które zostało użyte do utworzenia zestawu plików aktualizacji wsadowej. W przypadku napotkania różnicy między drzewami docelowymi aktualizacja może zostać odrzucona z ostrzeżeniem (jeśli wydaje się, że plik jest już aktualny) lub może zostać podjęta próba aktualizacji pliku, a następnie, jeśli plik nie zostanie zweryfikowany aktualizacja została odrzucona z błędem. Oznacza to, że należy ponownie uruchomić operację odczytu i odczytu, jeśli polecenie zostało przerwane. Jeśli chcesz wymusić, aby zawsze wykonywano aktualizację pakietową, niezależnie od rozmiaru i daty pliku, użyj opcji -I (podczas odczytywania partii). Jeśli wystąpi błąd, drzewo docelowe prawdopodobnie będzie w stanie częściowo zaktualizowanym. W tym wypadku,

    Wersja rsync używana we wszystkich miejscach docelowych musi być co najmniej tak nowa, jak wersja użyta do wygenerowania pliku wsadowego. Rsync umrze z błędem, jeśli wersja protokołu w pliku wsadowym jest zbyt nowa, aby obsłużyć rsync do odczytu wsadowego. Zobacz także opcję --protocol, aby dowiedzieć się, jak utworzyć rsync podczas tworzenia pliku wsadowego, który może zrozumieć starszy rsync. (Należy pamiętać, że pliki wsadowe zmieniły się formalnie w wersji 2.6.3, więc mieszanie starszych wersji z nowszymi wersjami nie będzie działać).

    Podczas odczytywania pliku wsadowego rsync wymusi na wartości niektórych opcji dopasowanie danych w pliku wsadowym, jeśli nie ustawiono ich na takie same jak polecenie zapisu wsadowego. Inne opcje można (i należy) zmienić. Na przykład --write-batch zmienia się na --read-batch, --files-from jest usuwany, a opcje --filter / - include / - exclude nie są potrzebne, chyba że określono jedną z opcji --delete .

    Kod tworzący plik BATCH.sh przekształca wszelkie opcje filtru / włączania / wykluczania w pojedynczą listę, która jest dołączana jako dokument „tutaj” do pliku skryptu powłoki. Zaawansowany użytkownik może użyć tego do zmodyfikowania listy wykluczeń, jeśli pożądana jest zmiana w tym, co zostanie usunięte przez --delete. Normalny użytkownik może zignorować ten szczegół i po prostu użyć skryptu powłoki jako łatwego sposobu uruchomienia odpowiedniej komendy --read-batch dla partii danych.

    Oryginalny tryb wsadowy w rsync był oparty na „rsync +”, ale najnowsza wersja używa nowej implementacji.

Wyobrażam sobie, że możesz spróbować

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup
Chloe
źródło
Sugerowane polecenie nie działa:remote destination is not allowed with --read-batch
kynan
Pokaż pełne polecenie. -nazwa pliku oznacza odczyt ze standardowego wejścia, a STDIN jest również odczytywany foow przykładzie z pliku lokalnego.
Chloe
2
To wydaje się być maksymalnie poprawnym rozwiązaniem tego, co próbowałem zrobić, chociaż mój przypadek użycia już dawno wyparował w eterze. : D
Jessie
4

Możesz spróbować użyć unisona . Tworzenie listy plików powinno być znacznie szybsze, ponieważ utrzymuje pamięć podręczną plików.

Jason Axelson
źródło
2
Uwaga: Unison nie przechowuje „pamięci podręcznej” plików. Przechowuje tylko bazę danych nazw plików, znaczników czasu, sum kontrolnych. Nadal skanuje system plików i tworzy sumę kontrolną do porównania ze zdalnym. Jedyną zaletą Unison jest synchronizacja dwukierunkowa. Polecam Unison, ale tutaj to nie pomoże.
Chloe
4

Te rsync --batch-modepodpory multicast. Jeśli jest to możliwe w twojej sieci, warto się temu przyjrzeć.

kodekrank
źródło
2

co powiesz na zmianę systemów plików?

Jakiś czas temu zmieniłem wielotabajtowy FS z ext3 na XFS. Czas skanowania katalogów (przy ostatnim sprawdzeniu około 600 000 plików) skrócił się z 15-17 minut do mniej niż 30 sekund!

Javier
źródło
1

Nie jest to bezpośrednia odpowiedź, ale jeśli używasz rsync w wersji 3+, zacznie się przesyłać, zanim wygeneruje całą listę plików.

Inną opcją, wciąż niezbyt wydajną, byłoby uruchamianie ich jako zadań, więc kilka z nich działa jednocześnie.

Pomyślałem też o tej dziwności, jeśli nie masz nic przeciwko użyciu tar:

tar cf - . | tee >(ssh localhost 'cat > test1.tar') >(ssh localhost 'cat > test2.tar') >/dev/null

Gdzie każdy lokalny host byłby oczywiście innym serwerem (zakłada logowanie na podstawie klucza). Nigdy wcześniej nie korzystałem z powyższego.

Kyle Brandt
źródło
Hmm! O dziwo, cwrsync (rsync 3.0.7) wydaje się tego nie robić. Muszę jednak zastanowić się, dlaczego tak jest, ponieważ byłoby to bardzo pomocne w ograniczeniu tych ogromnych czasów wykonywania. Dzięki!
Jessie
Ta wersja po obu stronach?
Kyle Brandt
Nie, właściwie; maszyną lokalną jest cwrsync 3.0.7, a host zdalny (cóż, ten z którym teraz pracuję) to rsync 3.0.3 na Debianie Lennym. Wydaje się, że nie byłaby to zbyt duża różnica wersji, aby mogła się źle zachowywać, ale nie wiem ... Zajmę się aktualizacją strony Debiana.
Jessie
1
Co za dziwny mały liniowiec. Prawdopodobnie by to zadziałało, gdybym nie wykorzystał faktu, że rsync nie musi ponownie duplikować kilku gigabajtów danych na kilku wolnych linkach, kiedy zmieniło się co najwyżej kilkaset kb. Ponadto uzyskanie obu końców do (cw) rsync 3.0.7 nadal powodowało kompilację i przesyłanie list plików. Jednak nie przejmowałem się tym zbytnio.
Jessie
To nie jest „tar cf -.” to samo co „tar c.” ?
Johan Boulé,
1

Co powiesz na uruchamianie zadań rsync z hosta 1, hosta 2 i hosta 3? Lub uruchom zadanie, aby skopiować na host1, a następnie uruchom je na host2 i host3, aby pobrać je z hosta 1.

mfinni
źródło
1

Lepszym rozwiązaniem byłoby utworzenie repozytorium za pomocą git i po prostu wypychanie do 3 hostów. Szybciej, nie potrzebujesz części listy plików i zużywa ona mniej zasobów.

Powodzenia,
João Miguel Neves

jneves
źródło
10
git nie zachowuje czasów modyfikacji ani uprawnień (z wyjątkiem bitu wykonania) i wymagałby przechowywania drugiej kopii danych jako obiektów git, .git/chociaż wypychanie do pilotów, które już miałyby większość danych, byłoby szybsze. git nie zastępuje rsync.
Dan D.
Ponadto git jest publicznie dostępny, chyba że zapłacisz.
Chloe
8
@Chloe, mylisz Git z GitHub. Sam git jest wolny open source rozproszonym systemem sterowania wersja, a każdy może zorganizować git repozytorium dowolnym sposobem, w tym http, nfsa afp. GitHub to strona internetowa, która zajmuje się tworzeniem i utrzymywaniem repozytoriów git dla Ciebie i upublicznia je (chyba że płacisz).
toriningen
1
@Chloe GitHub jest publicznie dostępny, ale BitBucket zapewnia prywatne repo.
sws
2
Ponadto Git nie śledzi pustych katalogów.
Flimm
1

Szukając tej odpowiedzi sam, myślę, że musisz najpierw utworzyć partię przy użyciu rsync, a następnie wysłać ją do nich wszystkich, co sprawi, że lista plików będzie musiała zostać skrócona tylko raz, a następnie możesz po prostu w tle wszystkie trzy rsyncs, aby uruchomić je równolegle.

Morgan
źródło
1

Innym możliwym rozwiązaniem jest po prostu równoległe uruchamianie tylu procesów rsync, co hostów, tj. Fork.

Alexey Tigarev
źródło