it-swarm.it

Come posso copiare al meglio un numero elevato di piccoli file su scp?

Ho una directory che ha diversi gigabyte e diverse migliaia di piccoli file. Voglio copiarlo sulla rete con scp più di una volta. Il tempo della CPU sui computer di origine e di destinazione è economico, ma l'overhead di rete aggiunto copiando ogni file singolarmente è enorme. Lo farei tar/gzip e lo spedirei, ma la macchina sorgente è a corto di disco.

C'è un modo per me di convogliare l'output di tar -czf <output> <directory> per scp? In caso contrario, esiste un'altra soluzione semplice? La mia macchina sorgente è antica (SunOS), quindi preferirei non installarla su di essa.

63
nmichaels

Puoi eseguire il pipe di tar attraverso una sessione ssh:

$ tar czf - <files> | ssh [email protected] "cd /wherever && tar xvzf -"
110
pdo

Il catrame con compressione bzip2 dovrebbe prelevare tanto carico dalla rete e dalla cpu.

$ tar -C /path/to/src/dir -jcf - ./ | ssh [email protected] 'tar -C /path/to/dest/dir -jxf -'

Non usando -v perché l'output dello schermo potrebbe rallentare il processo. Ma se vuoi un output dettagliato usalo sul lato locale di tar (-jcvf), non sulla parte remota.

Se copi ripetutamente sullo stesso percorso di destinazione, come l'aggiornamento di una copia di backup, la scelta migliore è rsync con compressione.

$ rsync -az -e ssh /path/to/src/dir/ [email protected]:/path/to/dest/dir/

Si noti che entrambi i percorsi src e dest terminano con un /. Ancora una volta, non usando -v e -P flag apposta, aggiungili se hai bisogno di un output dettagliato.

23
forcefsck

usa rsync , usa SSH.

Uso:

rsync -aPz /source/path destination.server:remote/path

Gli switch rsync si preoccupano della compressione e delle informazioni sull'I-Node. -P visualizza l'avanzamento di ogni file.

Puoi usare scp -C, che consente la compressione, ma se possibile, usa rsync.

16
polemon

Puoi eseguire tar su entrambe le estremità usando ssh. scp fa parte della famiglia di bontà ssh, quindi probabilmente ce l'hai su entrambi i lati.

 8:03AM 12 % tar cf - some_directory | ssh dest_Host "tar xf -"

Potrebbe esserci un modo per far funzionare gzip o bzip2 nella pipeline per ridurre anche il traffico di rete.

3
Bruce Ediger

La risposta di @pdo è buona, ma si può aumentare la velocità con un buffer e una buona compressione e aggiungere una barra di avanzamento.

Spesso la rete è il collo di bottiglia e la velocità varia nel tempo. Pertanto, aiuta a bufferizzare i dati prima di inviarli sulla rete. Questo può essere fatto con pv.

