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.