Existe-t-il une alternative plus rapide à cp pour la copie de fichiers volumineux (~ 20 Go)?

40

Je suis un étudiant diplômé et le groupe dans lequel je travaille entretient un cluster Linux. Chaque nœud du cluster a son propre disque local, mais ces disques locaux sont relativement petits et ne sont pas équipés d'une sauvegarde automatique. Le groupe possède donc un serveur de fichiers avec plusieurs To d'espace de stockage. Je suis un novice relatif de Linux, donc je ne sais pas quelles sont les spécifications du serveur de fichiers en termes de vitesse, de capacité de réseau, etc. Je sais par expérience que les disques locaux sont nettement plus rapides que le serveur de fichiers en termes d'E / S. . Une douzaine de personnes environ utilisent le serveur de fichiers.

Utiliser cppour copier un fichier de ~ 20 Go du serveur de fichiers sur l’un des disques locaux prend environ 11,5 minutes en temps réel en moyenne (selon time). Je sais que cette cpopération n’est pas très efficace car (1) timeme dit que le temps système pour une telle copie n’est que de ~ 45 secondes; et parce que (2) lorsque j'examine au topcours de la copie, % de la CPU est assez faible (par inspection, environ 0-10% en moyenne).

Utiliser cppour copier le même fichier d'environ 20 Go d'un dossier du disque local vers un autre dossier du même disque local prend moins de temps - environ 9 minutes en temps réel (~ 51 secondes en temps système, selon time). Donc, apparemment, le serveur de fichiers est un peu plus lent que le disque local, comme prévu, mais peut-être pas beaucoup plus lentement. Je suis surpris que la copie de local à même local ne soit pas plus rapide que 9 minutes.

J'ai besoin de copier environ 200 fichiers volumineux - chacun environ 20 Go - du serveur de fichiers vers l'un des disques locaux. Ma question est donc la suivante: existe-t-il une alternative plus rapide cpque la copie de gros fichiers sous Linux? (Ou y a-t-il des drapeaux à l'intérieur cpque je pourrais utiliser qui accéléreraient la copie?) Même si je pouvais d'une manière ou d'une autre réduire de façon considérable le temps de copie, cela aiderait énormément.

Je suis sûr d’acheter de nouveaux disques matériels plus rapides, mais je n’ai pas accès à de telles ressources. Je ne suis pas non plus un administrateur système - je ne suis qu'un utilisateur (novice) - je n'ai donc pas accès à des informations plus détaillées sur la charge qui se trouve sur les disques. Je sais que bien qu'une douzaine de personnes utilisent quotidiennement le serveur de fichiers, je suis la seule personne à utiliser ce nœud / disque local.

Andrew
la source
29
Cela fait environ 29Mo / s, ce qui est assez rapide si vous me le demandez. Je ne pense pas qu'il y ait une commande qui accélérera cela, le "goulot d'étranglement" est très probablement a) le réseau ou b) le serveur de fichiers.
tink
5
tink est 100% correct. Je n'ai jamais rien vu qui puisse améliorer ça. La seule chose que j'ai faite dans le passé est de compresser les données avant de les envoyer, mais cela signifie que vous ajoutez du temps avec les étapes de compression et de décompression, mais cela vaut parfois la peine si les données sont un bon candidat. comprimé!
slm
3
Vous pouvez également essayer ddet rsyncde comparer que l' on travaille plus vite dans votre environnement
Raza
@Salton Merci. Je n'ai pas encore essayé dd, mais je viens d'essayer rsync. Le temps réel était d'environ 11,5 minutes et le temps système était d'environ 1,5 minute, selon time.
Andrew
2
Je suis surpris que personne n'ait signalé que la copie d'un disque local à un disque local pourrait être rendue plus efficace si plusieurs disques étaient montés. Copier de /dev/sda1vers /dev/sdb1sera plus rapide que de copier d'un emplacement /dev/sda1à un autre sur /dev/sda1une autre partition /dev/sdacar le disque dur n'aura pas à effectuer de recherches supplémentaires entre les lectures et les écritures (en supposant des disques durs traditionnels avec des disques en rotation et des têtes mobiles; SSD est évidemment différent).
tripleee

Réponses:

53

% CPU devrait être faible pendant une copie. La CPU indique au contrôleur de disque "saisir les données des secteurs X – Y dans la mémoire tampon en Z". Ensuite, il fait quelque chose d'autre (ou dort s'il n'y a rien d'autre). Le matériel déclenche une interruption lorsque les données sont en mémoire. Ensuite, le processeur doit le copier plusieurs fois et indique à la carte réseau "transmettre des paquets aux emplacements mémoire A, B et C". Ensuite, cela revient à faire autre chose.

