Spostando 2 TB (10 mil file + dirs), qual è il mio collo di bottiglia?


21

sfondo

Mi ha esaurito lo spazio su /home/datae necessità di trasferire /home/data/repoa /home/data2.

/home/data/repocontiene 1M dirs, ognuno dei quali contiene 11 dir e 10 file. Ha un totale di 2 TB.

/home/dataè su ext3 con dir_index abilitato. /home/data2è su ext4. Esecuzione di CentOS 6.4.

Presumo che questi approcci siano lenti a causa del fatto che repo/ha 1 milione di dir direttamente sotto di esso.


Tentativo 1: mvè veloce ma viene interrotto

Potrei fare se questo fosse finito:

/home/data> mv repo ../data2

Ma è stato interrotto dopo il trasferimento di 1,5 TB. Stava scrivendo a circa 1 GB / min.

Tentativo 2: ricerca per rsyncindicizzazione dopo 8 ore dall'elenco dei file di costruzione

/home/data> rsync --ignore-existing -rv repo ../data2

Ci sono volute diverse ore per costruire la "lista dei file incrementali" e poi trasferire a 100 MB / min.

Lo annullo per provare un approccio più veloce.

Tentativo 3a: si mvlamenta

Test su una sottodirectory:

/home/data/repo> mv -f foobar ../../data2/repo/
mv: inter-device move failed: '(foobar)' to '../../data2/repo/foobar'; unable to remove target: Is a directory

Non sono sicuro di cosa si tratti di un errore, ma forse cpmi può salvare.

Tentativo 3b: cpnon arriva da nessuna parte dopo 8 ore

/home/data> cp -nr repo ../data2

Legge il disco per 8 ore e decido di annullarlo e tornare a rsync.

Tentativo 4: ricerca per rsyncindicizzazione dopo 8 ore dall'elenco dei file di costruzione

/home/data> rsync --ignore-existing --remove-source-files -rv repo ../data2

Pensavo --remove-source-filesche avrebbe potuto renderlo più veloce se avessi iniziato la pulizia ora.

Sono necessarie almeno 6 ore per compilare l'elenco dei file, quindi trasferisce a 100-200 MB / min.

Ma il server è stato caricato durante la notte e la mia connessione è stata chiusa.

Tentativo 5: SOLO 300 GB A SINISTRA PER MUOVERSI PERCHÉ È COSÌ DOLORE

/home/data> rsync --ignore-existing --remove-source-files -rvW repo ../data2

Interrotto di nuovo. La -Wquasi sembrava di fare "l'invio di elenco di file incrementale" più veloce, che per la mia comprensione non dovrebbe avere un senso. Indipendentemente da ciò, il trasferimento è terribilmente lento e mi sto arrendendo.

Tentativo 6: tar

/home/data> nohup tar cf - . |(cd ../data2; tar xvfk -)

Fondamentalmente tentando di ricopiare tutto ma ignorando i file esistenti. Deve superare 1,7 TB di file esistenti ma almeno sta leggendo a 1,2 GB / min.

Finora, questo è l'unico comando che dà gratificazione istantanea.

Aggiornamento: interrotto di nuovo, in qualche modo, anche con nohup ..

Tentativo 7: harakiri

Sto ancora discutendo questo

Tentativo 8: script 'unisci' con mv

La directory di destinazione aveva circa 120.000 directory vuote, quindi ho corso

/home/data2/repo> find . -type d -empty -exec rmdir {} \;

Script Ruby:

SRC  = "/home/data/repo"
DEST = "/home/data2/repo"

`ls #{SRC}  --color=never > lst1.tmp`
`ls #{DEST} --color=never > lst2.tmp`
`diff lst1.tmp lst2.tmp | grep '<' > /home/data/missing.tmp`

t = `cat /home/data/missing.tmp | wc -l`.to_i
puts "Todo: #{t}"

# Manually `mv` each missing directory
File.open('missing.tmp').each do |line|
  dir = line.strip.gsub('< ', '')
  puts `mv #{SRC}/#{dir} #{DEST}/`
end

FATTO.


Hai ragione, deve trovare ed enumerare ogni directory e 1 milione di directory sarà doloroso.
— cybernard,