Inoltre, di solito si può aumentare la velocità con un algoritmo di compressione adeguato. Gzip (come usato sopra) è un algoritmo di compressione veloce, ma in generale zstandard (zstd) (e per rapporti di compressione elevati LZMA/LZMA2 (xz) comprime meglio ed è più veloce allo stesso tempo I nuovi xz e zstd hanno già il supporto multi core integrato. Per usare gzip con più core pigz può essere usato.

Ecco un esempio per inviare dati con una barra di avanzamento, buffering e compressione zstandard su una rete:

tar cf - . | pv -perabs $(du -sk . | cut -f 1)K | zstd -14 --long=31 -T0 | pv -qCB 512M | ssh [email protected] "cd /wherever && pv -qCB 512M | zstd -cd -T0 --long=31 | tar xf -"

Il primo pv è mostrare l'avanzamento ( p ), il tempo stimato ( e ), velocità di trasferimento ( r ), velocità media ( a ), byte totali trasferiti ( b ). La dimensione totale è stimata con du e aggiunta all'opzione size ( s ). L'avanzamento viene misurato prima della compressione e del buffering, quindi non è molto preciso, ma comunque utile.

zstd viene utilizzato con l'impostazione di compressione 14 . Questo numero può essere ridotto o aumentato a seconda della velocità della rete e della CPU, quindi zstd è un po 'più veloce della velocità della rete. Con quattro core su una CPU Haswell da 3,2 GHz 14 fornisce una velocità di circa 120 MB/s. Nell'esempio, viene utilizzata la modalità lunga 31 (utilizza una finestra da 2 GB, richiede molta RAM, ma è molto buona, ad esempio per comprimere i dump del database) . Le opzioni T0 impostano la quantità di thread sul numero di core. Bisogna essere consapevoli del fatto che insieme alla modalità lunga queste impostazioni utilizzano molta memoria.

Un problema con zstd è che la maggior parte dei sistemi operativi non viene fornita con la versione> = 1.3.4. Questa versione è necessaria per un corretto supporto multi core e lungo. Se non disponibile, può essere compilato e installato da https://github.com/facebook/zstd con solo make -j4 && Sudo make install. Invece di zstd, si può anche usare xz o pigz. xz è lento ma si comprime molto bene (buono su connessioni lente), pigz/gzip è veloce ma non si comprime molto bene. pv viene quindi riutilizzato, ma per il buffering (q per quiet, C per la modalità no splice [sempre necessaria per il buffering] e B per impostare la dimensione del buffer).

Nell'esempio viene utilizzato anche un buffer sul lato ricevitore. Questo spesso non è necessario (perché la velocità di decompressione e di scrittura sul disco rigido è per lo più superiore alla velocità della rete), ma di solito non danneggia neanche.

3
Fabian Heller

Se hai gzip su entrambe le estremità: sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh [email protected] "cd destinationdir && gzip -c -d | tar xf -"

Se non hai gzip sul computer di origine, assicurati di aver decompresso sulla destinazione: sourcehost$ cd sourcedir && tar cf - . | compress | ssh [email protected] "cd destdir && uncompress | tar xf -"

Questo sarebbe più veloce del primo comprimerlo, quindi inviarlo, quindi decomprimerlo e non richiede spazio su disco aggiuntivo su entrambi i lati. Ho sorseggiato la bandiera di compressione (z) su tar, perché probabilmente non ce l'hai sul lato antico.

2
MattBianco

Oppure puoi farlo al contrario, se necessario. Cioè tirare il tarball sulla rete piuttosto che Push come è stato suggerito. Questo non risolve la parte ripetitiva della tua domanda e rsync è la cosa migliore per farlo, ma probabilmente ci sono tar switch per aiutarti.

Quindi sulla macchina locale:

ssh remote 'tar zcf - /etc/resolv.conf' | tar zxf -

Meglio trovarsi prima nella directory giusta o devi usare l'opzione -C sul comando untaring alla fine.

Basta menzionarlo nel caso fosse necessario. È per me come nella mia situazione il mio server locale è dietro nat, quindi prenderei qualche rete inutilmente per poterlo fare nel modo che è stato precedentemente menzionato.

HTH

2
DaveQB

Oppure monta il filesystem remoto tramite sshfs

sshfs [email protected]:/path/on/remote /path/on/local
1
ivanivan

Sebbene non sia il più elegante, soprattutto perché non sta copiando un singolo file Zip o tar e doppiamente, in quanto non aiuta a ridurre la necessità della rete, la mia unica scelta è stata quella di utilizzare scp -r:

-r

      Copia ricorsivamente intere directory. Si noti che scpsegue i collegamenti simbolici rilevati nella traversata dell'albero.
Fonte: scp (1)

Stavo riscontrando problemi con l'esaurimento dello spazio su disco con un file tar zippato da 30 GB. Pensavo che gunzip potesse farlo in linea, cioè rimuovendo l'originale mentre veniva decompresso (e potrei aver perso un risultato di Google) ma non sono riuscito a trovare nulla.

Infine, poiché ero stanco di provare più volte in attesa che un nuovo file TAR o Zip finisse di eseguire il taring o zippare, alla fine ho appena fatto:

  1. Dal server/PC/laptop originale, vai alla directory in cui si trovano le tue cartelle con numerosi file/cartelle.
  2. scp -r source_folder_nameyourname@yourservername:destination_folder_name

Quindi prendi un po 'di birra, caffè o popcorn e aspetta. La cosa buona è che scp riproverà se la connessione di rete "si blocca". Spero solo che non scenda completamente.

1
JGlass