Vous poussez ~ 240 Mbps. Sur un réseau local gigabit, vous devriez être capable de faire au moins 800 Mbps, mais:

  1. Il est partagé entre tous ceux qui utilisent le serveur de fichiers (et éventuellement une connexion entre des commutateurs, etc.).
  2. Cela est limité par la vitesse à laquelle le serveur de fichiers peut gérer l'écriture, en gardant à l'esprit que sa bande passante d'E / S de disque est partagée par tous les utilisateurs.
  3. Vous n'avez pas précisé comment vous accédiez au serveur de fichiers (NFS, CIFS (Samba), AFS, etc.). Vous devrez peut-être ajuster votre montage réseau, mais sur tout ce qui est semi-récent, les valeurs par défaut sont généralement assez saines.

Pour traquer le goulot d'étranglement, cela iostat -kx 10va être une commande utile. Il vous montrera l'utilisation sur vos disques durs locaux. Si vous pouvez l'exécuter sur le serveur de fichiers, cela vous indiquera le taux d'occupation du serveur de fichiers.

La solution générale sera d’accélérer ce goulot d’étranglement, pour lequel vous n’avez bien sûr pas le budget. Cependant, il existe quelques cas spéciaux où vous pouvez trouver une approche plus rapide:

  • Si les fichiers sont compressibles et que votre processeur est rapide, une compression minimale à la volée sera peut-être plus rapide. Quelque chose comme lzopou peut-être gzip --fastest.
  • Si vous ne changez que quelques bits ici et là, puis envoyez le fichier, seul l'envoi des deltas sera beaucoup plus rapide. Malheureusement, rsynccela ne va pas vraiment aider ici, car il faudra lire le fichier des deux côtés pour trouver le delta. Au lieu de cela, vous avez besoin de quelque chose qui garde la trace du delta lorsque vous modifiez le fichier ... La plupart des approches présentées ici sont spécifiques à une application. Mais il est possible d’organiser quelque chose avec, par exemple, device-mapper (voir la nouvelle cible dm-era ) ou btrfs.
  • Si vous copiez les mêmes données sur plusieurs machines, vous pouvez utiliser quelque chose comme udpcast pour les envoyer simultanément à toutes les machines.

Et, puisque vous remarquez que vous n'êtes pas l'administrateur système, j'imagine que cela signifie que vous avez un administrateur système. Ou au moins une personne responsable du serveur de fichiers et du réseau. Vous devriez probablement lui demander, ils devraient être beaucoup plus familiers avec les spécificités de votre configuration. Votre administrateur système devrait au moins pouvoir vous indiquer le taux de transfert auquel vous pouvez raisonnablement vous attendre.

derobert
la source
+1 pour iostat -kx 10 :-)
n611x007
16

Cela pourrait peut-être être une alternative plus rapide, et vous ne serez pas encombrer le réseau pendant deux jours: prenez un ou deux gros disques USB (USB 3 si vous en avez) ou FireWire, connectez-le au serveur et copiez les fichiers sur le disque. Transportez le disque sur votre ordinateur local. Copiez les fichiers sur la machine.

Thomas Padron-McCarthy
la source
23
Sneakernet ( en.wikipedia.org/wiki/Sneakernet ) peut être très rapide: ne sous-estimez jamais la bande passante d'un break plein de cassettes qui défilent sur l'autoroute.
SplinterReality
10

Votre définition de l'efficacité est à l'envers. Une implémentation plus efficace gaspille moins de temps CPU. Sur la copie locale, le débit moyen (lecture + écriture) est en moyenne d’environ 74 Mo / s, ce qui équivaut à peu près à ce qu’un disque dur unique va obtenir.

psusi
la source
1
Oops. Quand j'ai dit "efficace", je voulais dire "rapide".
Andrew
10

