Movendo 2TB (10 mil arquivos + dirs), qual é o meu gargalo?

20

Antecedentes

Eu ficou sem espaço em /home/data e preciso transferir /home/data/repo para /home/data2 .

/home/data/repo contém 1M dirs, cada um contendo 11 dirs e 10 arquivos. Totaliza 2TB.

/home/data está no ext3 com dir_index ativado. /home/data2 está no ext4. Rodando o CentOS 6.4.

Suponho que essas abordagens são lentas devido ao fato de que repo/ tem 1 milhão de diretórios diretamente abaixo dela.

Tentativa 1: mv é rápido, mas é interrompido

Eu poderia ser feito se isso tivesse terminado:

/home/data> mv repo ../data2

Mas foi interrompido após a transferência de 1,5 TB. Estava escrevendo a cerca de 1GB / min.

Tentativa 2: rsync rastreia após 8 horas da criação da lista de arquivos

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

Demorou várias horas para criar a 'lista de arquivos incremental' e, em seguida, transfere a 100MB / min.

Eu cancelo para tentar uma abordagem mais rápida.

Tentativa 3a: mv reclama

Teste-o em um subdiretório:

/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

Eu não tenho certeza sobre o que é esse erro, mas talvez cp possa me ajudar.

Tentativa 3b: cp não chega a lugar algum depois de 8 horas

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

Ele lê o disco por 8 horas e eu decido cancelá-lo e voltar ao rsync.

Tentativa 4: rsync rastreia após 8 horas da criação da lista de arquivos

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

Eu usei --remove-source-files pensando que isso poderia ser mais rápido se eu começar a limpeza agora.

Leva pelo menos 6 horas para criar a lista de arquivos e, em seguida, transfere a 100-200MB / min.

Mas o servidor ficou sobrecarregado durante a noite e minha conexão foi fechada.

Tentativa 5: THERES SOMENTE 300GB DEIXAR DE MOVER POR QUE ISTO É TÃO DOLOROSO

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

Interrompido novamente. O -W quase pareceu "enviar lista de arquivos incremental" mais rápido, o que, para mim, não deveria fazer sentido. Independentemente disso, a transferência é terrivelmente lenta e estou desistindo disso.

Tentativa 6: tar

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

Basicamente tentando copiar tudo, mas ignorando os arquivos existentes. Tem que percorrer 1,7 TB de arquivos existentes, mas pelo menos está lendo a 1,2 GB / min.

Até agora, este é o único comando que dá gratificação instantânea.

Atualização: interrompida novamente, de alguma forma, mesmo com nohup ..

Tentativa 7: harakiri

Ainda debatendo esse aqui

Tentativa 8: 'mesclagem' com script com mv

O diretório de destino tinha cerca de 120k dirs vazios, então eu corri

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

Script em 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

FEITO.

    
por Tim 06.09.2013 / 17:48

3 respostas

5

Já ouviu falar em dividir grandes tarefas em tarefas menores?

/home/data/repo contains 1M dirs, each of which contain 11 dirs and 10 files. It totals 2TB.

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 de intervalo para o café.

    
por 18.09.2013 / 03:05
4

Isso é o que está acontecendo:

  • Inicialmente, o rsync cria a lista de arquivos.
  • A criação dessa lista é muito lenta, devido a uma classificação inicial da lista de arquivos.
  • Isso pode ser evitado usando ls -f -1 e combinando-o com xargs para construir o conjunto de arquivos que o rsync usará, ou redirecionando a saída para um arquivo com a lista de arquivos.
  • Passar essa lista para rsync em vez da pasta, fará com que o rsync comece a funcionar imediatamente.
  • Esse truque de ls -f -1 sobre pastas com milhões de arquivos é descrito perfeitamente neste artigo: link
por 31.03.2014 / 12:37
1

Mesmo que o rsync seja lento (por que é lento? talvez -z ajudará), parece que você mudou muito, então você pode continuar tentando:

Se você usou --remove-source-files, você poderia então seguir removendo diretórios vazios. --remove-source-files removerá todos os arquivos, mas deixará os diretórios lá.

Assegure-se de que NÃO use --remove-source-files com --delete para fazer várias passagens.

Também para aumentar a velocidade, você pode usar --inplace

Se você está sendo expulso porque está tentando fazer isso remotamente em um servidor, execute-o em uma sessão de "tela". Pelo menos assim você pode deixar isso acontecer.

    
por 14.09.2013 / 05:35