rsincronizzare più destinazioni utilizzando lo stesso elenco file?


22

Mi chiedo se è possibile per rsync copiare una directory su più destinazioni remote in una volta sola, o anche in parallelo. (non necessario, ma sarebbe utile.)

Normalmente, qualcosa di simile al seguente funzionerebbe perfettamente:

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

E se questa è l'unica opzione, la userò. Tuttavia, / junk si trova su un disco lento con parecchi file e ricostruire l'elenco dei file di circa 12.000 file ogni volta è incredibilmente lento (~ 5 minuti) rispetto al trasferimento / aggiornamento effettivo. È possibile fare qualcosa del genere, per ottenere la stessa cosa:

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

Grazie per aver guardato!

Risposte:


12

Ecco le informazioni dalla pagina man per rsync sulla modalità batch.

MODALITÀ BATCH

La modalità batch può essere utilizzata per applicare lo stesso set di aggiornamenti a molti sistemi identici. Supponiamo che uno abbia un albero che viene replicato su un numero di host. Supponiamo ora che siano state apportate alcune modifiche all'albero dei sorgenti e che tali modifiche debbano essere propagate agli altri host. Per fare ciò utilizzando la modalità batch, rsync viene eseguito con l'opzione write-batch per applicare le modifiche apportate all'albero di origine a uno degli alberi di destinazione. L'opzione write-batch fa sì che il client rsync memorizzi in un "file batch" tutte le informazioni necessarie per ripetere questa operazione su altri alberi di destinazione identici.

La generazione del file batch una volta evita di dover eseguire più volte lo stato del file, il checksum e la generazione del blocco dati durante l'aggiornamento di più alberi di destinazione. I protocolli di trasporto multicast possono essere utilizzati per trasferire contemporaneamente i file di aggiornamento batch in parallelo a più host, anziché inviare gli stessi dati a ciascun host singolarmente.

Per applicare le modifiche registrate a un altro albero di destinazione, eseguire rsync con l'opzione read-batch, specificando il nome dello stesso file batch e l'albero di destinazione. Rsync aggiorna l'albero di destinazione utilizzando le informazioni memorizzate nel file batch.

Per comodità, viene anche creato un file di script quando viene utilizzata l'opzione di scrittura in batch: verrà chiamato come il file batch con ".sh" aggiunto. Questo file di script contiene una riga di comando adatta per l'aggiornamento di un albero di destinazione utilizzando il file batch associato. Può essere eseguito usando una shell Bourne (o Bourne-like), opzionalmente passando un nome di percorso dell'albero di destinazione alternativo che viene quindi utilizzato al posto del percorso di destinazione originale. Ciò è utile quando il percorso dell'albero di destinazione sull'host corrente differisce da quello utilizzato per creare il file batch.

   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

In questi esempi, rsync viene utilizzato per aggiornare / adest / dir / da / source / dir / e le informazioni per ripetere questa operazione vengono archiviate in "pippo" e "pippo.sh". L'host "remoto" viene quindi aggiornato con i dati in batch che vanno nella directory / bdest / dir. Le differenze tra i due esempi rivelano una parte della flessibilità che hai nel modo di gestire i batch:

  • Il primo esempio mostra che la copia iniziale non deve essere locale: è possibile inviare o estrarre dati da / verso un host remoto utilizzando la sintassi della shell remota o la sintassi del demone rsync, come desiderato.

  • Il primo esempio usa il file "foo.sh" creato per ottenere le giuste opzioni rsync quando si esegue il comando read-batch sull'host remoto.

  • Il secondo esempio legge i dati batch tramite input standard in modo che il file batch non debba essere prima copiato sulla macchina remota. In questo esempio si evita lo script foo.sh perché era necessario utilizzare un'opzione --read-batch modificata, ma è possibile modificare il file di script se si desidera utilizzarlo (assicurarsi che nessun'altra opzione stia tentando di utilizzare lo standard input, come l'opzione "--exclude-from = -").

    Avvertenze:

    L'opzione read-batch prevede che l'albero di destinazione che sta aggiornando sia identico all'albero di destinazione utilizzato per creare il set di file di aggiornamento batch. Quando viene rilevata una differenza tra gli alberi di destinazione, l'aggiornamento potrebbe essere scartato con un avviso (se il file sembra essere già aggiornato) o potrebbe essere tentato l'aggiornamento del file e quindi, se il file non riesce a verificare , l'aggiornamento è stato eliminato con un errore. Ciò significa che dovrebbe essere sicuro rieseguire un'operazione di lettura batch se il comando viene interrotto. Se si desidera forzare sempre l'aggiornamento in batch, indipendentemente dalle dimensioni e dalla data del file, utilizzare l'opzione -I (durante la lettura del batch). Se si verifica un errore, l'albero di destinazione sarà probabilmente in uno stato parzialmente aggiornato. In quel caso,

    La versione rsync utilizzata su tutte le destinazioni deve essere almeno nuova come quella utilizzata per generare il file batch. Rsync morirà con un errore se la versione del protocollo nel file batch è troppo nuova per essere gestita da rsync con lettura batch. Vedi anche l'opzione --protocol per un modo per far sì che la creazione di rsync generi un file batch che un vecchio rsync possa capire. (Si noti che i file batch sono stati modificati nella versione 2.6.3, pertanto il missaggio di versioni precedenti a quelle più recenti non funzionerà.)

    Durante la lettura di un file batch, rsync forzerà il valore di alcune opzioni in modo che corrispondano ai dati nel file batch se non sono stati impostati sullo stesso comando di scrittura batch. Altre opzioni possono (e dovrebbero) essere modificate. Ad esempio --write-batch cambia in --read-batch, --files-from viene eliminato e le opzioni --filter / - include / - exclude non sono necessarie a meno che non sia specificata una delle opzioni --delete .

    Il codice che crea il file BATCH.sh trasforma le opzioni di filtro / include / exclude in un unico elenco che viene aggiunto come documento "qui" al file di script della shell. Un utente esperto può utilizzarlo per modificare l'elenco di esclusione se si desidera modificare ciò che viene eliminato da --delete. Un utente normale può ignorare questo dettaglio e usare semplicemente lo script della shell come un modo semplice per eseguire il comando --read-batch appropriato per i dati in batch.

    La modalità batch originale in rsync era basata su "rsync +", ma l'ultima versione utilizza una nuova implementazione.

