rsync vers plusieurs destinations en utilisant la même liste de fichiers?

22

Je me demande s'il est possible pour rsync de copier un répertoire vers plusieurs destinations distantes en une seule fois, ou même en parallèle. (pas nécessaire, mais serait utile.)

Normalement, quelque chose comme ce qui suit fonctionnerait très bien:

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

Et si c'est la seule option, je vais l'utiliser. Cependant, / junk est situé sur un lecteur lent avec pas mal de fichiers, et la reconstruction de la liste de fichiers d'environ ~ 12 000 fichiers à chaque fois est extrêmement lente (~ 5 minutes) par rapport au transfert / mise à jour réel. Est-il possible de faire quelque chose comme ça, d'accomplir la même chose:

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

Merci d'avoir regardé!

Jessie
la source

Réponses:

12

Voici les informations de la page de manuel de rsync sur le mode batch.

TEMPS DIFFÉRÉ

Le mode batch peut être utilisé pour appliquer le même ensemble de mises à jour à de nombreux systèmes identiques. Supposons que l'on ait une arborescence qui est répliquée sur un certain nombre d'hôtes. Supposons maintenant que certaines modifications ont été apportées à cet arbre source et que ces modifications doivent être propagées aux autres hôtes. Pour ce faire en utilisant le mode batch, rsync est exécuté avec l'option write-batch pour appliquer les modifications apportées à l'arborescence source à l'une des arborescences de destination. L'option write-batch oblige le client rsync à stocker dans un "fichier de commandes" toutes les informations nécessaires pour répéter cette opération sur d'autres arborescences de destination identiques.

La génération du fichier de commandes une fois évite d'avoir à exécuter l'état du fichier, la somme de contrôle et la génération de blocs de données plusieurs fois lors de la mise à jour de plusieurs arborescences de destination. Les protocoles de transport multidiffusion peuvent être utilisés pour transférer les fichiers de mise à jour par lots en parallèle vers de nombreux hôtes à la fois, au lieu d'envoyer les mêmes données à chaque hôte individuellement.

Pour appliquer les modifications enregistrées à une autre arborescence de destination, exécutez rsync avec l'option read-batch, en spécifiant le nom du même fichier de commandes et l'arborescence de destination. Rsync met à jour l'arborescence de destination à l'aide des informations stockées dans le fichier de commandes.

Pour votre commodité, un fichier de script est également créé lorsque l'option write-batch est utilisée: il sera nommé de la même manière que le fichier batch avec ".sh" ajouté. Ce fichier de script contient une ligne de commande adaptée à la mise à jour d'une arborescence de destination à l'aide du fichier de commandes associé. Il peut être exécuté à l'aide d'un shell Bourne (ou de type Bourne), en passant éventuellement un autre chemin d'accès d'arbre de destination qui est ensuite utilisé à la place du chemin de destination d'origine. Cela est utile lorsque le chemin de l'arborescence de destination sur l'hôte actuel diffère de celui utilisé pour créer le fichier de commandes.

   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

