Sommaire
Comment pouvez-vous configurer Linux pour lire à la fois à partir d'un disque / système de fichiers local et écrire sur un partage réseau en même temps, au lieu de lire alors qu'aucune donnée ne passe sur le réseau, puis d'envoyer ces données sur le réseau pendant que le disque local est tourner au ralenti?
Il est beaucoup plus rapide de lire et d'écrire en même temps au lieu d'effectuer une seule opération, puis l'autre de manière alternée.
Détails
Je déplace une grande quantité de données des disques locaux d'une machine Linux vers un périphérique NAS.
J'utilise rsync
essentiellement pour copier /srv/data
dans /mnt/nas
, qui est une monture CIFS.
Tout a bien commencé, lisant à 100 Mo / s et écrivant sur le NAS à 100 Mo / s (limite du réseau gigabit), la lecture et l'écriture se faisant simultanément.
Cependant maintenant, quelques heures plus tard, je constate qu'il lit à partir du disque local, puis arrête la lecture pendant qu'il écrit sur le NAS, puis lorsqu'il n'y a plus de données à écrire sur le NAS, il reprend la lecture à partir du disque encore. Le réseau est inactif pendant la lecture du disque et le disque est inactif pendant que le réseau est en cours d'utilisation.
Inutile de dire que lire 200 Mo puis écrire 200 Mo prennent beaucoup plus de temps que lire et écrire ces 200 Mo en même temps.
Comment puis-je configurer le noyau de telle sorte qu'il s'en tient au comportement antérieur de lecture et d'écriture en même temps, plutôt que d'alterner entre lecture puis écriture, en n'effectuant qu'une seule opération à la fois?
Quelques observations: Lorsque le disque local lit à 100 + Mo / s, tout semble se passer en parallèle très bien, mais une fois que le disque ralentit (semble ne tourner qu'à 20 Mo / s pour une raison quelconque), c'est à ce moment que cette lecture / écriture le changement semble se produire.
Je peux également exécuter sync
manuellement toutes les quelques secondes pour obtenir les écritures en parallèle avec les lectures (bien que évidemment à des vitesses réduites), mais mettre sync
en while
boucle pour qu'il s'exécute toutes les cinq secondes ne semble pas être la bonne solution ...
Le noyau semble mettre en cache environ 1 Go de données, puis les écrire sur le réseau aussi rapidement que possible - ce qui est bien - je ne comprends tout simplement pas pourquoi le disque lent doit cesser d'être lu pendant que les données sont envoyées sur le réseau. réseau.
Réponses:
Après quelques recherches supplémentaires, il semble que ce problème soit moins lié au noyau et plus sur la façon dont
rsync
CIFS interagit.Pour autant que je sache, ce qui se passe, c'est que lors de la
rsync
fermeture du fichier de destination, CIFS (et probablement tout système de fichiers réseau) s'assure que le fichier est complètement vidé et écrit sur le disque distant avant leclose
retour de l' appel système. Il s'agit de garantir à toute application qu'une fois l'opération de fermeture terminée avec succès, le fichier a été entièrement enregistré et il n'y a aucun risque d'erreurs supplémentaires pouvant entraîner une perte de données.Si cela n'était pas fait, il serait possible pour une application de fermer un fichier, de quitter en pensant que l'opération de sauvegarde a réussi, puis plus tard (peut-être en raison d'un problème de réseau) les données ne pourraient pas être écrites après tout, mais d'ici là il est trop tard pour que l'application fasse quoi que ce soit, comme demander à l'utilisateur s'il souhaite enregistrer le fichier ailleurs à la place.
Cette exigence signifie que chaque fois que la
rsync
copie d'un fichier est terminée, le tampon de disque entier doit être vidé sur le réseau avant dersync
pouvoir continuer à lire le fichier suivant.Une solution de contournement consiste à monter le partage CIFS avec l'option
cache=none
qui désactive cette fonctionnalité et fait que toutes les E / S vont directement au serveur. Cela élimine le problème et permet aux lectures et aux écritures de s'exécuter en parallèle, mais un inconvénient de cette solution est que les performances sont quelque peu inférieures. Dans mon cas, la vitesse de transfert réseau passe de 110 Mo / s à 80 Mo / s.Cela peut signifier que si vous copiez des fichiers volumineux, les performances peuvent être meilleures avec le comportement alterné de lecture / écriture. Avec de nombreux fichiers plus petits, la désactivation du cache entraînera moins de vidages du cache chaque fois qu'un fichier est fermé, de sorte que les performances peuvent y augmenter.
Il semble avoir
rsync
besoin d'une option pour fermer ses descripteurs de fichiers dans un autre thread, afin qu'il puisse commencer à lire le fichier suivant pendant que le dernier est toujours vidé.EDIT: J'ai confirmé que cela
cache=none
aide certainement lors du transfert de nombreux petits fichiers (le fait passer de 10 Mo / s à 80 Mo / s), mais lors du transfert de gros fichiers (1 Go +)cache=none
, le transfert de 110 Mo / s vers le même 80 Mo / s est supprimé. Cela suggère que le transfert lent de nombreux petits fichiers concerne moins la recherche de disque source, et davantage le fait d'avoir autant de vidages de cache de tous les petits fichiers.la source
rsync
ne lire le fichier dans un autre thread ( en fait, un processus différent) parce qu'il est conçu de telle sorte qu'une copie dersync
est en cours d' exécution de chaque côté du réseau, même si dans votre cas , les deux exemplaires sont du même côté (et le système de fichiers se cache la fait qu'il existe un réseau). Je suppose que cela n'aide pas, car le processus de lecture remplit très très rapidement le tuyau pendant que le processus d'écriture se bloque sur unclose()
.rsync
fonctionnerait mieux si vous utilisiezrsync
le câble, pas CIFS.rsync
sur le NAS serait d'utiliserrsync
sur le réseau (commersync -a files localhost:/dest/path
) tout en introduisant artificiellement un énorme tampon (comme, plusieurs mégaoctets, au moins) dans les connexions réseau. Je ne sais pas à quoi ressemblerait le meilleur hack pour faire cela.rsync
sur la boîte NAS elle-même pourrait également contourner le problème. Un peu plus complexe cependant (autorisations NAS étranges, il faut supprimer les liens symboliques, etc.) mais si j'avais un peu plus de données à copier, cela vaut la peine d'investir du temps pour le faire, je pense.dump(8)
un NAS monté sur NFS. À l'époque, j'ai diagnostiqué le problème comme maximisant le processeur sur le NAS, en raison de l'effet combiné du serveur NFS et d'un pare-feu fonctionnant sur le NAS (la boîte n'était pas enracinée et le pare-feu ne pouvait pas être complètement désactivé à partir de l'interface Web). Le problème a disparu lorsque nous avons remplacé le NAS par un ancien PC. FWIW.