tar -xf desempenho para muitos arquivos

2

Considere as duas abordagens a seguir para armazenar um diretório com muitos (vários milhares) de arquivos pequenos em um tarball:

  1. Armazena todos os arquivos no root do tarball
  2. Armazene o próprio diretório no tarball, com os arquivos dentro do diretório.

Isso teria algum efeito de desempenho na rapidez com que o tar é descompactado ( tar -xf )?

Eu posso imaginar que a segunda abordagem poderia ser mais rápida (possivelmente muito mais rápida), mas não estou ciente de como o tar funciona exatamente; daí a minha pergunta.

Observações:

  • A mesma pergunta pode ser solicitada para o empacotamento ( tar -cf ), mas isso é de menor importância para mim.
  • Claro que posso fazer alguns testes, mas gostaria de alguma explicação teórica se for realmente mais rápido.
por Roel Van Zeebroeck 01.09.2016 / 09:05

3 respostas

2

Não é uma resposta teórica, mas eu pensei em fazer os testes. Eu tenho um blade Dell 1955 rodando FreeBSD 10.3 - então isso pode ser específico para o bsdtar. Eu criei dois sistemas de arquivos ZFS para manter as coisas separadas ( /zroot/tar1 e /zroot/tar2 ) e, em seguida, gerou 4000 arquivos de 1 MB com conteúdo aleatório usando o seguinte:

for i in {1..4000}; do
    dd if=/dev/urandom of=/zroot/tar1/tar_test.$i bs=1M count=1
done

Eu então copiei estes 4000 arquivos para /zroot/tar2/mytar (então usamos exatamente os mesmos dados de cada vez), com "mytar" sendo um diretório.

Primeiro no sistema de arquivos com todos os arquivos "soltos", eu arquivei todos os arquivos, depois os removi (deixando apenas o arquivo tar), depois desarquei-os. Eu fiz isso cinco vezes e os horários são mostrados abaixo:

tar cf 1.tar *  0.76s user 16.98s system 6% cpu 4:52.68 total
tar cf 1.tar *  0.74s user 16.51s system 5% cpu 4:51.63 total
tar cf 1.tar *  0.94s user 16.19s system 5% cpu 4:55.50 total
tar cf 1.tar *  0.82s user 16.15s system 5% cpu 4:52.72 total
tar cf 1.tar *  0.69s user 16.22s system 5% cpu 4:52.00 total

tar xf 1.tar  0.44s user 10.52s system 3% cpu 4:54.92 total
tar xf 1.tar  0.39s user 10.67s system 3% cpu 5:03.59 total
tar xf 1.tar  0.39s user 10.51s system 3% cpu 4:52.85 total
tar xf 1.tar  0.46s user 10.45s system 3% cpu 5:01.28 total
tar xf 1.tar  0.44s user 10.59s system 3% cpu 5:01.29 total

Após a última extração, eu removi o arquivo tar e mudei para /zroot/tar2 , onde realizei os mesmos testes novamente, só que desta vez em um diretório contendo os mesmos 4000 arquivos:

tar cf 2.tar mytar  0.72s user 16.51s system 5% cpu 5:25.84 total
tar cf 2.tar mytar  0.61s user 16.19s system 5% cpu 5:18.19 total
tar cf 2.tar mytar  0.68s user 16.14s system 5% cpu 5:01.50 total
tar cf 2.tar mytar  0.65s user 15.87s system 5% cpu 4:41.64 total
tar cf 2.tar mytar  0.68s user 16.71s system 5% cpu 5:07.72 total

tar xf 2.tar  0.42s user 10.39s system 3% cpu 4:57.50 total
tar xf 2.tar  0.41s user 10.41s system 3% cpu 4:50.07 total
tar xf 2.tar  0.47s user 10.26s system 3% cpu 4:57.25 total
tar xf 2.tar  0.58s user 10.50s system 3% cpu 5:00.45 total
tar xf 2.tar  0.40s user 11.34s system 4% cpu 4:50.24 total