Dans ces exemples, rsync est utilisé pour mettre à jour / adest / dir / à partir de / source / dir / et les informations pour répéter cette opération sont stockées dans "foo" et "foo.sh". L'hôte "distant" est alors mis à jour avec les données du lot entrant dans le répertoire / bdest / dir. Les différences entre les deux exemples révèlent une partie de la flexibilité dont vous disposez dans la façon dont vous traitez les lots:

  • Le premier exemple montre que la copie initiale n'a pas besoin d'être locale - vous pouvez pousser ou extraire des données vers / depuis un hôte distant en utilisant la syntaxe du shell distant ou la syntaxe du démon rsync, comme vous le souhaitez.

  • Le premier exemple utilise le fichier "foo.sh" créé pour obtenir les bonnes options rsync lors de l'exécution de la commande read-batch sur l'hôte distant.

  • Le deuxième exemple lit les données de lot via une entrée standard afin que le fichier de lot n'ait pas besoin d'être copié sur la machine distante en premier. Cet exemple évite le script foo.sh car il devait utiliser une option --read-batch modifiée, mais vous pouvez modifier le fichier de script si vous souhaitez en faire usage (assurez-vous qu'aucune autre option n'essaie d'utiliser la norme , comme l'option "--exclude-from = -").

    Mises en garde:

    L'option lecture-lot s'attend à ce que l'arborescence de destination qu'il met à jour soit identique à l'arborescence de destination qui a été utilisée pour créer le jeu de fichiers de mise à jour par lots. Lorsqu'une différence entre les arbres de destination est rencontrée, la mise à jour peut être supprimée avec un avertissement (si le fichier semble déjà à jour) ou la mise à jour du fichier peut être tentée, puis, si le fichier ne parvient pas à vérifier , la mise à jour a été supprimée avec une erreur. Cela signifie qu'il devrait être sûr de réexécuter une opération de lecture par lots si la commande a été interrompue. Si vous souhaitez forcer la mise à jour par lots à toujours être tentée quelles que soient la taille et la date du fichier, utilisez l'option -I (lors de la lecture du lot). Si une erreur se produit, l'arborescence de destination sera probablement dans un état partiellement mis à jour. Dans ce cas,

    La version rsync utilisée sur toutes les destinations doit être au moins aussi nouvelle que celle utilisée pour générer le fichier de commandes. Rsync mourra avec une erreur si la version du protocole dans le fichier de commandes est trop nouvelle pour être gérée par la lecture par lots de rsync. Voir aussi l'option --protocol pour un moyen de faire en sorte que la création de rsync génère un fichier batch qu'un ancien rsync peut comprendre. (Notez que les fichiers batch ont changé de format dans la version 2.6.3, donc le mélange de versions plus anciennes que celle avec des versions plus récentes ne fonctionnera pas.)

    Lors de la lecture d'un fichier de commandes, rsync forcera la valeur de certaines options à correspondre aux données du fichier de commandes si vous ne les avez pas définies de la même manière que la commande d'écriture par lots. D'autres options peuvent (et doivent) être modifiées. Par exemple, --write-batch change en --read-batch, --files-from est abandonné et les options --filter / - include / - exclude ne sont pas nécessaires sauf si l'une des options --delete est spécifiée .

    Le code qui crée le fichier BATCH.sh transforme toutes les options de filtre / inclusion / exclusion en une seule liste qui est ajoutée en tant que document «ici» au fichier de script shell. Un utilisateur avancé peut l'utiliser pour modifier la liste d'exclusion si un changement dans ce qui est supprimé par --delete est souhaité. Un utilisateur normal peut ignorer ces détails et utiliser simplement le script shell comme un moyen facile d'exécuter la commande --read-batch appropriée pour les données par lots.

    Le mode batch d'origine dans rsync était basé sur "rsync +", mais la dernière version utilise une nouvelle implémentation.

J'imagine que tu pourrais essayer

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup
Chloe
la source
La commande suggérée ne fonctionne pas:remote destination is not allowed with --read-batch
kynan
Affiche la commande complète. -pour un nom de fichier signifie lire à partir de l'entrée standard, et STDIN est également lu foodans l'exemple, un fichier local.
Chloé
2
Cela semble être la solution maximale correcte pour ce que j'essayais de faire, bien que mon cas d'utilisation pour cela se soit depuis longtemps évaporé dans l'éther. : D
Jessie
4

Vous pouvez essayer d'utiliser à l' unisson . La création de la liste de fichiers devrait être beaucoup plus rapide car elle conserve un cache des fichiers.

Jason Axelson
la source
2
Remarque: Unison ne conserve pas de «cache» des fichiers. Il ne conserve qu'une base de données des noms de fichiers, horodatages, sommes de contrôle. Il effectue toujours une analyse du système de fichiers et crée une somme de contrôle à comparer à la télécommande. Le seul avantage d'Unison est la synchronisation bidirectionnelle. Je recommande Unison, mais cela n'aidera pas ici.
Chloé
4

Le rsync --batch-modeprend en charge la multidiffusion. Si cela est possible sur votre réseau, cela pourrait valoir la peine de l'examiner.

