Afinando o teste do VirtFS

Arlindo escreveu um ótimo artigo sobre os testes comparativos de desempenho do NFS e do VirtFS. Isto gerou uma longa discussão na lista de difusão cefala-admin na semana passada. No frigir dos ovos, a escolha recaiu sobre o NFS, principalmente porque o desempenho do rsync com arquivo destino numa partição VirtFS foi catastrófico, por razões que desconhecemos. No presente artigo, estou documentando os aspectos metodológicos que levantei durante a tal discussão, caso a questão volte à pauta no futuro.

Performance/reliability/concurrency: Pick two

Nos testes feitos por Arlindo, a partição VirtFS foi montada com as opções por default. Entretanto, eu descobri que a opção de cache pode ter uma influência enorme no desempenho. Este é o resultado com a opção cache por default:

rlaboiss@NFS:~$ sudo umount /mnt/virtfs
rlaboiss@NFS:~$ sudo mount -t 9p /virtfs /mnt/virtfs -otrans=virtio,version=9p2000.L
rlaboiss@git:~$ dd if=/dev/zero of=/mnt/virtfs/test count=1000 bs=32k
1000+0 records in
1000+0 records out
32768000 bytes (33 MB) copied, 0.653058 s, 50.2 MB/s

Abaixo está o resultado do mesmo teste com a opção cache=loose, para o qual desempenho é multiplicado por 6.6:

rlaboiss@git:~$ sudo umount /mnt/virtfs/
rlaboiss@git:~$ sudo mount -t 9p /virtfs /mnt/virtfs -otrans=virtio,version=9p2000.L,cache=loose
rlaboiss@git:~$ dd if=/dev/zero of=/mnt/virtfs/test count=1000 bs=32k
1000+0 records in
1000+0 records out
32768000 bytes (33 MB) copied, 0.0980486 s, 334 MB/s

A ideia de testar variações do parâmetro de cache veio da documentação do v9fs do kernel Linux. O que é descrito neste documento me lembra o velho dilema dos estudantes, que almejam sempre ter:

  • boas notas
  • vida social
  • oito horas de sono por dia

Apenas dois destes objetivos podem ser alcançados simultaneamente. É como no VirtFS, em que você tem que escolher dois dentre os três objetivos:

  • desempenho
  • confiabilidade
  • concorrência

Com a opção "no cache" por default, perde-se o desempenho. Com cache=loose, perde-se a confiabilidade. Com cache=fscache, perde-se a concorrência. (Nota: o termo "concorrência" significa gestão de acesso simultâneo a um mesmo arquivo por dois processos diferentes.)

Em se tratando de dd, tamanho de bloco é documento

Vocês talvez tenham notado que eu utilizei a opção bs do comando dd nos meus testes acima. O desempenho do dd depende de maneira crítica do tamanho do bloco (512 bytes, por default). Além disso, existe, aparentemente, um tamanho ideal de bloco que depende do hardware do HD.

Eis aqui o teste realizado com o arquivo de destino na partição VirtFS, no qual pode-se observar a existência de um tamanho ótimo de bloco:

rlaboiss@git:~$ sudo umount /mnt/virtfs/
rlaboiss@git:~$ sudo mount -t 9p /virtfs /mnt/virtfs -otrans=virtio,version=9p2000.L,cache=loose
rlaboiss@NFS:~$ for bs in 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1M 2M 4M 8M 16M; do
    speed=$(dd if=/dev/zero of=/mnt/virtfs/test count=10 bs=$bs 2>&1 | grep copied | cut -f3 -d, );
    printf "%5s %8s" $bs $speed;
    echo "";
done
   1k      6.0 MB/s
   2k     16.2 MB/s
   4k     53.7 MB/s
   8k     84.7 MB/s
  16k      178 MB/s
  32k      323 MB/s
  64k      540 MB/s
 128k      583 MB/s
 256k      936 MB/s
 512k      1.3 GB/s
   1M      1.6 GB/s
   2M      1.5 GB/s
   4M      2.2 GB/s
   8M      2.0 GB/s
  16M      590 MB/s

Como Arlindo comentou, é sempre interessante comparar os resultados obtidos no VirtFS com os resultados obtidos quando o arquivo destino está na própria imagem da VM. Ei-los:

rlaboiss@NFS:~$ for bs in 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1M 2M 4M 8M 16M; do
    speed=$(dd if=/dev/zero of=/var/tmp/test count=10 bs=$bs 2>&1 | grep copied | cut -f3 -d, );
    printf "%5s %8s" $bs $speed;
    echo "";
done
   1k      116 MB/s
   2k     99.6 MB/s
   4k      161 MB/s
   8k      288 MB/s
  16k      457 MB/s
  32k      663 MB/s
  64k      832 MB/s
 128k      1.0 GB/s
 256k      1.1 GB/s
 512k      1.1 GB/s
   1M      927 MB/s
   2M      587 MB/s
   4M      401 MB/s
   8M      430 MB/s
  16M      340 MB/s

É interessante observar que o pico de desempenho do VirtFS acontece mais tarde (bs=4M) do que aquele do arquivo na imagem da VM (bs=256k). Entretanto, a velocidade de escritura máxima no VirtFS é o dobro daquela do disco da imagem VM (2.2 GB/s contra 1.1 GB/s, respectivamente)

Para terminar o registro, aqui vão os resultados com o arquivo de destino numa partição compartilhada via NFS:

rlaboiss@NFS:~$ for bs in 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1M 2M 4M 8M 16M; do
    speed=$(dd if=/dev/zero of=/home/rlaboiss/test count=10 bs=$bs 2>&1 | grep copied | cut -f3 -d, );
    printf "%5s %8s" $bs $speed;
    echo "";
done
   1k      197 kB/s
   2k      533 kB/s
   4k      1.1 MB/s
   8k      1.3 MB/s
  16k      3.4 MB/s
  32k      4.7 MB/s
  64k      6.6 MB/s
 128k      8.4 MB/s
 256k      9.5 MB/s
 512k      9.5 MB/s
   1M     11.7 MB/s
   2M     13.8 MB/s
   4M     14.2 MB/s
   8M     16.2 MB/s
  16M     15.8 MB/s

Detalhes metodológicos

Os testes do Arlindo foram feitos na VM nfs. Os testes acima, foram feitos na git.cefala.org. Para isto, eu adicionei um hardware nesta VM, que aparece assim no arquivo /etc/libvirt/qemu/CEFALA-Git.xml:

<filesystem type='mount' accessmode='mapped'>
  <driver type='path'/>
  <source dir='/var/tmp/virtfs'/>
  <target dir='/virtfs'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</filesystem>

O diretório /var/tmp/virtfs aparece assim na kvm:

rlaboiss@CEFALA:~$ ls -ld /var/tmp/virtfs/
drwxrwxrwx 3 libvirt-qemu libvirt-qemu 4096 Jun  1 13:39 /var/tmp/virtfs/

social