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.
fonte
Respostas:
Esta configuração pode não estar bem ajustada. Existem parâmetros necessários para o arquivo /etc/modprobe/zfs.conf e o valor ashift ao usar SSDs
Tente ashift = 12 ou 13 e teste novamente.
Editar:
Ainda é uma solução virtualizada, por isso não sabemos muito sobre o hardware subjacente ou como tudo está interconectado. Não sei se você obterá melhor desempenho com esta solução.
Editar:
Acho que não vejo o ponto de tentar otimizar uma instância de nuvem dessa maneira. Porque se o melhor desempenho fosse o objetivo, você estaria usando hardware, certo?
Mas lembre-se de que o ZFS possui muitas configurações ajustáveis e o que você obtém por padrão não está nem perto do seu caso de uso.
Tente o seguinte em seu
/etc/modprobe.d/zfs.conf
e reinicie. É o que eu uso nos meus conjuntos de dados totalmente SSD para servidores de aplicativos. Seu ashift deve ser 12 ou 13. Benchmark com compressão = desativado, mas use compressão = lz4 na produção. Atime = off. Eu deixaria o tamanho do registro como padrão (128K).fonte
zfs get compression
. Dedupe também está desligado.Parece provável que você esteja aguardando um bloqueio mutex do kernel Linux que, por sua vez, esteja aguardando um buffer de anel Xen. Não posso ter certeza disso sem acesso a uma máquina semelhante, mas não estou interessado em pagar à Amazon US $ 7 / hora por esse privilégio.
A redação mais longa está aqui: https://www.reddit.com/r/zfs/comments/4b4r1y/why_is_zfs_on_linux_unable_to_fully_utilize_8x/d1e91wo ; Prefiro estar em um lugar do que em dois.
fonte
Passei um tempo decente tentando rastrear isso. Meu desafio específico: um servidor Postgres e eu quero usar o ZFS para seu volume de dados. A linha de base é o XFS.
Em primeiro lugar, minhas provações me dizem que
ashift=12
está errado. Se houver umashift
número mágico , não será 12. Estou usando0
e obtendo resultados muito bons.Também experimentei várias opções de zfs e as que me dão os resultados abaixo são:
atime=off
- Eu não preciso de horários de acessochecksum=off
- Estou tirando a roupa, não espelhandocompression=lz4
- O desempenho é melhor com a compactação (compensação da CPU?)exec=off
- Isto é para dados, não executáveislogbias=throughput
- Leia nas interwebs que é melhor para o Postgresrecordsize=8k
- 8k de tamanho de bloco específico para PGsync=standard
- tentou desativar a sincronização; não vi muito benefícioMeus testes abaixo mostram um desempenho melhor que o XFS (comente se você encontrar erros nos meus testes!).
Com isso, meu próximo passo é tentar o Postgres executando em um sistema de arquivos 2 x EBS ZFS.
Minha configuração específica:
EC2:
m4.xlarge
instânciaEBS:
gp2
volumes de 250 GBkernel: Linux [...] 3.13.0-105-generic # 152-Ubuntu SMP [...] x86_64 x86_64 x86_64 GNU / Linux *
Primeiro, eu queria testar o desempenho bruto do EBS. Usando uma variação do
fio
comando acima, criei o encantamento abaixo. Nota: Estou usando blocos de 8k, porque é isso que li nas gravações do PostgreSQL:O desempenho bruto do volume EBS é
WRITE: io=3192.2MB
.Agora, testando o XFS com o mesmo
fio
comando:Nossa linha de base é
WRITE: io=3181.9MB
; muito perto da velocidade do disco bruto.Agora, no ZFS com
WRITE: io=3181.9MB
como referência:Observe que isso teve um desempenho melhor que o XFS
WRITE: io=4191.7MB
. Tenho certeza de que isso se deve à compactação.Para chutes, vou adicionar um segundo volume:
Com um segundo volume
WRITE: io=5975.9MB
, então ~ 1,8X as gravações.Um terceiro volume nos fornece
WRITE: io=6667.5MB
, portanto, aproximadamente 2,1X das gravações.E um quarto volume nos dá
WRITE: io=6552.9MB
. Para esse tipo de instância, parece que quase capto a rede EBS com dois volumes, definitivamente com três e não é melhor com 4 (750 * 3 = 2250 IOPS).* Neste vídeo, verifique se você está usando o kernel 3.8+ linux para obter toda a qualidade do EBS.
fonte
WRITE: io=
; essa não é a velocidade, é a quantidade de dados gravados naquele tempo. Relacionado à velocidade apenas para testes com tempo de execução fixo, mas para consistência com outros benchmarks, é melhor focar no IOPSiops=
,. No seu caso, os resultados são semelhantes Você provavelmente poderia melhorar muito se usar volumes IOPS EBS provisionados e uma instância maior. Consulte esta página para obter os limites esperados do EBS por tamanho de instância. Cuidado, as cobranças do EBS aumentam rapidamente se você não tomar cuidado!/etc/modules.d/zfs.conf
. A próxima pergunta seria qual é o número apropriado de Iops para uma instância do ec2. Olhar para a página que você faz referência ainda é complicado, e eu não estou vendo um desempenho tão bom quanto o estado dos documentos.