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

21

fundo

I ficou sem espaço no /home/datae necessidade de transferência /home/data/repopara /home/data2.

/home/data/repocontém 1 milhão de diretórios, cada um contendo 11 diretórios e 10 arquivos. Totaliza 2 TB.

/home/dataestá no ext3 com o dir_index ativado. /home/data2está no ext4. Executando o CentOS 6.4.

Suponho que essas abordagens sejam lentas devido ao fato de repo/ter 1 milhão de dirs 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. Ele estava escrevendo a cerca de 1 GB / min.

Tentativa 2: rsyncrastreia após 8 horas de construção da lista de arquivos

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

Demorou várias horas para criar a 'lista de arquivos incrementais' e depois é transferida a 100 MB / min.

Eu o cancelo para tentar uma abordagem mais rápida.

Tentativa 3a: mvreclama

Testando-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

Não sei ao certo o que é esse erro, mas talvez cppossa me salvar.

Tentativa 3b: cpnão chega a lugar algum após 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: rsyncrastreia após 8 horas de construção da lista de arquivos

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

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

Demora pelo menos 6 horas para criar a lista de arquivos e depois transfere entre 100 e 200 MB / min.

Mas o servidor ficou sobrecarregado da noite para o dia e minha conexão foi fechada.

Tentativa 5: EXISTEM SOMENTE 300 GB PARA MOVER POR QUE ISSO É TÃO DOLORIZADO

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

Interrompido novamente. O -Wquase parecia tornar o "envio da lista de arquivos incrementais" mais rápido, o que, na minha opinião, não faria sentido. Independentemente disso, a transferência é terrivelmente lenta e estou desistindo dessa.

Tentativa 6: tar

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

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

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

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

Tentativa 7: harakiri

Ainda debatendo este

Tentativa 8: 'mesclar' com script com mv

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

/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

FEITO.

Tim
fonte
Você está correto, ele precisa encontrar e enumerar cada diretório e 1 milhão de diretórios será doloroso.
cybernard
2
Olhe para o lado positivo ... se fosse o Windows, você não poderia ter nem um milhão de subdiretórios e ainda terá um sistema operacional que funcione. :)
Jack
11
@ Tim, por que você não acaba de mvnovo? Em teoria mv, somente o arquivo de origem será excluído se o arquivo de destino tiver sido completamente copiado, portanto deve funcionar bem. Além disso, você tem acesso físico à máquina ou isso é feito através de uma sshconexão?
terdon 6/09/13
5
Não, não pode. mvnão perdoa, se você ficar desconectado, poderá perder dados e nem saber. Como você disse que está fazendo isso de novo ssh, eu recomendo usar screene desanexar. Habilite o log e acompanhe esse caminho. Se você estiver usando verbos, levará mais tempo. Também tenteiotop
justbrowsing
2
@justbrowsing - Boa ligação screen. Eu estava pensando em detalhes, mas acho que é tarde demais para reiniciar taragora. E iotoptem sido a minha utilidade favorito para os últimos dias :)
Tim

Respostas:

6

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

/ home / data / repo contém 1 milhão de diretórios, cada um contendo 11 diretórios e 10 arquivos. Totaliza 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/

(...)

Hora do café.

Ярослав Рахматуллин
fonte
11
O benefício que enfatizo vagamente é que você monitora o progresso em pequenas partes manualmente, para que a retomada da tarefa leve menos tempo se uma parte for abortada (porque você sabe quais etapas foram concluídas com êxito).
Ярослав Рахматуллин
Isso é basicamente o que acabei fazendo no final, exceto com mv. Infelizmente, não há reunião de ferramentas mve a rsyncmeio caminho.
Tim
4

Isto é o que está acontecendo:

  • Inicialmente, o rsync criará a lista de arquivos.
  • A criação desta lista é realmente 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 criar o conjunto de arquivos que o rsync usará ou redirecionar a saída para um arquivo com a lista de arquivos.
  • Passar esta lista para o rsync em vez da pasta fará com que o rsync comece a funcionar imediatamente.
  • Esse truque de ls -f -1 em pastas com milhões de arquivos é perfeitamente descrito neste artigo: http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang/
maki
fonte
11
Você pode dar um exemplo de como usar ls com o rsync? Eu tenho uma situação semelhante, mas não idêntica. Na máquina AI, o rsyncd está em execução e uma grande árvore de diretórios que desejo transferir para a máquina B (na verdade, 90% do diretório já está em B). O problema é que tenho que fazer isso usando uma conexão móvel instável que cai frequentemente. Passar uma hora na criação da lista de arquivos toda vez que eu reinicio é bastante ineficiente. Além disso, B está atrás do NAT que eu não controlo, por isso é difícil conectar A -> B, enquanto B -> A é fácil.
db
Concorde com @db. Se um exemplo pudesse ser dado, isso tornaria essa resposta muito mais útil.
redfox05 08/04
1

Mesmo se o rsync for lento (por que é lento? Talvez -z ajudará), parece que você passou muito disso, então você pode continuar tentando:

Se você usou --remove-source-files, poderá fazer o acompanhamento removendo os diretórios vazios. --remove-source-files removerá todos os arquivos, mas deixará os diretórios lá.

Apenas certifique-se de NÃO usar --remove-source-files com --delete para fazer várias passagens.

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

Se você for expulso porque está tentando fazer isso remotamente em um servidor, vá em frente e execute isso dentro de uma sessão de 'tela'. Pelo menos assim, você pode deixá-lo funcionar.

Angelo
fonte