A degradação do desempenho ocorre quando o zpool está muito cheio ou muito fragmentado. A razão para isso é o mecanismo de descoberta de blocos livres empregado com o ZFS. Oposto a outros sistemas de arquivos como NTFS ou ext3, não há nenhum bitmap de bloco mostrando quais blocos estão ocupados e quais estão livres. Em vez disso, o ZFS divide seu zvol em (geralmente 200) áreas maiores chamadas "metaslabs" e armazena AVL-trees 1 de informações de blocos livres (mapa de espaço) em cada metaslab. A árvore AVL balanceada permite uma busca eficiente por um bloco adequado ao tamanho da solicitação.
Embora este mecanismo tenha sido escolhido por razões de escala, infelizmente também se tornou uma grande dor quando ocorre um alto nível de fragmentação e / ou utilização do espaço. Assim que todos os metaslabs carregam uma quantidade significativa de dados, você obtém um grande número de pequenas áreas de blocos livres, em oposição a um pequeno número de grandes áreas quando a piscina está vazia. Se o ZFS precisar alocar 2 MB de espaço, ele começará a ler e avaliar todos os mapas de espaço do metaslabs para encontrar um bloco adequado ou uma maneira de dividir os 2 MB em blocos menores. Isso, claro, leva algum tempo. O que é pior é o fato de que custará um monte de operações de E / S, já que o ZFS realmente leu todos os mapas de espaço fora dos discos físicos . Para qualquer das suas gravações.
A queda no desempenho pode ser significativa. Se você gosta de fotos bonitas, dê uma olhada na postagem do no Delphix , que tem algumas números retirados de um pool zfs (supersimplificado mas ainda válido). Estou descarnando furiosamente um dos gráficos - observe as linhas azul, vermelha, amarela e verde neste gráfico que representam (respectivamente) conjuntos a 10%, 50%, 75% e 93% da capacidade obtida em relação à taxa de transferência em KB / s ao se tornar fragmentado ao longo do tempo:
Umrápido&Umconsertosujoparaissotemsidotradicionalmenteomododedepuraçãometaslab(apenasemitaechometaslab_debug/W1|mdb-kw
emtempodeexecuçãoparaalterarinstantaneamenteaconfiguração).Nessecaso,todososmapasdeespaçoseriammantidosnoOSRAM,removendoorequisitodeE/Sexcessivaedispendiosaemcadaoperaçãodegravação.Emúltimaanálise,issotambémsignificaquevocêprecisademaismemória,especialmenteparagrandespools,porissoéumaespéciedeRAMparaocomérciodecavalosdearmazenamento.Seupoolde10TBprovavelmentecustará2-4GBdememória2,masvocêpoderádirecionarpara95%deutilizaçãosemmuitacomplicação.
1éumpoucomaiscomplicado,sevocêestiverinteressado,veja post de Bonwick em mapas espaciais para detalhes
2 se você precisar calcular um limite superior para a memória, use zdb -mm <pool>
para recuperar o número de segments
atualmente em uso em cada metaslab, divida-o por dois para modelar na pior das hipóteses (cada segmento ocupado seria seguido por um livre), multiplique-o pelo tamanho do registro de um nó AVL (dois ponteiros de memória e um valor, dada a natureza de 128 bits do zfs e o endereçamento de 64 bits soma até 32 bytes, embora as pessoas pareçam geralmente assumir 64 bytes por algum motivo).
zdb -mm tank | awk '/segments/ {s+=$2}END {s*=32/2; printf("Space map size sum = %d\n",s)}'
Referência: o esquema básico está contido em esta postagem de Markus Kovero no zfs- discutir lista de discussão , embora eu acredite que ele cometeu alguns erros em seu cálculo, que espero ter corrigido no meu.