Fai scrivere Linux sul filesystem di rete contemporaneamente alle letture del disco locale


17

Sommario

Come è possibile configurare Linux per leggere sia da un disco / file system locale che da scrivere su una condivisione di rete contemporaneamente, invece di leggere mentre nessun dato passa sulla rete, quindi inviare quei dati sulla rete mentre il disco locale è inattivo?

È molto più veloce leggere e scrivere contemporaneamente invece di eseguire solo un'operazione e poi l'altra in modo alternato.

Dettagli

Sto trasferendo una grande quantità di dati dai dischi locali su una macchina Linux a un dispositivo NAS.

Sto usando rsyncper copiare basicamente /srv/datain /mnt/nas, che è il monte a CIFS.

È iniziato bene, leggendo a 100 MB / sec e scrivendo sul NAS a 100 MB / sec (limite della rete gigabit), con la lettura e la scrittura simultanee.

Tuttavia ora, poche ore dopo, sto scoprendo che sta leggendo dal disco locale, quindi interrompendo la lettura mentre scrive sul NAS, quindi quando non ci sono più dati da scrivere sul NAS, riprende la lettura dal disco ancora. La rete è inattiva durante la lettura del disco e il disco è inattivo mentre la rete è in uso.

Inutile dire che leggere 200 MB e poi scrivere 200 MB richiede molto più tempo che leggere e scrivere quei 200 MB contemporaneamente.

Come posso configurare il kernel in modo tale che si attacchi al comportamento precedente di lettura e scrittura contemporaneamente, piuttosto che alternare tra lettura e scrittura, eseguendo solo un'operazione alla volta?

Alcune osservazioni: quando il disco locale legge a 100 + MB / sec tutto sembra accadere in parallelo bene, ma una volta che il disco rallenta (sembra andare a soli 20 MB / sec ora per qualche motivo) è allora che questo legge / scrive il passaggio sembra avvenire.

Posso anche eseguire syncmanualmente ogni pochi secondi per far sì che le scritture avvengano in parallelo con le letture (anche se ovviamente a velocità ridotta) tuttavia inserendo syncun whileciclo in modo che funzioni ogni cinque secondi non sembra la soluzione giusta ...

Il kernel sembra memorizzare nella cache circa 1 GB di dati e poi scriverli sulla rete il più velocemente possibile - il che va bene - semplicemente non capisco perché il disco lento debba smettere di essere letto mentre i dati vengono inviati via Rete.


1
La maggior parte degli strumenti unix non è assolutamente ottimizzata per la larghezza di banda in questo senso, non è rsync, nemmeno un semplice cp. Sono app a thread singolo che utilizzano l'IO bloccante.
Peter - Ripristina Monica il

1
Da qualche parte circa 100 MB / s è anche ciò che ci si può aspettare di vedere sui moderni comuni HDD rotazionali a 7200 rpm in carichi di lavoro puramente sequenziali. Si riduce una volta che inizi a cercare, ad esempio per aggiornare i metadati o se il file system è frammentato, perché diventi legato a IOPS.
un CVn il

puoi installare rsync sul NAS?
Jasen,

Risposte:


27

Dopo qualche indagine in più, sembra che questo problema sia meno correlato al kernel e più su come rsynce CIFS interagiscono.

Per quanto ne so, ciò che sta accadendo è che quando si rsyncchiude il file di destinazione, CIFS (e probabilmente qualsiasi file system di rete) assicura che il file sia completamente scaricato e scritto sul disco remoto prima che closeritorni syscall. Questo per garantire a qualsiasi applicazione che, una volta completata l'operazione di chiusura, il file sia stato completamente salvato e non vi siano rischi di ulteriori errori che potrebbero causare la perdita di dati.

Se ciò non avvenisse, sarebbe possibile che un'applicazione chiuda un file, esca pensando che l'operazione di salvataggio sia andata a buon fine, quindi in seguito (forse a causa di un problema di rete) i dati non potrebbero essere scritti dopo tutto, ma a quel punto è troppo tardi perché l'applicazione possa fare qualcosa al riguardo, come chiedere all'utente se desidera invece salvare il file altrove.