Com os tempos médios, obtemos o seguinte:

+===========+=========+===========+
|           |  Loose  | Directory |
+===========+=========+===========+
| Archive   | 4:52.91 | 5:06.97   |
+-----------+---------+-----------+
| Unarchive | 4:58.79 | 4:55.1    |
+-----------+---------+-----------+

Assim, podemos ver que o uso de um diretório melhora marginalmente o desarquivamento dos arquivos, com uma penalidade ligeiramente maior no arquivamento inicial.

Eu fiz a mesma coisa novamente, mas usei treliça para obter um resumo de cada operação, calculando a média do tempo total gasto em syscalls que obtivemos:

+===========+=======+===========+
|           | Loose | Directory |
+===========+=======+===========+
| Archive   | 04:43 | 04:58     |
+-----------+-------+-----------+
| Unarchive | 04:56 | 04:50     |
+-----------+-------+-----------+

A maior parte do tempo é gasto no syscall read () (novamente, em média):

+===========+=======+===========+
|           | Loose | Directory |
+===========+=======+===========+
| Archive   | 03:53 | 04:07     |
+-----------+-------+-----------+
| Unarchive | 04:37 | 04:36     |
+-----------+-------+-----------+

Ao desarquivar, as maiores vitórias vêm de uma combinação de chamadas read () mais rápidas e chamadas lstat () mais rápidas (lstat é semelhante a stat, mas se o arquivo é um link simbólico, ele não é seguido, em vez disso, retorna informações sobre o link simbólico).

Aqui estão os tempos de lstat (), em média:

+-------+-------+-----------+
|       | Loose | Directory |
+-------+-------+-----------+
| lstat |  8.57 |      0.97 |
+-------+-------+-----------+ 

Não tenho certeza se isso ajuda você em tudo. Mas, depois de ter ficado intrigado em sua pergunta por ter feito um pouco de pesquisa, pensei em compartilhar o que eu tinha para ver se alguém poderia ir mais longe.

Aqui está um link para os arquivos de resumo de cada execução , caso sejam de interesse .

Devido ao tamanho dos traços completos (~ 50MB), estou com dificuldades para fazer o upload deles em qualquer lugar persistente on-line (paste2.org/pastebin/etc).

    
por 06.09.2016 / 12:09
1

Isso depende muito do sistema de arquivos que você está usando. Um diretório simples ficará lento no ext2 e em outros sistemas de arquivos mais antigos que precisam de consultas O (n) para verificar se existe uma entrada de diretório de um nome específico. ext3 / 4 e outros sistemas de arquivos modernos usam índices baseados em árvore para diretórios maiores, então eles só precisam de tempo de pesquisa O (log n)

Same question can be asked for packaging (tar -cf) but this is of less importance to me.

Por outro lado, a criação de alcatrão depende em grande parte do IO do disco e se a implementação faz readaheads. Arquivos pequenos incorrem em muitas leituras aleatórias e leitura de arquivo único não funciona efetivamente em arquivos pequenos. Eu escrevi fastar como uma implementação especializada para este caso de uso que otimiza a ordem na qual os arquivos são lidos e realiza leituras antecipadas em vários arquivos.

    
por 02.07.2017 / 14:36
0

A diferença no tempo de extração não é significativa em comparação com o tempo total que a extração leva, pelo menos em uma escala (milhares de arquivos). O formato tar é surpreendentemente simples: é basicamente uma concatenação de cabeçalho e arquivo, cabeçalho e arquivo. Então, quando você extrai, o tar apenas extrai os dados. Em particular, ele não se importa se está sobrescrevendo um arquivo existente, por isso não queima a verificação do tempo. (tarballs com caminhos absolutos são tratados de forma ligeiramente diferente, mas isso é uma prática ruim de qualquer maneira).

    
por 02.07.2017 / 16:30

Tags