Si vous avez un accès direct SSH (ou SFTP) (demandez à votre administrateur système), vous pouvez utiliser scpavec compression ( -C):

scp -C you@server:/path/to/yourfile .

Bien sûr, cela n’est utile que si le fichier est compressible et cela nécessitera plus de temps CPU, car il utilisera le cryptage (car il est sur SSH) et la compression.

Rétablir Monica
la source
Dans ce cas, il serait utile de désactiver le cryptage. Rappelez-vous que nous essayons de rendre la copie plus rapide .
lgeorget
3
@lgeorget Je soupçonne que la surcharge du chiffrement ne sera pas importante, vu la lenteur des disques durs. J'ai envisagé d'ajouter quelque chose à propos de -c none, mais cela semble être non standard .
Rétablir Monica
1
Nous traitons avec des fichiers ~ 20G, il est donc assez inefficace d’utiliser le chiffrement s’il n’est pas nécessaire.
lgeorget
1
@lgeorget Le cryptage peut être effectué beaucoup plus rapidement que le débit qu'il obtient, il ne ralentira donc rien. Mais il semble inutile de passer par SSH ici. Si vous avez juste besoin de compression, il y a sûrement d'autres outils?
Thomas
@Thomas L'avantage de SSH est que si vous êtes censé avoir accès au serveur distant, il exécute presque certainement SSH. Une autre option serait de compresser le fichier localement, de le copier sur le serveur, puis sshde le décompresser et de le décompresser.
Rétablir Monica
8

La cpmise en œuvre n'est probablement pas un goulot d'étranglement. Essayez d'observer l'utilisation d'E / S via iotople serveur et le nœud de cluster. Cela vous donnera une idée de l’amélioration des performances.

Une autre astuce consiste à éviter de copier les mêmes données à partir du même hôte. Par exemple, si vous avez le même fichier 20G à distribuer à partir du serveur de fichiers sur le réseau vers tous les nœuds du cluster, le processus fonctionnera beaucoup plus rapidement si vous copiez les fichiers entre homologues plutôt que sur un serveur unique. C'est un peu plus compliqué à implémenter, mais vous pouvez même essayer d'utiliser un p2p en ligne de commande comme un concentrateur à connexion directe.

Si dans ces fichiers 20G, certaines parties sont communes et que certaines sont spécifiques à un nœud de cluster, envisagez de les séparer en parties communes et spécifiques, puis distribuez la partie commune de manière p2p.

Michał Šrajer
la source
1
Si vous êtes sur un réseau local, vous devriez pouvoir faire de la multidiffusion plutôt que d'égal à égal. Ce qui devrait être plus rapide et moins chargé sur le réseau.
derobert
8

La nature / le contenu de ces fichiers peut faire une différence. J'ai cru comprendre que vous deviez copier 200 fichiers, environ 20 Go chacun, d'un ordinateur à un autre, c'est tout?

Si ces fichiers sont compressibles ou avec des pièces similaires / identiques, vous avez deux approches:

  • compressez-les avant de les copier ou créez un tunnel entre les ordinateurs sur lesquels l'activation du zip est activée. Donc, si le réseau est le goulot d'étranglement, ce sera un peu plus rapide

  • Si les fichiers sont très similaires ou partagent des éléments de contenu commun, essayez d’utiliser rsync . Il passera un certain temps à rechercher ce qui est commun parmi les fichiers et n'aura pas besoin de le copier littéralement , car il le reconstruira en fonction de ce qui est commun.

modifier

Aurez-vous besoin de copier ces fichiers plusieurs fois? (comme une copie -> utiliser ces fichiers -> changer quelque chose dans les fichiers de l'ordinateur A -> copier à nouveau les fichiers sur l'ordinateur B)

Si c'est le cas, rsync sera utile, car il essaiera de détecter ce qui est égal entre les versions et ne copie pas ce qui n'est pas modifié.

Et une troisième méthode: si ce qui précède est correct (modifications de fichier, puis copiez à nouveau tous les fichiers sur le deuxième ordinateur), vous pouvez essayer binary diffde modifier simplement sur le deuxième ordinateur ce qui a été modifié sur le premier ordinateur.

