Estou tentando fazer alguns testes em termos de tamanho de bloco do sistema de arquivos para identificar algum gargalo potencial em um trabalho de grade devido a IO ruim. Percebo muito incremento de arquivo pequeno de 8096 B durante o trabalho enquanto o tamanho do bloco do FS é:
stat -fc %s /my/filesytem
1048576
O que está longe de ser o ideal. Para simular tal comportamento criei dois pequenos arquivos aleatórios de 1GB a 20GB com dd
e /dev/urandom
como fonte, e tentei este código python:
#!/bin/python
bsize=8096
print('File random.20g1')
print(strftime("%Y-%m-%d_%H:%M:%S"))
f1= open('random.20g1','rb')
f2= open('random.20g1.dest','wb')
while True:
b = f1.read(bsize)
if b:
f2.write(b)
else:
break
print(strftime("%Y-%m-%d_%H:%M:%S"))
E eu tentei o mesmo com bsize=1048576
.
Primeiro observo uma pequena diferença de tempo de leitura/gravação de 4 segundos entre um tamanho de bloco de 8096 e 1048576 (4 segundos a menos para o tamanho de bloco grande).
Este primeiro resultado foi promissor mas depois de mais testes, como aumentar o tamanho do arquivo para 20GB ou fazer o mesmo com 10 arquivos de GB observo sempre a mesma diferença de 4/3 segundos em termos de desempenho e o ganho nunca escala qualquer que seja o Arquivo.
Estou fazendo algo errado no meu procedimento de teste ou parece bom para você?
Eu teria esperado alguma melhora no aumento do tamanho do arquivo, por exemplo.
Este código
está fazendo leituras e gravações sequenciais
bsize
- dado qualquer , ele lê os primeirosbsize
bytes, grava-os no arquivo de destino, depois lê os segundosbsize
bytes, anexa-os ao arquivo de destino, ...Seu sistema operacional os armazenará no cache da página e poderá até fazer a leitura antecipada e o pré-buffer dos dados de entrada como @StephenKitt mencionado nos comentários. Assim, as chamadas de IO subjacentes para o disco real acabarão reunidas em pedaços muito maiores, provavelmente o 1 MB que você mencionou.
A pequena diferença que você vê no desempenho é quase certamente devido apenas porque, quando você usa um menor
bsize
, seu processo precisa fazer mais chamadas de sistema no kernel para realmente mover os dados.Portanto, é quase certo que você não vê muita diferença quando altera
bsize
seu código de teste, mas não é realmente possível dizer com certeza sem muito mais detalhes sobre seu sistema.MAIS...
O que você está fazendo é efetivamente idêntico ao
Se você realmente usar
dd
, você pode fazer muito mais coisas para testar o IO do disco (basta olhar para a página man - você pode usar o IO direto para ignorar o cache da página, por exemplo), mas no final, o IO testando você pode fazer comdd
é bastante limitado, pois será sequencial.dd
mostrará a você o melhor desempenho de E/S, mas não pode simular muitas cargas de trabalho do mundo real que revelam as desvantagens do desempenho de E/S.Você precisa determinar mais sobre o padrão de E/S que seu trabalho de grade realmente usa - está fazendo leituras/gravações sequenciais como em seu teste, ou está fazendo leituras e/ou gravações aleatórias onde procura no(s) arquivo(s) para um arquivo efetivamente aleatório local antes de fazer o IO? As operações de E/S aleatórias são muito mais exigentes em um sistema de arquivos e hardware de disco subjacente - especialmente discos giratórios. Sistemas que podem mover centenas de MB/s de fluxo de E/S sequencial podem ser reduzidos a literalmente um punhado de kilobytes por segundo por operações aleatórias de E/S de pequeno porte. Especialmente se você estiver usando discos SATA SLOW de 5.000 RPM.
Pode ficar muito ruim quando pessoas que não entendem de sistemas de arquivos e matrizes RAID configuram armazenamento. O tamanho de bloco do sistema de arquivos de 1 MB que você mencionou com certeza parece que você pode estar lidando com uma configuração do sistema de armazenamento sob um paradigma equivocado de "maior é sempre mais rápido".
Misturar um paradigma "maior é sempre mais rápido" com coisas como matrizes RAID5/6 e IO de bloco pequeno aleatório (como o que seu trabalho de grade parece estar fazendo) pode ser uma receita para um desempenho de IO totalmente horrível.
Você pode usar
strace
no Linux para obter as chamadas de sistema reais que seus trabalhos fazem. Procure por chamadas comolseek
,write
,read
epwrite
epread
. Isso lhe dirá o padrão de IO real que seu(s) trabalho(s) faz.Depois de obter seu padrão de E/S, você pode testar e comparar o desempenho de armazenamento real sob esse padrão com uma ferramenta que chega perto de duplicar esse padrão. Você provavelmente precisa de uma ferramenta que escreva ou leia de/para locais aleatórios. Novamente, assumindo o Linux, você pode começar com o
fio
. Você provavelmente precisará usar as opções de leitura/gravação aleatórias.