J'essaie de copier un lot de fichiers avec scp
mais c'est très lent. Voici un exemple avec 10 fichiers:
$ time scp cap_* user@Host:~/dir
cap_20151023T113018_704979707.png 100% 413KB 413.2KB/s 00:00
cap_20151023T113019_999990226.png 100% 413KB 412.6KB/s 00:00
cap_20151023T113020_649251955.png 100% 417KB 416.8KB/s 00:00
cap_20151023T113021_284028464.png 100% 417KB 416.8KB/s 00:00
cap_20151023T113021_927950468.png 100% 413KB 413.0KB/s 00:00
cap_20151023T113022_567641507.png 100% 413KB 413.1KB/s 00:00
cap_20151023T113023_203534753.png 100% 414KB 413.5KB/s 00:00
cap_20151023T113023_855350640.png 100% 412KB 411.7KB/s 00:00
cap_20151023T113024_496387641.png 100% 412KB 412.3KB/s 00:00
cap_20151023T113025_138012848.png 100% 414KB 413.8KB/s 00:00
cap_20151023T113025_778042791.png 100% 413KB 413.4KB/s 00:00
real 0m43.932s
user 0m0.074s
sys 0m0.030s
Ce qui est étrange, c'est que le taux de transfert est d'environ 413 Ko/s et la taille du fichier est d'environ 413 Ko, donc il devrait vraiment transférer un fichier par seconde, mais cela prend environ 4,3 secondes par fichier.
Avez-vous une idée de l'origine de ces frais généraux et existe-t-il un moyen de le rendre plus rapide?
Le commentaire de @ wurtel est probablement correct: il y a beaucoup de frais généraux pour établir chaque connexion. Si vous pouvez résoudre ce problème vous obtiendrez des transferts plus rapides (et si vous ne pouvez pas, utilisez simplement la solution de contournement rsync
de @ roaima). J'ai fait une expérience de transfert de fichiers de taille similaire (head -c 417K /dev/urandom > foo.1
et a fait quelques copies de ce fichier) vers un hôte qui met un certain temps à se connecter (Host4) et un autre qui répond très rapidement (Host1):
$ time ssh $Host1 echo
real 0m0.146s
user 0m0.016s
sys 0m0.008s
$ time scp * $Host1:
foo.1 100% 417KB 417.0KB/s 00:00
foo.2 100% 417KB 417.0KB/s 00:00
foo.3 100% 417KB 417.0KB/s 00:00
foo.4 100% 417KB 417.0KB/s 00:00
foo.5 100% 417KB 417.0KB/s 00:00
real 0m0.337s
user 0m0.032s
sys 0m0.016s
$ time ssh $Host4 echo
real 0m1.369s
user 0m0.020s
sys 0m0.016s
$ time scp * $Host4:
foo.1 100% 417KB 417.0KB/s 00:00
foo.2 100% 417KB 417.0KB/s 00:00
foo.3 100% 417KB 417.0KB/s 00:00
foo.4 100% 417KB 417.0KB/s 00:00
foo.5 100% 417KB 417.0KB/s 00:00
real 0m6.489s
user 0m0.052s
sys 0m0.020s
$
Vous pouvez utiliser rsync
(sur ssh
), qui utilise une seule connexion pour transférer tous les fichiers source.
rsync -avP cap_* user@Host:dir
Si vous n'avez pas rsync
(et pourquoi pas !?) vous pouvez utiliser tar
avec ssh
comme ceci, ce qui évite de créer un fichier temporaire:
tar czf - cap_* | ssh user@Host tar xvzfC - dir
Le rsync
est à privilégier, toutes choses égales par ailleurs, car il peut être redémarré en cas d'interruption.
C'est la négociation du transfert qui prend du temps. En général, les opérations sur n fichiers de b octets prennent chacune beaucoup, beaucoup plus longtemps qu'une seule opération sur un seul fichier de n * - b octets. Cela est également vrai, par exemple pour les E/S disque.
Si vous regardez attentivement, vous verrez que le taux de transfert dans ce cas est size_of_the_file/secs.
Pour transférer des fichiers plus efficacement, regroupez-les avec tar
, puis transférez l'archive tar:
tar cvf myarchive.tar cap_20151023T*.png
ou, si vous souhaitez également compresser l'archive,
tar cvzf myarchive.tar.gz myfile*
La compression ou non dépend du contenu du fichier, par exemple. s'il s'agit de fichiers JPEG ou PNG, la compression n'aura aucun effet.
Une autre raison pour laquelle scp est plus lent qu'il ne devrait l'être, en particulier sur les réseaux à large bande passante, est qu'il a des tampons de contrôle de flux internes définis statiquement qui finissent par devenir des goulots d'étranglement des performances du réseau.
HPN-SSH est une version corrigée d'OpenSSH qui augmente la taille de ces tampons. Cela fait une différence énorme avec la vitesse de transfert scp (voir les graphiques sur le site, mais je parle aussi d'expérience personnelle). Bien sûr, pour obtenir les avantages dont vous avez besoin pour installer HPN-SSH sur tous vos hôtes, cela en vaut la peine si vous devez régulièrement transférer des fichiers volumineux.
J'ai utilisé la technique décrite ici qui utilise gzip parallèle et netcat pour compresser et copier rapidement les données.
Cela se résume à:
# SOURCE:
> tar -cf - /u02/databases/mydb/data_file-1.dbf | pigz | nc -l 8888
# TARGET:
> nc <source Host> 8888 | pigz -d | tar xf - -C /
Cela utilise tar pour rassembler le ou les fichiers. Utilise ensuite pigz pour obtenir de nombreux threads cpu pour compresser et envoyer le fichier, la transmission réseau utilise netcat. Côté réception, netcat écoute puis décompresse (en parallèle) et décompresse.
Je viens d'avoir ce problème lors d'un transfert de site à site d'un gros fichier mp4 via scp
. Obtient ~ 250 Ko/s. Après avoir désactivé la protection contre les inondations (FP) UDP sur le pare-feu de destination, le taux de transfert est passé à 6,5 Mo/s. Lorsque vous réactivez FP, le taux retombe à ~ 250 Ko/s.
Expéditeur: cygwin, Destinataire: Fedora 20, Firewall Sophos UTM.
Pourquoi SSH utilise-t-il UDP? @ Superuser.com - Ce n'est pas directement d'après ce que j'ai lu.
Lors de l'examen du journal du pare-feu, la détection des inondations se produisait à la fois sur les ports source et destination 4500 sur les adresses IP publiques, et non sur les adresses VPN internes de site à site privées. Il semble donc que mon problème soit probablement une NAT situation transversale où les données scp
TCP sont finalement cryptées et encapsulées dans ESP & paquets UDP, et par conséquent soumis à FP. Pour supprimer scp
de l'équation, j'ai exécuté une opération de copie de fichiers Windows sur le VPN et remarqué des performances similaires à scp
avec et sans FP activé. A également exécuté un test iperf
sur TCP et a remarqué 2Mbits/sec avec FP, et 55Mbits/sec sans.
Étant donné que cette question n'est pas si ancienne et que personne d'autre n'a fait référence à cette solution, je pense qu'elle est appropriée car elle pousse la bande passante à la limite maximale (10 Mo/s dans mon cas) contrairement à scp qui est d'environ 250 ko/s, ce qui répond à votre question.
En fait, les mêmes 250 kb/s avec rsync - au moins avec le spécificateur de port rclone -Avvp cap_* -e "ssh -p 1087 -i id_rsa" user@Host:~/dir
Citer un publier sur la liste de diffusion openssh-unix-dev :
Le protocole scp est obsolète, rigide et difficile à corriger. Ses auteurs recommandent plutôt l'utilisation de protocoles plus modernes comme sftp et rsync pour le transfert de fichiers
La même syntaxe s'applique à sftp donc au lieu de scp text.txt user@Host
c'est maintenant sftp text.txt user@Host
( exemples d'utilisation scp interchangeables avec sftp )
De plus, la version récente d'OpenSSH devrait activer le démon - au moins dans mon cas sur un serveur Arch Linux mais vous devrez peut-être installer un paquet sftp sur d'autres distributions.
Un autre exemple de travail avec un indicateur de fichier de chiffrement ssh (id_rsa) et un port ssh non standard 1087 au lieu de 22 pour vous éviter de jouer avec la syntaxe:
sftp -P 1087 -i id_rsa user@server:/home/user/Downloads/Video/*/*.mp4 /home/user/Videos/
Votre sftp peut également être limité à 800kb/s ou ~ 1 Mbit/s. Vous pouvez vérifier cela avec:
# sysctl -a | grep net.*rmem
et vous pouvez modifier les limites, par exemple comme ça s'ils sont trop lents:
# sysctl -w net.ipv4.tcp_rmem='40960 873800 62914560'
# sysctl -w net.core.rmem_max=8388608