Forum Linux.général rsync, plusieurs sources, plusieurs destination

Posté par  (site Web personnel) . Licence CC By‑SA.
Étiquettes : aucune
1
8
déc.
2021

Bonjour à tous,

J'ai un script qui me construit une liste de fichiers avec un chemin d'accès et un chemin de destination sur un serveur distant.

Exemple :

a/d/p/e/fic1.jpg;files/ref1/fic1/thumbnail/
o/i/n/9/fic2.jpg;files/ref1/fic/hd1
t/d/g/h/toto1.jpg;files/ref2/fic/
[...]

Pour le moment j'ai une boucle qui lit ligne par ligne le fichier et reconstruit la commande rsync avec la source et la destination. Mon fichier contient ~15000 lignes et il lancé tout les soirs. Je trouve tout cela pas du tout optimisé car pour chaque ligne rsync ce connecte, vérifie si le fichier existe et si non (ou différent) il le transfert, opération répétée 15 000 fois. L'idéal serait qu'il se connecte, vérifie pour l'intégralité de la liste si le fichier existe et le transfert si besoin à la destination prévue dans le fichier.

Il existe une option pour lui donner un fichier contenant une liste de fichiers sources mais ils seront tous transférés à la même destination et je n'ai pas trouvé un moyen pour qu'il utilise une destination spécifique par ligne.

Est-ce au moins possible ? Ou alors avec une autre méthode/commande.