2
Guarda il lato positivo ... se fosse Windows, non potresti nemmeno avere un milione di sottodirectory e avere ancora un sistema operativo che funziona. :)
— Jack,

1
@ Tim, perché non lo fai di mvnuovo? In teoria mveliminerà un file di origine solo se il file di destinazione è stato completamente copiato, quindi dovrebbe funzionare correttamente. Inoltre, hai accesso fisico alla macchina o è fatto attraverso una sshconnessione?
— terdon,

5
No non può. mvnon perdona, se continui a disconnetterti potresti perdere i dati e nemmeno conoscerli. Come hai detto che lo stai facendo ssh, ti consiglio vivamente di utilizzare screene staccare. Abilita la registrazione e tieni traccia di quello. Se stai usando verbose ci vorrà solo più tempo. Prova ancheiotop
— sopraccigliare il

2
@justbrowsing - Buona chiamata screen. Mi chiedevo di essere prolisso, ma credo sia troppo tardi per riavviare taradesso. Ed iotopè stata la mia utility preferita negli ultimi giorni :)
— Tim

Risposte:


6

Hai mai sentito parlare di dividere grandi compiti in compiti più piccoli?

/ home / data / repo contiene 1M di directory, ognuna delle quali contiene 11 directory e 10 file. Ha un totale di 2 TB.

rsync -a /source/1/ /destination/1/
rsync -a /source/2/ /destination/2/
rsync -a /source/3/ /destination/3/
rsync -a /source/4/ /destination/4/
rsync -a /source/5/ /destination/5/
rsync -a /source/6/ /destination/6/
rsync -a /source/7/ /destination/7/
rsync -a /source/8/ /destination/8/
rsync -a /source/9/ /destination/9/
rsync -a /source/10/ /destination/10/
rsync -a /source/11/ /destination/11/

(...)

Tempo di pausa caffè


1
Il vantaggio che sto vagamente sottolineando è che si monitorare i progressi in piccole parti manualmente in modo che la ripresa l'operazione avrà lesss tempo se una parte viene interrotta (perché non si sa quali fasi sono state completate con successo).
— Ярослав Рахматуллин,

Questo è fondamentalmente quello che alla fine ho fatto, tranne con mv. Sfortunato non c'è incontro strumento mved rsynca metà strada.
— Tim

4

Questo è ciò che sta succedendo:

  • Inizialmente rsync costruirà l'elenco dei file.
  • La creazione di questo elenco è molto lenta, a causa di un ordinamento iniziale dell'elenco dei file.
  • Questo può essere evitato usando ls -f -1 e combinandolo con xargs per creare l'insieme di file che verrà utilizzato da rsync o reindirizzando l'output su un file con l'elenco dei file.
  • Passando questo elenco a rsync anziché alla cartella, rsync inizierà a funzionare immediatamente.
  • Questo trucco di ls -f -1 su cartelle con milioni di file è perfettamente descritto in questo articolo: http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang/

1
Puoi fare un esempio di come usare ls con rsync? Ho una situazione simile ma non identica. Sulla macchina AI ho rsyncd in esecuzione e un grande albero di directory che voglio trasferire alla macchina B (in realtà, il 90% della directory è già in B). Il problema è che devo farlo usando una connessione mobile instabile che spesso cade. Trascorrere un'ora a costruire l'elenco dei file ogni volta che riavvio è abbastanza inefficiente. Inoltre, B è dietro NAT che non controllo, quindi è difficile connettere A -> B, mentre B -> A è facile.
— db

Accetto con @db. Se si potesse dare un esempio, ciò renderebbe questa risposta molto più utile.
— redfox05

1

Anche se rsync è lento (perché è lento? Forse -z ti aiuterà) sembra che tu ne sia stato spostato molto, quindi puoi continuare a provare:

Se hai usato --remove-source-files, potresti quindi seguire rimuovendo le directory vuote. --remove-source-files rimuoverà tutti i file, ma lascerà lì le directory.

Assicurati solo di NON usare --remove-source-files con --delete per fare più passaggi.

Anche per una maggiore velocità puoi usare --inplace

Se vieni cacciato perché stai provando a farlo da remoto su un server, vai avanti ed eseguilo all'interno di una sessione 'schermo'. Almeno in questo modo puoi lasciarlo correre.

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.