Nous utilisons rsync pour sauvegarder les serveurs.
Malheureusement, le réseau de certains serveurs est lent.
Il faut jusqu'à cinq minutes pour que rsync détecte que rien n'a changé dans les énormes répertoires. Ces énormes arborescences de répertoires contiennent beaucoup de petits fichiers (environ 80k fichiers).
Je suppose que les clients rsync envoient des données pour chacun des fichiers 80k.
Étant donné que le réseau est lent, je voudrais éviter d'envoyer 80 000 fois des informations sur chaque fichier.
Existe-t-il un moyen de dire à rsync de faire une somme de hachage d'une arborescence de sous-répertoires?
De cette façon, le client rsync n'enverrait que quelques octets pour une énorme arborescence de répertoires.
Mise à jour
Jusqu'à présent, ma stratégie consiste à utiliser rsync
. Mais si un autre outil convient mieux ici, je peux changer. Les deux (serveur et client) sont sous mon contrôle.
pdate2
Il y a 80k fichiers dans un répertoire arborescence. Chaque répertoire ne contient pas plus de 2 000 fichiers ou sous-répertoires
pdate
Détails sur la lenteur du réseau:
time ssh einswp 'cd attachments/200 && ls -lLR' >/tmp/list
real 0m2.645s
Taille du fichier tmp/list: 2MByte
time scp einswp:/tmp/list tmp/
real 0m2.821s
Conclusion: scp a la même vitesse (pas de surprise)
time scp einswp:tmp/100MB tmp/
real 1m24.049s
Vitesse: 1,2 Mo/s
Quelques points sans rapport:
80 000 fichiers dans un répertoire? Aucun système d'exploitation ou application ne gère très bien cette situation par défaut. Vous venez de remarquer ce problème avec rsync.
Rsync moderne gère les grands répertoires beaucoup mieux que par le passé. Assurez-vous que vous utilisez la dernière version.
Même le vieux rsync gère assez bien les gros répertoires sur des liens à latence élevée ... mais les fichiers de 80k ne sont pas gros ... c'est énorme!
Cela dit, l'utilisation de la mémoire de rsync est directement proportionnelle au nombre de fichiers dans une arborescence. Les grands répertoires prennent une grande quantité de RAM. La lenteur peut être due à un manque de RAM de chaque côté. Faites un test en regardant l'utilisation de la mémoire. Linux utilise les restes RAM comme cache disque, donc si vous manquez de RAM, il y a moins de cache disque. Si vous manquez de RAM et que le système commence à utiliser le swap, les performances seront vraiment mauvaises.
--checksum
(ou -c
) nécessite la lecture de chaque bloc de chaque fichier. Vous pouvez probablement vous en tirer avec le comportement par défaut de simplement lire les heures de modification (stockées dans l'inode).
Il y a certains projets comme Gigasync qui "hacheront la charge de travail en utilisant Perl pour récapituler l'arborescence des répertoires, en construisant de petites listes de fichiers à transférer avec rsync."
L'analyse du répertoire supplémentaire va représenter une grande quantité de frais généraux, mais ce sera peut-être une victoire nette.
Si vous utilisez Linux/FreeBSD/etc avec tous les paramètres par défaut, les performances seront terribles pour toutes vos applications. Les valeurs par défaut supposent des répertoires plus petits afin de ne pas gaspiller RAM sur les caches surdimensionnés.
Ajustez votre système de fichiers pour mieux gérer les grands répertoires: Les grandes tailles de dossiers ralentissent-elles IO performance?
Les systèmes d'exploitation de type BSD ont un cache qui accélère la recherche d'un nom vers l'inode (le cache "namei"). Il y a un cache namei pour chaque répertoire. S'il est trop petit, c'est un obstacle plus qu'une optimisation. Étant donné que rsync effectue un lstat () sur chaque fichier, l'inode est accessible pour chacun des fichiers de 80 Ko. Cela pourrait faire exploser votre cache. Recherchez comment régler les performances du répertoire de fichiers sur votre système.
XFS a été conçu pour gérer des répertoires plus volumineux. Voir système de fichiers grand nombre de fichiers dans un seul répertoire
Envisagez de calculer le nombre de blocs de disque en cours de lecture et calculez la vitesse à laquelle vous devez vous attendre à ce que le matériel puisse lire autant de blocs.
Peut-être que vos attentes sont trop élevées. Considérez combien de blocs de disque doivent être lus pour effectuer une rsync sans fichiers modifiés: chaque serveur devra lire le répertoire et lire un inode par fichier. Supposons que rien ne soit mis en cache car, eh bien, 80k fichiers ont probablement fait exploser votre cache. Disons que c'est 80k blocs pour garder les mathématiques simples. Cela représente environ 40 millions de données, qui devraient être lisibles en quelques secondes. Cependant, s'il doit y avoir une recherche de disque entre chaque bloc, cela pourrait prendre beaucoup plus de temps.
Vous devrez donc lire environ 80 000 blocs de disques. À quelle vitesse votre disque dur peut-il faire cela? Étant donné qu'il s'agit d'E/S aléatoires, pas d'une longue lecture linéaire, 5 minutes pourraient être assez excellentes. C'est 1/(80000/600), ou un disque lu toutes les 7,5 ms. Est-ce rapide ou lent pour votre disque dur? Cela dépend du modèle.
Une autre façon d'y penser est la suivante. Si aucun fichier n'a changé, ls -Llr
fait la même quantité d'activité sur le disque mais ne lit jamais les données de fichier (juste les métadonnées). Le temps ls -Llr
prend pour exécuter est votre limite supérieure.
Rsync (sans modification de fichiers) est-il beaucoup plus lent que ls -Llr
? Ensuite, les options que vous utilisez pour rsync peuvent être améliorées. Peut être -c
est activé ou un autre indicateur qui lit plus que des répertoires et des métadonnées (données d'inode).
Rsync (sans modification de fichiers) est-il presque aussi rapide que ls -Llr
? Ensuite, vous avez réglé le mieux possible rsync. Vous devez régler le système d'exploitation, ajouter de la RAM, obtenir des disques plus rapides, modifier les systèmes de fichiers, etc.
Les fichiers 80k sont juste une mauvaise conception. Très peu de systèmes de fichiers et d'outils système gèrent très bien ces gros répertoires. Si les noms de fichiers sont abcdefg.txt, pensez à les stocker dans abdc/abcdefg.txt (notez la répétition). Cela décompose les répertoires en plus petits, mais ne nécessite pas une énorme modification du code.
Pensez également à utiliser une base de données. Si vous avez 80k fichiers dans un répertoire, vos développeurs peuvent peut-être contourner le fait que ce qu'ils veulent vraiment, c'est une base de données. MariaDB ou MySQL ou PostgreSQL serait une bien meilleure option pour stocker de grandes quantités de données.
Enfin, 5 minutes sont-elles vraiment si mauvaises? Si vous exécutez cette sauvegarde une fois par jour, 5 minutes, ce n'est pas beaucoup de temps. Oui, j'aime la vitesse. Cependant, si 5 minutes sont "assez bonnes" pour vos clients, elles sont suffisantes pour vous. Si vous n'avez pas de SLA écrit, que diriez-vous d'une discussion informelle avec vos utilisateurs pour savoir à quelle vitesse ils s'attendent à ce que les sauvegardes prennent.
Je suppose que vous n'avez pas posé cette question s'il n'était pas nécessaire d'améliorer les performances. Cependant, si vos clients sont satisfaits de 5 minutes, déclarez la victoire et passez à d'autres projets qui nécessitent vos efforts.
Mise à jour: Après quelques discussions, nous avons déterminé que le goulot d'étranglement est le réseau. Je vais recommander 2 choses avant d'abandonner :-).
-z
, et configurez votre ssh avec et sans compression. Minutez les 4 combinaisons pour voir si l'une d'entre elles fonctionne significativement mieux que les autres.Non, ce n'est pas possible avec rsync et ce serait tout à fait inefficace à un autre égard:
Normalement, rsync
compare uniquement les dates de modification de fichier et les tailles de fichier. Votre approche l'obligerait à lire et à additionner le contenu des fichiers tous deux fois (sur le système local et distant) pour trouver les répertoires modifiés.
Pour la synchronisation d'un grand nombre de fichiers (où peu de choses ont changé), il vaut également la peine de définir noatime
sur les partitions source et de destination. Cela permet d'économiser les temps d'accès en écriture sur le disque pour chaque fichier inchangé.
Vous pouvez également essayer lsyncd, qui ne rsync que lorsque des modifications sont détectées sur le système de fichiers et uniquement les sous-répertoires modifiés. Je l'utilise pour des répertoires contenant jusqu'à deux millions de fichiers sur un serveur décent.
Utilisez rsync en mode démon côté serveur pour accélérer le processus de listage/somme de contrôle:
Notez qu'il n'est pas chiffré, mais peut être tunnelé sans perdre l'amélioration des performances de la liste.
La compression rsync plutôt que ssh devrait également améliorer les performances.