Merci d'avance.

  • # Une idée de contournement

    Posté par  . Évalué à 3 (+1/-0).

    Il existe une option pour lui donner un fichier contenant une liste de fichiers sources mais ils seront tous transférés à la même destination et je n'ai pas trouvé un moyen pour qu'il utilise une destination spécifique par ligne.

    Je te propose d'établir quand même un point précis sur le serveur qui va recueillir les fichiers (par exemple /reception.
    Ensuite à partir de ton fichier de 15000 lignes, du génère la liste des fichiers à transférer par rsync vers ce point, en conservant l'arborescence.

    Ton fichier a/d/p/e/fic1.jpg va atterrir dans /reception/a/d/p/e/fic1.jpg

    Tu fais donc le transfert des 15000 fichiers avec une seule excécution de rsync.

    Ensuite sur ton serveur, tu exécutes un script (générer à partir de ton gros fichier) qui va établir des liens durs (hardlink) entre les fichiers contenus dans /reception vers les endroits que tu veux.

    # sur le serveur distant
    cp -l /reception/a/d/p/e/fic1.jpg files/ref1/fic1/thumbnail/
    

    Il n'y aura donc qu'une seule fois le fichier fic1.jpg sur le disque dur, mais présent à la fois dans /reception/a/d/p/e/ et dans files/ref1/fic1/thumbnail/

    Avec cette idée, tu gardes la rapidité de synchronisation de rsync, tu évites de dupliquer les fichiers sur le serveur distant, tu as quand même les fichiers où tu veux sur ton serveur et enfin, c'est automatisable.

    • [^] # Re: Une idée de contournement

      Posté par  (site Web personnel) . Évalué à 2 (+0/-0).

      C'est une bonne idée, moyennement quelques adaptations.

      Dans mon premier post je n'ai pas précisé que ces fichiers sont ensuite accessible via une url pour être mis à dispo pour des clients. Sur le serveur de destination c'est du apache/php qui tourne. Je ne sais pas si les hardlink marchent dans ce cas ?

      Il n'y aura donc qu'une seule fois le fichier fic1.jpg sur le disque dur, mais présent à la fois dans /reception/a/d/p/e/ et dans files/ref1/fic1/thumbnail/

      C'était pas clair dans mon exemple mais se sont des différents.

      Born to Kill EndUser !

      • [^] # Re: Une idée de contournement

        Posté par  . Évalué à 4 (+2/-0).

        Attention que si les liens physiques sont du côté de la destination, il faut dire à rsync de modifier directement le contenus du fichier (--inplace) pour que ces liens soient préservés.

      • [^] # Re: Une idée de contournement

        Posté par  . Évalué à 2 (+0/-0).

        Sur le serveur de destination c'est du apache/php qui tourne. Je ne sais pas si les hardlink marchent dans ce cas ?

        Je serais très étonné que cela ne marche pas. C'est quasi des fichiers normaux.

        C'était pas clair dans mon exemple mais se sont des différents.

        Je comprends pas trop, mais si tu veux dire que les noms seront différents, et bien ca marche quand même :

        cp -l titi.txt tmp/toto.txt
        

        Les fichiers titi.txt et tmp/toto.txt pointent vers le même "fichier" sur le disque dur.

    • [^] # Re: Une idée de contournement

      Posté par  . Évalué à 1 (+0/-0). Dernière modification le 10/12/21 à 17:01.

      Bonne idée, si je peux me permettre le plus simple serait de gèrer les liens côté source, avec comme avantage: ne pas devoir gèrer le 'inplace' et une vérification ultra simple: find dirsource dir_liens -type f \! -links 2, et pour enlever les liens exédentaires find dir_liens -type f -links 1 -delete.

      • [^] # Re: Une idée de contournement

        Posté par  . Évalué à 1 (+0/-0). Dernière modification le 10/12/21 à 17:09.

        (enfin bon pour la vérif c'est quif-quif, c'est tout aussi facile où que soient fait les hardlinks, faut juste pas oublier le --inplace si c'est fait côté destination). donc bref, je retire ce que je dis :D

  • # Avec tar

    Posté par  . Évalué à 3 (+1/-0). Dernière modification le 08/12/21 à 21:07.

    Tu peux utiliser tar --xform= pour créer une archive. Par exemple, pour le premier fichier: tar -c --xform='s|^a/d/p/e/fic1\.jpg$|files/ref1/fic1/thumbnail.jpg|' files/ref1/fic1/thumbnail.jpg

    Attention à bien échapper le fichier source, --xform étant une regexp sed. --xform étant répétable, tu peux renommer tous tes fichiers dans l’archive ainsi.

    Pour transférer avec ssh, tar -cz ... | ssh user@host tar -xzvC /destination/path

    Par contre, pas de transfert incrémental (ie seulement de ce qui a été modifié) avec cette méthode, à moins que tu aies la créer des archives incrémentales (--listed-incremental) depuis la source.

    Attention également à ne pas renommer un fichier (a/d/e/fic1.jpg) en dossier (files/).

    Attention aussi, les dossiers intermédiaires doivent être ajoutés dans l’archive (si tu renommes un fichier en files/ref1/fic1/thumbnail.jpg, tu dois d’abord t’assurer que files/, files/ref1/... ont précédemment été ajoutés dans l’archive (ou alors soient déjà présents sur la destination) : tar ne créera pas automatiquement les répertoires intermédiaires.

    • [^] # Re: Avec tar

      Posté par  . Évalué à 2 (+0/-0).

      Autre solution possiblement plus simple : créer l'arborescence cible dans un autre dossier avec des hardlinks, puis lancer rsync là dessus

    • [^] # Re: Avec tar

      Posté par  (site Web personnel) . Évalué à 2 (+0/-0).

      C'est pas mal aussi cette idée avec tar mais je préfère rester avec rsync car les fichiers source ne changent pas beaucoup donc le côté incrémentale est vraiment un plus.

      Born to Kill EndUser !

      • [^] # Re: Avec tar

        Posté par  . Évalué à 2 (+1/-0).

        find avec l'option mtime peut t'aider … Sinon il y a aussi le couple dump/restore.

  • # Changer de format d'entrée ?

    Posté par  . Évalué à 2 (+1/-0). Dernière modification le 08/12/21 à 22:18.

    Si ton format était plutôt de ce genre :

    destination;fichier1;fichier2;fichier3[...]
    

    Tu pourrais lancer un rsync par destination, ce qui peut être plus efficace déjà.

    Si tu ne veux pas/peux pas changer le format (parce que tu l'utilises ailleurs par exemple), tu peux sans doute dans ton script qui lance rsync faire un premier traitement qui dédoublonne les destinations pour faire ce que je propose, mais à la volée (via une variable, ou un tableau, en RAM).

    Enfin, tu peux utiliser un outil comme parallel (la version GNU ou une autre), qui va lancer les exécutions de rsync en parallèle. (Attention, dans le man de parallel il y a un exemple avec rsync mais ce n'est pas ton cas de figure).

    • [^] # Re: Changer de format d'entrée ?

      Posté par  (site Web personnel) . Évalué à 2 (+0/-0).

      J'ai la main sur la structure du fichier mais cela ne change en rien la structure physique du stockage et je n'ai pas la main sur le stockage source.

      Born to Kill EndUser !

      • [^] # Re: Changer de format d'entrée ?

        Posté par  . Évalué à 1 (+0/-0).

        Certes.
        Mais justement ma proposition est de ne changer l'organisation ni de la source ni de la destination, mais seulement de comment tu organises le traitement : collecte des paires sources/destination, regroupement par destination, synchro.

        Ou alors je comprend pas le problème ?

      • [^] # Re: Changer de format d'entrée ?

        Posté par  . Évalué à 2 (+0/-0).

        comme dit cg
        tu prends ton fichier, tu scriptes pour ranger différemment les données dans un nouveau fichier (temporaire)

        puis tu rsync avec ce nouveau fichier

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.