A documentação da VMware diz para usar o PVSCSI em cargas de trabalho intensivas em storage. A internet concorda. E não está errado — mas depois de rodar a mesma carga do fio em cinco VMs simultâneas com os dois controladores, o tipo de controlador se mostrou a variável menos interessante. O SIOC fazia todo o trabalho pesado.
Este é um complemento do post sobre o fio_benchmark. Mesmo script, mesmos discos virtuais de 200 GiB, cinco VMs acessando o storage simultaneamente em quatro configurações: LSI sem SIOC, LSI com SIOC, PVSCSI sem SIOC e PVSCSI com SIOC.
O ambiente de teste#
Cinco VMs (gus_fio_1 até gus_fio_5), todas no mesmo cluster vSphere, todas rodando o fio_benchmark simultaneamente contra um disco virtual dedicado de 200 GiB. Cada teste rodou por 300 segundos por perfil. O alvo era /dev/sdb — um disco dedicado, sem SO nem dados.
Configuração das VMs: Ubuntu Server 24.04, 2 vCPU, 4 GB de RAM. Idêntica nas cinco VMs em cada rodada de teste.
Cada VM executou o seguinte comando simultaneamente:
sudo ./fio_benchmark.sh -t /dev/sdb -r 300 -s -m-r 300 define 300 segundos por perfil de teste, -s executa a varredura de iodepth e -m executa a varredura de mix R/W.
Quatro configurações:
- LSI Logic SAS (LSI) — o controlador padrão que o vSphere atribui quando você avança pelo assistente de criação de VM
- VMware Paravirtual (PVSCSI) — o controlador SCSI paravirtual da VMware, feito sob medida
- Cada um repetido com o SIOC (Storage I/O Control) desabilitado e habilitado
Sem SIOC: a loteria do storage#
Com cinco VMs rodando simultaneamente e o SIOC desligado, o que você tem é uma corrida. Quem submete I/O primeiro fica com a fila — e os resultados refletem exatamente isso.
Leitura sequencial de 128K — LSI, SIOC desligado#
| VM | Largura de banda | Latência (méd.) |
|---|---|---|
| gus_fio_1 | 401 MiB/s | 9,95 ms |
| gus_fio_2 | 1.148 MiB/s | 3,47 ms |
| gus_fio_3 | 203 MiB/s | 19,63 ms |
| gus_fio_4 | 326 MiB/s | 12,22 ms |
| gus_fio_5 | 204 MiB/s | 19,60 ms |
O gus_fio_2 puxou 1.148 MiB/s enquanto o gus_fio_3 e o gus_fio_5 ficaram presos em ~204 MiB/s. Cinco VMs idênticas, mesma carga, mesmo datastore — e uma delas recebeu 5,6× mais banda do que outra. Não é diferença de configuração. É só timing de fila.
A dispersão de latência confirma: o gus_fio_2 com 3,47 ms de média, o gus_fio_3 com 19,63 ms. A VM “vencedora” completava o I/O 5,7× mais rápido porque estava com a fila.
O PVSCSI tem o mesmo problema:
Leitura sequencial de 128K — PVSCSI, SIOC desligado#
| VM | Largura de banda | Latência (méd.) |
|---|---|---|
| gus_fio_1 | 191 MiB/s | 20,85 ms |
| gus_fio_2 | 382 MiB/s | 10,44 ms |
| gus_fio_3 | 648 MiB/s | 6,15 ms |
| gus_fio_4 | 382 MiB/s | 10,45 ms |
| gus_fio_5 | 191 MiB/s | 20,85 ms |
Outro vencedor, mesma dinâmica. O gus_fio_3 pegou 648 MiB/s enquanto o gus_fio_1 e o gus_fio_5 ficaram em 191 MiB/s — uma diferença de 3,4×. O controlador mudou; a injustiça não.
É isso que acontece quando várias VMs compartilham storage sem nenhum mecanismo de fairness. Não é previsível, não é proporcional, e muda a cada vez que você roda o benchmark.
A varredura de iodepth revela outra camada#
A varredura de iodepth (randread de 4K, um único job, indo da profundidade 1 a 128) mostra algo interessante sobre como as diferentes VMs se comportam sob contenção.
Varredura de iodepth do gus_fio_4 — LSI, SIOC desligado:
| iodepth | IOPS | Latência média |
|---|---|---|
| 16 | 32.470 | 0,49 ms |
| 32 | 40.120 | 0,80 ms |
| 64 | 40.319 | 1,59 ms |
| 128 | 40.735 | 3,14 ms |
O gus_fio_4 conseguiu continuar escalando bem além do iodepth 32 e manteve mais de 40K IOPS até a profundidade 128. Enquanto isso:
Varredura de iodepth do gus_fio_2 — LSI, SIOC desligado:
| iodepth | IOPS | Latência média |
|---|---|---|
| 16 | 22.399 | 0,71 ms |
| 32 | 30.885 | 1,03 ms |
| 64 | 19.845 | 3,22 ms |
| 128 | 19.274 | 6,64 ms |
O gus_fio_2 atingiu o pico na profundidade 32 (30.885 IOPS) e depois despencou na profundidade 64 — caindo para 19.845 IOPS. É a fila de storage saturando: quando o gus_fio_2 empurrou I/Os concorrentes demais, eles se acumularam e a latência subiu o suficiente para reduzir a vazão efetiva. A fila de comandos bateu no teto, e adicionar mais profundidade piorou as coisas.
Este é o diagnóstico mais útil que a varredura oferece. Se a sua curva de IOPS atinge um pico e depois cai conforme você aumenta a profundidade, você encontrou o ponto em que o seu storage (ou a fila do hypervisor) está saturado.
O que o SIOC realmente faz#
O SIOC (Storage I/O Control) adiciona uma camada de gerenciamento de congestionamento no nível do datastore. Quando detecta que a latência está subindo acima de um limite (configurável, com padrão de 30ms para datastores de HDD), ele começa a limitar as VMs que estão emitindo quantidades desproporcionalmente grandes de I/O.
Leitura sequencial de 128K — LSI, SIOC ligado#
| VM | Largura de banda | Latência (méd.) |
|---|---|---|
| gus_fio_1 | 406 MiB/s | 9,82 ms |
| gus_fio_2 | 401 MiB/s | 9,95 ms |
| gus_fio_3 | 292 MiB/s | 13,67 ms |
| gus_fio_4 | 331 MiB/s | 12,07 ms |
| gus_fio_5 | 293 MiB/s | 13,64 ms |
Os 1.148 MiB/s do gus_fio_2 viraram 401 MiB/s — uma redução de 65%. O gus_fio_3, que estava estrangulado em 203 MiB/s, subiu para 292 MiB/s. A faixa se comprimiu de 203–1.148 MiB/s para 292–406 MiB/s.
O SIOC não aumentou a vazão agregada total — o datastore tem a mesma capacidade física de qualquer forma. O que ele fez foi impedir que uma VM levasse 5× a sua parte justa.
O gus_fio_3 e o gus_fio_5 ainda ficam atrás do gus_fio_1 e do gus_fio_2 mesmo com o SIOC habilitado. Isso é consistente em todas as rodadas e sugere que eles estão em um disco físico ou extent VMFS diferente dentro do mesmo datastore — um problema de posicionamento que o SIOC não consegue resolver.
O PVSCSI com SIOC mostra o mesmo padrão:
Leitura sequencial de 128K — PVSCSI, SIOC ligado#
| VM | Largura de banda | Latência (méd.) |
|---|---|---|
| gus_fio_1 | 285 MiB/s | 14,00 ms |
| gus_fio_2 | 568 MiB/s | 7,02 ms |
| gus_fio_3 | 576 MiB/s | 6,93 ms |
| gus_fio_4 | 569 MiB/s | 7,01 ms |
| gus_fio_5 | 285 MiB/s | 14,02 ms |
O SIOC comprimiu a variação do PVSCSI de uma dispersão de 3,4× (191–648 MiB/s) para 2× (285–576 MiB/s). O gus_fio_1 e o gus_fio_5 continuam consistentemente com metade da banda das outras três — as mesmas duas VMs que ficaram atrás com o LSI. O controlador mudou; o posicionamento não.
A varredura de mix R/W — a fairness do SIOC fica mais visível aqui#
A varredura de mix R/W (randrw de 4K, 8 jobs, iodepth 8, variando o % de escrita de 0% a 100%) mostra como o IOPS degrada conforme a pressão de escrita aumenta. A curva de penalidade de escrita diz muito sobre a saúde do storage.
LSI, SIOC desligado — varredura de mix R/W do gus_fio_4:
| % de escrita | IOPS | Latência média |
|---|---|---|
| 0% (leitura pura) | 40.585 | 1,56 ms |
| 50% | 33.997 | 1,92 ms |
| 100% (escrita pura) | 29.838 | 2,13 ms |
Degradação limpa e gradual. O gus_fio_4 foi a VM com sorte nesta rodada.
LSI, SIOC desligado — varredura de mix R/W do gus_fio_3:
| % de escrita | IOPS | Latência média |
|---|---|---|
| 0% | 19.189 | 3,32 ms |
| 50% | 16.043 | 4,05 ms |
| 100% | 14.888 | 4,29 ms |
O gus_fio_3 começou em 19K IOPS onde o gus_fio_4 começou em 40K. Mesmo datastore, mesmo instante. Sem o SIOC, a diferença entre a VM “vencedora” e a “perdedora” na leitura pura é de mais de 2× — e essa diferença persiste ao longo de toda a curva de penalidade de escrita.
PVSCSI vs LSI: o que os números realmente dizem#
O controlador SCSI paravirtual elimina o overhead da emulação de hardware. Em vez de o hypervisor fingir ser uma placa LSI Logic SAS, o PVSCSI usa um ring buffer compartilhado com o qual o driver do guest conversa diretamente. Menos trocas de contexto, agrupamento de I/O mais eficiente, teoricamente melhor vazão.
Na prática, com estas VMs e este datastore, a diferença dependeu da carga de trabalho.
Vazão e latência (apenas gus_fio_1, SIOC desligado)#
| Teste | Controlador | IOPS | Largura de banda | Latência média |
|---|---|---|---|---|
| Leitura aleatória 4K | LSI | 19.238 | 75,2 MiB/s | 6,63 ms |
| Leitura aleatória 4K | PVSCSI | 20.193 | 78,9 MiB/s | 6,32 ms |
| Escrita aleatória 4K | LSI | 17.357 | 67,8 MiB/s | 3,67 ms |
| Escrita aleatória 4K | PVSCSI | 15.451 | 60,4 MiB/s | 4,13 ms |
| Escrita aleatória | LSI | 5.146 | 321,6 MiB/s | 12,37 ms |
| Escrita aleatória | PVSCSI | 1.653 | 103,3 MiB/s | 38,69 ms |
| Escrita seq. | LSI | 8.960 | 280,0 MiB/s | 1,76 ms |
| Escrita seq. | PVSCSI | 5.450 | 170,3 MiB/s | 2,92 ms |
As leituras aleatórias são praticamente um empate. O quadro das escritas é mais difícil de ler com clareza: as escritas aleatórias de 4K são parecidas, mas a escrita aleatória de bloco maior (bs de 64K, 8 jobs) mostra o PVSCSI com 3× menos IOPS e 3× mais latência do que o LSI. As escritas sequenciais seguem na mesma direção — o PVSCSI com cerca de 40% menos banda.
Esses testes rodaram simultaneamente nas cinco VMs, então os resultados não são apenas uma comparação de controladores — são uma comparação de controladores sob contenção compartilhada. O comportamento de agrupamento de I/O do ring buffer do PVSCSI pode mudar a dinâmica de contenção quando várias VMs acessam o mesmo datastore ao mesmo tempo.
Overhead de CPU: onde o PVSCSI realmente entrega#
O quadro de vazão acima é misto. O quadro de CPU não é.
| Teste | Controlador | CPU (usr / sys) | IOPS/CPU% |
|---|---|---|---|
| Leitura seq. | LSI | 0,68% / 2,09% | 8.563 |
| Leitura seq. | PVSCSI | 0,48% / 1,51% | 9.851 |
| Escrita seq. | LSI | 2,85% / 2,10% | 1.807 |
| Escrita seq. | PVSCSI | 1,01% / 1,00% | 2.701 |
| Leitura aleatória 4K | LSI | 0,26% / 0,77% | 18.640 |
| Leitura aleatória 4K | PVSCSI | 0,20% / 0,63% | 24.260 |
| Escrita aleatória 4K | LSI | 0,75% / 1,40% | 8.104 |
| Escrita aleatória 4K | PVSCSI | 0,44% / 1,01% | 10.666 |
O PVSCSI consistentemente gasta menos CPU por IOPS em todos os testes:
- Escrita sequencial: o LSI usa 4,95% de CPU total para 8.960 IOPS. O PVSCSI usa 2,01% de CPU total para 5.450 IOPS. A regressão de banda é real, mas a redução de 59% na CPU também.
- Leitura aleatória de 4K: o PVSCSI é 30% mais eficiente (24.260 vs 18.640 IOPS/CPU%). Aqui o PVSCSI também ganha em vazão, então é uma vitória limpa.
- Escrita aleatória de 4K: 31% melhor eficiência no PVSCSI, e vazão quase equivalente.
Essa é a promessa original do driver paravirtual: eliminar o overhead da emulação e obter mais I/O por ciclo de CPU. Os números de CPU confirmam que funciona. Se o custo em vazão nas escritas de bloco grande importa depende da sua carga de trabalho.
As principais conclusões#
O SIOC importa mais do que o tipo de controlador. Sem o SIOC, uma única VM em um cluster de cinco VMs puxou 5,6× mais banda do que as vizinhas. Com o SIOC, a variação se comprimiu para cerca de 1,4×. Se você roda várias VMs intensivas em storage em um datastore compartilhado e o SIOC está desabilitado, você tem um problema de fairness independentemente do controlador que estiver usando.
A vantagem real do PVSCSI é a eficiência de CPU, não a vazão bruta. As diferenças de vazão entre os controladores dependem da carga de trabalho e nem sempre favorecem o PVSCSI. O que é consistente: o PVSCSI gasta de 30 a 60% menos CPU por IOPS em todos os testes. Em um host rodando muitas VMs pesadas em storage, esse overhead se acumula. Se você tem limitação de CPU, o PVSCSI importa mesmo quando os números de IOPS parecem semelhantes.
A varredura de iodepth é diagnóstica, não só informativa. O comportamento de saturação da fila (o IOPS atinge o pico e depois cai conforme a profundidade aumenta) mostra onde está o teto do seu storage. O gus_fio_2 atingiu o pico na profundidade 32 e degradou a partir dali — esse é o ponto em que aumentar a profundidade da fila prejudica em vez de ajudar.
A recomendação prática: habilite o SIOC em todo datastore compartilhado — o argumento da fairness é inequívoco, seja qual for o controlador. Para a escolha do controlador, o PVSCSI é o padrão certo: o ganho de eficiência de CPU é consistente em todas as cargas, e para a maioria das cargas mistas ou com predominância de leitura os números de vazão são equivalentes ou melhores. O único caso que vale a pena fazer benchmark antes de se comprometer é o de escritas em massa de bloco grande (backups, ETL, ingestão de vídeo) — a regressão ali foi significativa o bastante para que, se essa for a sua carga principal, você deva verificar no seu storage específico antes de assumir que o PVSCSI é a escolha certa.
O posicionamento da VM dentro de um datastore tem efeitos reais. O gus_fio_3 e o gus_fio_5 tiveram desempenho consistentemente inferior ao do gus_fio_1 e do gus_fio_2 em todas as configurações, inclusive com o SIOC. Se VMs no mesmo datastore estão recebendo desempenhos sistematicamente diferentes, suspeite do extent do disco ou do layout dos spindles antes de culpar o controlador ou o guest.
Todos os testes usaram o fio_benchmark — o script de benchmark apresentado no post anterior. Tempo de execução de 300 segundos por teste, libaio, I/O direto, sem cache de sistema de arquivos.
Os resultados brutos das cinco VMs nas quatro configurações estão disponíveis para download, caso você queira verificar os números ou fazer a sua própria análise: results_fio.txt.



