Acelerar a cópia de arquivos pequenos 1000000

7

Tenho arquivos de 4 a 20 kb em um diretório. Eu preciso copiar esse diretório. Mas parece que tenho que fazer uma busca por cada arquivo, então isso leva um bom tempo.

Existe alguma maneira de acelerar isso?

Atualmente, estou pensando que, se eu conseguisse os blocos de disco que esses arquivos ocupam, eu poderia ordená-los, mesclar os blocos que estavam próximos (dado que a leitura sequencial é mais rápida do que procurar) e ler esses blocos. estavam no cache de RAM (tenho 32 GB de RAM) antes de fazer a cópia.

Mas para que isso funcione eu preciso de uma maneira de identificar em quais blocos os arquivos estão.

Estou usando o EXT4 em um dispositivo magnético (ou seja, não SSD).

Editar:

Isso deve funcionar, mas não funciona:

ls |
parallel -IOO --pipe "sudo parallel -j100 hdparm --fibmap {}'|tail -n +5'" |
sort -nk 2 | 
perl -ane 'if($u+10000 < $F[1]) { print "$l ",($u-$l),"\n"; $l=$F[1] } $u=$F[2]' |
sudo parallel --colsep ' ' dd if=/dev/sda1 skip={1} bs=512 count={2} '| cat >/dev/null'

Ao testá-lo em um arquivo grande, ele não armazena em cache o arquivo.

Editar2:

Aqui estão alguns benchmarks. O cache foi liberado ( echo 3 >/proc/sys/vm/drop_caches ) entre cada execução. Medições feitas com iostats -dkx 5 .

rsync -Hav foo/ bar/: 1800 KB/s
cp -a foo/ bar/: 3600 KB/s
cat sort-by-inode | parallel -j1 -X cp foo/{} bar/: 5000 KB/s
cat sort-by-inode | shuf | parallel -j1 -X cp foo/{} bar/: 3000 KB/s
cat sort-by-inode | shuf | parallel -j10 -X cp foo/{} bar/: 7000 KB/s
cat sort-by-inode | parallel -j10 -X cp foo/{} bar/: 8000 KB/s
cat sort-by-inode | parallel -j100 -X cp foo/{} bar/: 9000 KB/s
cat sort-by-inode | parallel -j500 -X cp foo/{} bar/: 10000 KB/s

Então, o que podemos aprender com isso?

Parece que ordenar por inode é uma boa ideia. Mas parece que paralelizar vários cp impulsiona ainda mais o desempenho. Vale ressaltar que a fonte foo/ é um disco magnético, então isso ataca o mito de que paralelizar E / S em um único fuso não acelera a E / S: paralelizar claramente e consistentemente acelera a cópia aqui.

    
por Ole Tange 13.04.2014 / 12:13

3 respostas

7

Supondo que

  • entradas retornadas por readdir não são classificadas pelo número de inode
  • a leitura de arquivos na ordem inode reduz o número de operações de busca
  • o conteúdo da maioria dos arquivos está na alocação inicial de 8k (uma otimização ext4) que também deve render menos operações de busca

você pode tentar acelerar a cópia através da cópia de arquivos na ordem inode.

Isso significa usar algo assim:

$ cd /mnt/src
$ ls -U -i | sort -k1,1 -n | cut -d' ' -f2- > ~/clist
$ xargs cp -t /mnt2/dst < ~/clist
    
por 13.04.2014 / 15:11
3

tar lida com hardlinks sozinho.

cd "$srcdir" ; tar --hard-dereference -cf - ./* |
    tar -C"${tgtdir}" -vxf -

Dessa forma, você só tem os dois tar processos e não precisa continuar invocando cp vezes sem conta.

    
por 13.04.2014 / 17:21
1

Em uma veia semelhante à resposta @ maxschlepzig , você pode analisar a saída de filefrag para classificar arquivos na ordem em que seus primeiros fragmentos aparecem no disco:

find . -maxdepth 1 -type f |
  xargs -d'\n' filefrag -v |
  sed -n '
    /^   0:        0../ {
      s/^.\{28\}\([0-9][0-9]*\).*//
      h
      }
    / found$/ {
      s/:[^:]*$//
      H
      g
      s/\n/ /p
      }' |
    sort -nk 1,1 |
    cut -d' ' -f 2- |
    cpio -p dest_dir

MMV com o script sed acima, portanto, teste com cuidado.

Caso contrário, o que você fizer, filefrag (parte de e2fsprogs ) será muito mais rápido de usar do que hdparm , pois pode levar vários argumentos de arquivo. Apenas a sobrecarga de executar hdparm 1,000,000 vezes adicionará muita sobrecarga.

Além disso, provavelmente não seria tão difícil escrever um script perl (ou programa C), para um FIEMAP ioctl para cada arquivo, criar uma matriz ordenada dos blocos que devem ser copiados e os arquivos pertencem e copiam tudo em ordem, lendo o tamanho de cada bloco do arquivo correspondente (tenha cuidado para não ficar sem os descritores de arquivos).

    
por 13.04.2014 / 22:59