woliveirajr
la source
6

Je vois ce qui suit ici, le cryptage n’est pas une bonne idée car il pourrait éventuellement augmenter la quantité de données à transférer.

Si vous copiez entre deux systèmes, le goulot d'étranglement est bien sûr la connexion entre les serveurs.

Si vous copiez localement, regardez comment le processus se déroule, il est thread unique, ainsi les utilitaires Linux standard utilisent:

- for all blocks in a file
      read a block
      write a block

Il n'y a AUCUN accès simultané à cette opération.

Pour accélérer les choses, vous pouvez utiliser quelque chose comme ceci:

  buffer -i infile -o outfile -m size-of-shared-memory-default-1MByte

Reportez-vous à la page de manuel buffer (1) pour plus d'informations.

La commande buffer configure deux processus pour exécuter le processus de copie simultanément: un pour la lecture et l'autre pour l'écriture, et utilise un tampon de mémoire partagée pour communiquer les données entre les deux processus. La mémoire tampon partagée est votre mémoire tampon circulaire classique qui empêche l'écrasement des données non écrites et l'écriture des données déjà écrites. J'ai utilisé ce programme pour couper environ 10 à 20% du temps de copie dans les transferts de disque à bande.

mdpc
la source
En fait, il y a concurrence dans "lire un bloc / écrire un bloc" car "écrire un bloc" le place simplement dans la mémoire tampon du noyau, et le noyau gère l'écriture du bloc en arrière-plan (au moins jusqu'à ce que vous commenciez à vous épuiser). de RAM). Ou si vous utilisez O_DSYNC / O_SYNC pour une raison quelconque.
derobert
3

Pourquoi ne pas essayer un algorithme de propagation P2P, si vous devez mettre à jour votre cluster entier en même temps?

https://github.com/lg/murder est ce que Twitter utilise

Il y a BTSync que vous pouvez essayer aussi.

Gui13
la source
1

Si vous copiez fréquemment les mêmes ensembles de fichiers de votre ordinateur local vers le serveur avec des modifications mineures ici et là. Vous pouvez accélérer le transfert en utilisant rsync ou un DVCS (par exemple, hg ou git).

git ou hg peuvent suivre et détecter les deltas et ne transférer que ces deltas. En cas d'utilisation d'un git, puisque les deux parties ont l'historique complet du référentiel, déterminer que le delta est très bon marché.

rsync utilise une forme d'algorithme de checksum roulant pour détecter les deltas sans connaissance préalable de ce qui se trouve de l'autre côté. Bien que rsync ait besoin de plus de travail pour calculer les deltas, il n’est pas nécessaire de stocker l’historique complet du fichier.

Lie Ryan
la source
1

Vous voudrez peut-être essayer de regrouper tous les fichiers dans une seule archive (il n'est pas nécessaire de compresser). D'après mon expérience, la copie de cette archive est plus rapide que la copie d'un grand nombre de fichiers individuels.

Munim
la source
3
Bonne observation générique, mais comme le dit la question «~ 200 fichiers volumineux - chacun ~ 20 Go», je ne pense pas que cela puisse être considéré comme une réponse réelle à ce problème.
Manatwork
@manatwork ah .. je n'ai pas lu clairement. Je pensais qu'il avait 200 dossiers pour un total de 20 Go
Munim
0

Essayez bbcp . Les tests effectués dans notre environnement ont révélé que cp avait une sorte de gouverneur intégré. Faites attention, car lorsque vous retirez le gouverneur, vous pouvez rediriger votre serveur et provoquer une panne. Dans notre cas, nous mettions le serveur hors ligne pour faire la copie, donc mieux c'était plus rapide. Cela a amélioré le temps de transfert de plusieurs heures.

James Shewey
la source
0

Assurez-vous que les fichiers cibles n'existent pas avant la copie.

Parfois, il est surprenant de constater combien de temps est consacré même à la copie sur le même hôte (aucun réseau impliqué).

Voir ma réponse à une autre question cp ici . En bref, écraser un fichier existant est beaucoup plus lent que de le tronquer ou de le dissocier d’abord, puis de le copier. Ce dernier est 8 fois plus rapide pour un fichier de 1,2 Go.

Pierre D
la source