Immagino che tu possa provare

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup

Il comando suggerito non funziona:remote destination is not allowed with --read-batch
kynan

Mostra il comando completo. -per un nome file significa leggere dallo standard input, e anche foonell'esempio STDIN viene letto da un file locale.
Chloe,

2
Questa sembra essere la soluzione massimamente corretta per quello che stavo cercando di fare, sebbene il mio caso d'uso per questo sia da tempo evaporato nell'etere. : D
Jessie,

4

Potresti provare a usare l' unisono . Dovrebbe essere molto più veloce nella creazione dell'elenco dei file perché mantiene una cache dei file.


2
Nota: Unison non mantiene una 'cache' dei file. Mantiene solo un database di nomi di file, timestamp, checksum. Esegue ancora una scansione del file system e crea un checksum da confrontare con il telecomando. L'unico vantaggio di Unison è la sincronizzazione bidirezionale. Raccomando Unison, ma non aiuta qui.
Chloe,

4

Il rsync --batch-modesupporto multicast. Se questo è possibile sulla tua rete, potrebbe valere la pena esaminarlo.


2

che ne dici di cambiare filesystem?

Qualche tempo fa, ho cambiato un FS multi-terabyte da ext3 a XFS. Il tempo per scansionare le directory (con circa 600.000 file l'ultima volta che ho controllato) è passato da 15-17 minuti a meno di 30 secondi!


1

Non è una risposta diretta, ma se si utilizza rsync versione 3+ inizierà il trasferimento prima di generare l'intero elenco file.

Un'altra opzione, ancora non molto efficiente, sarebbe quella di eseguirli come lavori in modo che alcuni funzionino contemporaneamente.

Inoltre, ho pensato a questa stranezza se non ti dispiace usare tar:

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

Ovviamente, ogni localhost si troverebbe su server diversi (presuppone l'accesso basato su chiave). Tuttavia, non ho mai usato quanto sopra.


Hmm! Stranamente, cwrsync (rsync 3.0.7) sembra non farlo. Dovrò capire perché, comunque, sarebbe di grande aiuto nel ridurre questi enormi tempi di autonomia. Grazie!
Jessie,

Quella versione su entrambi i lati?
Kyle Brandt,

No, in realtà; la macchina locale è cwrsync 3.0.7 e l'host remoto (beh, quello con cui sto lavorando ora) è rsync 3.0.3 su Debian Lenny. Non sembra che ci sia una differenza di versione troppo grande per comportarsi in modo errato, ma non lo so .. Cercherò di aggiornare il lato Debian.
Jessie,

1
Che strana piccola fodera. Probabilmente avrebbe funzionato, tuttavia, se non avessi sfruttato il fatto che rsync non avesse bisogno di duplicare alcuni concerti di dati su diversi collegamenti lenti quando, al massimo, solo poche centinaia di KB sono cambiati. Inoltre, ottenere entrambe le estremità in (cw) rsync 3.0.7 ha comunque completato la costruzione dell'elenco file e il trasferimento in serie. Non troppo preoccupato, però.
Jessie,

Non è "tar cf -." lo stesso di "tar c." ?
Johan Boulé,

1

Che ne dici di eseguire i lavori rsync da host1, host2 e host3? In alternativa, eseguire un lavoro da copiare su host1, quindi eseguirlo su host2 e host3 per ottenerlo da host1.


1

Una soluzione migliore sarebbe quella di creare un repository con git e semplicemente spingendo verso i 3 host. Più veloce, non avresti bisogno della parte dell'elenco dei file e consuma meno risorse.

Buona fortuna,
João Miguel Neves


10
git non conserva i tempi di modifica né i permessi (ad eccezione del bit di esecuzione) e richiederebbe l'archiviazione di una seconda copia dei dati come oggetti git, .git/sebbene i push verso i telecomandi che avrebbero già la maggior parte dei dati sarebbero più veloci. git non è un sostituto di rsync.
Dan D.

Inoltre, git è pubblicamente visualizzabile, a meno che tu non paghi.
Chloe,

8
@Chloe, sbagli git per GitHub. Git stesso è sistema distribuito di controllo di versione libera opensource, e chiunque può ospitare repository git con qualsiasi mezzo, inclusi http, nfse afp. GitHub è un sito Web che si occupa di creare e mantenere repository git per te e li rende pubblici (a meno che tu non paghi).
Toriningen,

1
@Chloe GitHub è visualizzabile pubblicamente, ma BitBucket fornisce repository privati.
sw

2
Inoltre, Git non tiene traccia delle directory vuote.
Flimm,

1

Nel cercare questa risposta da solo, penso che dovresti creare prima un batch usando prima rsync e poi inviandolo a tutti, il che lo farebbe in modo che l'elenco dei file debba essere scricchiolato solo una volta, e quindi potresti semplicemente sfondo tutti e tre i rsync per eseguirli in parallelo.


1

Un'altra possibile soluzione sta eseguendo in parallelo tutti i processi rsync quanti sono gli host, ovvero fork.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.