Perché il piping di 'dd' tramite gzip è molto più veloce di una copia diretta?


79

Volevo eseguire il backup di un percorso da un computer nella mia rete a un altro computer nella stessa rete su una linea a 100 Mbit / s. Per questo l'ho fatto

dd if=/local/path of=/remote/path/in/local/network/backup.img

che mi ha dato una velocità di trasferimento di rete molto bassa di qualcosa da 50 a 100 kB / s, che avrebbe richiesto un'eternità. Così l'ho fermato e ho deciso di provare a fare un gzipping al volo per renderlo molto più piccolo in modo che la quantità da trasferire fosse inferiore. Così ho fatto

dd if=/local/path | gzip > /remote/path/in/local/network/backup.img.gz

Ma ora ottengo qualcosa come 1 MB / s velocità di trasferimento di rete, quindi un fattore da 10 a 20 più veloce. Dopo aver notato questo, ho provato questo su diversi percorsi e file, ed è sempre stato lo stesso.

Perché piping dd attraverso gzip anche aumentare i tassi di trasferimento di un fattore di grandi dimensioni invece di ridurre solo la potenza del flusso di un fattore importante? Mi aspettavo anche una leggera diminuzione dei tassi di trasferimento, a causa del maggiore consumo di CPU durante la compressione, ma ora ho un doppio vantaggio. Non che io non sia felice, ma mi sto solo chiedendo. ;)


1
512 byte era la dimensione standard del blocco per l'archiviazione dei file nei primi Unix. Poiché tutto è un file in Unix / Linux, è diventato il valore predefinito per quasi tutto. Le versioni più recenti della maggior parte delle utilità sono aumentate ma non dd.
DocSalvager

La semplice risposta è quella dd sta uscendo a 1 MB / s ... proprio nell'attesa gzip tubo. Ha ben poco da fare con le dimensioni del blocco.
Tullo_x86

Risposte:


98

dd per impostazione predefinita utilizza una dimensione di blocco molto piccola - 512 byte (!!). Cioè, molte piccole letture e scritture. Sembra che dd, utilizzato in modo ingenuo nel primo esempio, stava generando un gran numero di pacchetti di rete con un payload molto piccolo, riducendo così il throughput.

D'altro canto, gzip è abbastanza intelligente da fare I / O con buffer più grandi. Cioè, un numero minore di grandi scritture sulla rete.

Puoi provare dd di nuovo con un più grande bs= parametro e vedi se funziona meglio questa volta?


19
Grazie, ho provato la copia diretta senza gzip e un blocco di bs=10M - & gt; trasferimento di rete veloce di qualcosa di 3 o 4 MB / s. Blocchi più alti + gzip non ha cambiato nulla rispetto a small blocksize + gzip.
Foo Bar

7
Se vuoi vedere quali alte dimensioni dei blocchi prova un altro dd dopo il gzip.
Joshua

Gzip sta facendo il proprio buffer di output o usa solo stdio?
Barmar

@Barmar Se sto leggendo la fonte correttamente, semplicemente write(3) s al buffer.

@CongMa puoi anche provare a usare pigz invece di gzip, funzionerà ancora più velocemente
GioMac

4

Un po 'tardi ma potrei aggiungere ...

In un'intervista mi è stato chiesto una volta quale sarebbe il metodo più veloce per la clonazione dei dati bit per bit e di grossa risposta con l'uso di dd o dc3dd ( DoD finanziato ). L'intervistatore ha confermato che tubazioni dd a dd è più efficiente, come questo semplicemente permette lettura / scrittura simultanea o in termini di programmatore stdin/stdoutquindi, in definitiva, raddoppiando le velocità di scrittura e dimezzando i tempi di trasferimento.

dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb

0

Cong è corretto. Stai eseguendo lo streaming dei blocchi dal disco non compresso a un host remoto. L'interfaccia di rete, la rete e il server remoto sono la limitazione. Per prima cosa devi aumentare le prestazioni di DD. La specifica di un parametro bs = che si allinea con la memoria del buffer dei dischi otterrà il maggior numero di prestazioni dal disco. Ad esempio, bs = 32M. Questo riempirà quindi il buffer di gzip allo sata o sas line rate strait dal buffer delle unità. Il disco sarà più incline al trasferimento sequenziale dando migliori risultati. Gzip comprimerà i dati in streaming e li invierà alla tua posizione. Se si utilizza NFS che consentirà la trasmissione di nfs è minima. Se si utilizza SSH, si incorpora l'incapsulamento SSH e l'overhead di crittografia. Se usi netcat, non hai la crittografia in testa.


0

Presumo qui che la "velocità di trasferimento" a cui ti riferisci sia segnalata da dd. Questo in realtà ha senso, perché dd in realtà sta trasferendo 10 volte la quantità di dati al secondo ! Però, dd non viene trasferito tramite la rete - tale lavoro viene gestito da gzip processi.

Qualche contesto: gzip consumerà i dati dalla sua pipe di input alla stessa velocità con cui può cancellare il suo buffer interno. La velocità a cui gzip Il buffer svuota dipende da alcuni fattori:

  • La larghezza di banda di scrittura I / O (che è strozzata dalla rete ed è rimasta costante)
  • L'I / O legge la larghezza di banda (che sarà molto più alta di 1MB / s in lettura da un disco locale su una macchina moderna, quindi non è un probabile collo di bottiglia)
  • Il suo rapporto di compressione (che assumerò con il tuo 10x di accelerazione intorno al 10%, indicando che stai comprimendo un tipo di testo altamente ripetitivo come un file di registro o qualche XML)

Quindi in questo caso, la rete può gestire 100kB / s, e gzip sta comprimendo i dati intorno a 10: 1 (e non viene col-collo di bottiglia dalla CPU). Ciò significa che mentre emette 100kB / s, gzip può consumare 1 MB / s, e il tasso di consumo è quello che dd posso vedere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.