Sou completamente novo no ZFS, então, para começar, pensei em fazer alguns benchmarks simples para ter uma ideia de como ele se comporta. Eu queria aumentar os limites de seu desempenho e provisionar uma i2.8xlarge
instância do Amazon EC2 (quase US $ 7 / hora, tempo é realmente dinheiro!). Esta instância possui 8 SSDs de 800 GB.
Fiz um fio
teste nos próprios SSDs e obtive a seguinte saída (aparada):
$ sudo fio --name randwrite --ioengine=libaio --iodepth=2 --rw=randwrite --bs=4k --size=400G --numjobs=8 --runtime=300 --group_reporting --direct=1 --filename=/dev/xvdb
[trimmed]
write: io=67178MB, bw=229299KB/s, iops=57324, runt=300004msec
[trimmed]
57K IOPS para gravações aleatórias em 4K. Respeitável.
Em seguida, criei um volume ZFS com todos os 8. No começo, eu tinha um raidz1
vdev com todos os 8 SSDs, mas li sobre os motivos pelos quais isso é ruim para o desempenho, então acabei com quatro mirror
vdevs, assim:
$ sudo zpool create testpool mirror xvdb xvdc mirror xvdd xvde mirror xvdf xvdg mirror xvdh xvdi
$ sudo zpool list -v
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
testpool 2.91T 284K 2.91T - 0% 0% 1.00x ONLINE -
mirror 744G 112K 744G - 0% 0%
xvdb - - - - - -
xvdc - - - - - -
mirror 744G 60K 744G - 0% 0%
xvdd - - - - - -
xvde - - - - - -
mirror 744G 0 744G - 0% 0%
xvdf - - - - - -
xvdg - - - - - -
mirror 744G 112K 744G - 0% 0%
xvdh - - - - - -
xvdi - - - - - -
Defino o tamanho do registro como 4K e executei meu teste:
$ sudo zfs set recordsize=4k testpool
$ sudo fio --name randwrite --ioengine=libaio --iodepth=2 --rw=randwrite --bs=4k --size=400G --numjobs=8 --runtime=300 --group_reporting --filename=/testpool/testfile --fallocate=none
[trimmed]
write: io=61500MB, bw=209919KB/s, iops=52479, runt=300001msec
slat (usec): min=13, max=155081, avg=145.24, stdev=901.21
clat (usec): min=3, max=155089, avg=154.37, stdev=930.54
lat (usec): min=35, max=155149, avg=300.91, stdev=1333.81
[trimmed]
Eu recebo apenas 52K IOPS neste pool do ZFS. Na verdade, isso é um pouco pior do que um SSD em si.
Não entendo o que estou fazendo de errado aqui. Eu configurei o ZFS incorretamente ou esse é um teste ruim do desempenho do ZFS?
Observe que estou usando a imagem oficial do CentOS 7 HVM de 64 bits, embora tenha atualizado para o kernel 4.4.5 elrepo:
$ uname -a
Linux ip-172-31-43-196.ec2.internal 4.4.5-1.el7.elrepo.x86_64 #1 SMP Thu Mar 10 11:45:51 EST 2016 x86_64 x86_64 x86_64 GNU/Linux
Instalei o ZFS a partir do repositório zfs listado aqui . Eu tenho a versão 0.6.5.5 do zfs
pacote.
ATUALIZAÇÃO : Por sugestão da @ ewwhite, tentei ashift=12
e ashift=13
:
$ sudo zpool create testpool mirror xvdb xvdc mirror xvdd xvde mirror xvdf xvdg mirror xvdh xvdi -o ashift=12 -f
e
$ sudo zpool create testpool mirror xvdb xvdc mirror xvdd xvde mirror xvdf xvdg mirror xvdh xvdi -o ashift=13 -f
Nenhum deles fez diferença. Pelo que entendi, os bits mais recentes do ZFS são inteligentes o suficiente para identificar SSDs 4K e usar padrões razoáveis.
No entanto, notei que o uso da CPU está aumentando. A Tim sugeriu isso, mas eu o rejeitei, mas acho que não estava assistindo a CPU por tempo suficiente para perceber. Há algo como 30 núcleos de CPU nesta instância, e o uso da CPU está aumentando até 80%. O processo de fome? z_wr_iss
, muitas instâncias disso.
Confirmei que a compactação está desativada, portanto não é o mecanismo de compactação.
Eu não estou usando raidz, então não deve ser o cálculo da paridade.
Eu fiz um perf top
e mostra a maior parte do tempo do kernel gasto _raw_spin_unlock_irqrestore
dentro z_wr_int_4
e osq_lock
dentro z_wr_iss
.
Agora acredito que há um componente de CPU nesse gargalo de desempenho, embora não esteja mais perto de descobrir o que pode ser.
ATUALIZAÇÃO 2 : Por sugestão da @ewwhite e de outras pessoas de que é a natureza virtualizada desse ambiente que cria incerteza no desempenho, eu costumava fio
comparar as gravações aleatórias em 4K espalhadas por quatro dos SSDs do ambiente. Cada SSD por si só fornece ~ 55K IOPS, então eu esperava algo em torno de 240K IO em quatro deles. Isso é mais ou menos o que eu tenho:
$ sudo fio --name randwrite --ioengine=libaio --iodepth=8 --rw=randwrite --bs=4k --size=398G --numjobs=8 --runtime=300 --group_reporting --filename=/dev/xvdb:/dev/xvdc:/dev/xvdd:/dev/xvde
randwrite: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8
...
randwrite: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=8
fio-2.1.5
Starting 8 processes
[trimmed]
write: io=288550MB, bw=984860KB/s, iops=246215, runt=300017msec
slat (usec): min=1, max=24609, avg=30.27, stdev=566.55
clat (usec): min=3, max=2443.8K, avg=227.05, stdev=1834.40
lat (usec): min=27, max=2443.8K, avg=257.62, stdev=1917.54
[trimmed]
Isso mostra claramente que o ambiente, por mais virtualizado que seja, pode sustentar o IOPS muito mais alto do que o que estou vendo. Algo na maneira como o ZFS é implementado está impedindo que ele atinja a velocidade máxima. Eu simplesmente não consigo descobrir o que é isso.