Questo requisito significa che ogni volta che rsynctermina la copia di un file, l'intero buffer del disco deve svuotarsi sulla rete prima di rsyncpoter continuare a leggere il file successivo.

Una soluzione alternativa è montare la condivisione CIFS con l'opzione cache=noneche disabilita questa funzione e fa in modo che tutto l'I / O vada direttamente al server. Ciò elimina il problema e consente l'esecuzione in parallelo di letture e scritture, tuttavia uno svantaggio di questa soluzione è che le prestazioni sono leggermente inferiori. Nel mio caso, la velocità di trasferimento in rete scende da 110 MB / sec a 80 MB / sec.

Ciò può significare che se si copiano file di grandi dimensioni, le prestazioni potrebbero essere migliori con il comportamento di lettura / scrittura alternato. Con molti file più piccoli, la disabilitazione della cache comporterà un minor numero di svuotamenti della cache ogni volta che un file viene chiuso, quindi le prestazioni potrebbero aumentare.

Sembra che abbia rsyncbisogno di un'opzione per chiudere i suoi handle di file in un altro thread, quindi può iniziare a leggere il file successivo mentre l'ultimo viene ancora scaricato.

EDIT: ho confermato che cache=noneaiuta sicuramente quando si trasferiscono molti piccoli file (lo porta da 10 MB / sec fino a 80 MB / sec) ma quando si trasferiscono file di grandi dimensioni (1 GB +) si cache=noneriduce il trasferimento da 110 MB / sec agli stessi 80 MB / sec. Ciò suggerisce che il trasferimento lento da molti file di piccole dimensioni riguarda meno la ricerca del disco di origine e di più sull'avere tanti svuotamenti della cache da tutti i file di piccole dimensioni.


2
Che è un problema molto interessante, e grazie per aver pubblicato la spiegazione. rsyncnon leggere il file in un thread diverso (in realtà, diverso processo) perché è progettato in modo che una copia rsyncè in esecuzione su ciascun lato della rete, anche se nel tuo caso entrambe le copie sono sullo stesso lato (e il filesystem si nasconde il fatto che esiste una rete). Immagino che non aiuti, perché il processo del lettore riempie molto rapidamente la pipa mentre il processo del writer sta bloccando un close(). rsyncavrebbe prestazioni migliori se si stesse utilizzando rsyncil cavo, non CIFS.
Celada,

1
Immagino che un'altra soluzione è che non è possibile eseguire rsyncsul NAS sarebbe quella di utilizzare rsyncsulla rete (come rsync -a files localhost:/dest/path) mentre in qualche modo si introduce artificialmente un enorme buffer (come, almeno megabyte) nelle connessioni di rete. Non sono sicuro di come sarebbe il miglior trucco per farlo.
Celada,

@Celada: grazie! Sì, immagino che rsyncl' esecuzione sul box NAS stesso avrebbe risolto anche il problema. Tuttavia, un po 'più complesso (strane autorizzazioni NAS, devo rilasciare collegamenti simbolici, ecc.) Ma se avessi un po' più di dati da copiare varrebbe la pena investire tempo per farlo, penso.
Malvineous,

2
Forse non correlato al tuo caso: ho avuto un problema simile qualche anno fa scrivendo l'output su dump(8)un NAS montato su NFS. Al momento ho diagnosticato il problema come massimizzare la CPU sul NAS, a causa dell'effetto combinato del server NFS e di un firewall in esecuzione sul NAS (il box non era rootato e il firewall non poteva essere completamente disabilitato da l'interfaccia web). Il problema è scomparso quando abbiamo sostituito il NAS con un vecchio PC. FWIW.
Satō Katsura,

@SatoKatsura: Sicuramente una possibilità per i vecchi dispositivi NAS, anche se in quel caso immagino che vedresti un trasferimento complessivo più lento piuttosto che uno instabile come questo? Il mio NAS è un Atom dual-core (~ 2GHz) che si trova a circa il 30% di utilizzo della CPU quando si massimizza una NIC gigabit senza frame jumbo, quindi dovrebbe essere ok lì.
Malvineous,
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.