codecrank
la source
2

que diriez-vous de changer les systèmes de fichiers?

Il y a quelque temps, j'ai changé un FS multi-téraoctets d'ext3 en XFS. Le temps de scanner les répertoires (avec environ 600 000 fichiers la dernière fois que j'ai vérifié) est passé de 15 à 17 minutes à moins de 30 secondes!

Javier
la source
1

Ce n'est pas une réponse directe, mais si vous utilisez rsync version 3+, il commencera à être transféré avant de générer la liste de fichiers complète.

Une autre option, encore peu efficace, serait de les exécuter en tant que jobs donc quelques-uns s'exécutent en même temps.

Aussi, je viens de penser à cette étrangeté si cela ne vous dérange pas d'utiliser tar:

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

Où chaque hôte local serait bien sûr des serveurs différents (suppose une connexion par clé). Je n'ai jamais utilisé ce qui précède cependant.

Kyle Brandt
la source
Hum! Curieusement, cwrsync (rsync 3.0.7) ne semble pas le faire. Je vais devoir chercher pourquoi, car cela serait d'une grande aide pour réduire ces énormes durées de fonctionnement. Merci!
Jessie
Cette version des deux côtés?
Kyle Brandt
Non en fait; la machine locale est cwrsync 3.0.7 et l'hôte distant (enfin, celui avec lequel je travaille maintenant) est rsync 3.0.3 sur Debian Lenny. Il ne semble pas que ce soit une différence de version trop importante pour qu'il se comporte mal, mais je ne sais pas .. Je vais examiner la mise à niveau du côté Debian.
Jessie
1
Quel étrange petit one-liner. Cela fonctionnerait probablement, cependant, si je ne tirais pas parti du fait que rsync n'a pas besoin de redoubler quelques données sur plusieurs liaisons lentes alors que, au plus, quelques centaines de ko seulement ont changé. De plus, obtenir les deux extrémités dans (cw) rsync 3.0.7 faisait toujours la création de listes de fichiers et le transfert en série. Pas trop préoccupé par ça, cependant.
Jessie
N'est-ce pas "tar cf -." le même que "tar c." ?
Johan Boulé
1

Que diriez-vous d'exécuter les tâches rsync à partir de host1, host2 et host3? Ou, exécutez un travail à copier sur host1, puis exécutez-le sur host2 et host3 pour l'obtenir à partir de host1.

mfinni
la source
1

Une meilleure solution serait de créer un référentiel avec git et de simplement pousser vers les 3 hôtes. Plus rapidement, vous n'auriez pas besoin de la partie liste de fichiers et elle consomme moins de ressources.

Bonne chance,
João Miguel Neves

jneves
la source
10
git ne conserve pas les temps de modification ni les autorisations (sauf pour le bit d'exécution) et nécessiterait de stocker une deuxième copie des données en tant qu'objets git .git/bien que les poussées vers les télécommandes qui auraient déjà la plupart des données seraient plus rapides. git ne remplace pas rsync.
Dan D.
De plus, git est accessible au public, sauf si vous payez.
Chloe
8
@Chloe, vous confondez git avec GitHub. Git lui-même est un système de contrôle de version distribué open source gratuit, et n'importe qui peut héberger le référentiel git par n'importe quel moyen, y compris http, nfset afp. GitHub est un site Web qui s'occupe de créer et de maintenir des dépôts git pour vous, et les rend publics (sauf si vous payez).
toriningen
1
@Chloe GitHub est visible publiquement, mais BitBucket fournit des dépôts privés.
sws
2
De plus, Git ne garde pas la trace des répertoires vides.
Flimm
1

En recherchant cette réponse moi-même, je pense que vous devez d'abord créer un lot à l'aide de rsync, puis l'envoyer à tous, ce qui rendrait la liste des fichiers nécessaire à la fois, et vous pourriez simplement fond les trois rsyncs pour les exécuter en parallèle.

Morgan
la source
1

Une autre solution possible consiste à exécuter autant de processus rsync en parallèle que vous avez d'hôtes, c'est-à-dire fork.

Alexey Tigarev
la source