Desempenho do ZFS: preciso manter espaço livre em um pool ou sistema de arquivos?

17

Eu sei que o desempenho do ZFS depende muito da quantidade de espaço livre:

Mantenha o espaço do pool com uma utilização de 80% para manter o desempenho do pool. Atualmente, o desempenho do pool pode diminuir quando um pool está muito cheio e os sistemas de arquivos são atualizados com freqüência, como em um servidor de correio ocupado. Pools completos podem causar uma penalidade no desempenho, mas nenhum outro problema. [...] Lembre-se de que mesmo com conteúdo principalmente estático na faixa de 95 a 96%, o desempenho de gravação, leitura e resilversão pode sofrer. ZFS_Best_Practices_Guide, solarisinternals.com (archive.org)

Agora, suponha que eu tenha um pool de 10T raidz2 hospedando um sistema de arquivos ZFS volume. Agora, crio um sistema de arquivos filho volume/teste faço uma reserva de 5T.

Em seguida, montei os dois sistemas de arquivos por NFS em algum host e realizo algum trabalho. Entendo que não posso gravar em volumemais de 5T, porque os 5T restantes estão reservados volume/test.

Minha primeira pergunta é: como o desempenho diminuirá se eu preencher meu volumeponto de montagem com ~ 5T? Vai cair, porque não há espaço livre nesse sistema de arquivos para a cópia na gravação do ZFS e outras meta-coisas? Ou permanecerá o mesmo, já que o ZFS pode usar o espaço livre dentro do espaço reservado para volume/test?

Agora a segunda pergunta . Faz alguma diferença se eu alterar a configuração da seguinte maneira? volumeagora possui dois sistemas de arquivos volume/test1e volume/test2. Ambos recebem uma reserva de 3T cada (mas sem cotas). Suponha agora, eu escrevo 7T para test1. O desempenho dos dois sistemas de arquivos será o mesmo ou será diferente para cada sistema de arquivos? Vai cair, ou permanecerá o mesmo?

Obrigado!

Pavel
fonte

Respostas:

9

Sim. Você precisa manter espaço livre em sua piscina. É principalmente para ações de cópia na gravação e instantâneos. O desempenho diminui em cerca de 85% de utilização. Você pode ir mais alto, mas há um impacto definitivo.

Não mexa com reservas. Especialmente com o NFS. Não é necessário. Talvez para um zvol, mas não NFS.

Eu não vejo a confusão, no entanto. Se você tem 10T, não use mais de 85% dele. Dimensione suas ações adequadamente, usando cotas para limitar seu uso. Ou não use cotas e monitore o uso geral do pool .

ewwhite
fonte
Obrigado! Não existe uma maneira justa em nossa configuração de usar cotas, para que todos usem o mesmo ponto de montagem e possam preencher o espaço, levando a uma queda no desempenho. Minha idéia era garantir algum espaço livre com uma reserva para que o sistema geral nunca ficasse muito lento. Mas no IIUC, posso ter essa garantia limitando volumea 8,5T e nunca mais pensar nisso. Isso está correto?
Pavel
Você poderia .. ou apenas assistir. Quero dizer, é NFS ... não é um zvol, então você pode excluir arquivos para voltar a 8.5TB.
ewwhite
Sim, mas é uma dor de ter estes "por favor limpar o seu sh .., o servidor de arquivos é terrivelmente lento" discussões nas listas de discussão a cada duas semanas ...
Pavel
Solução técnica para um problema social / administrativo :) Você antecipa tantos dados?
Ewwhite 27/05
Hehe .. Sim, essa é uma situação bastante comum que enfrentamos. Portanto, existem declarações como esta: "Em sistemas de arquivos com muitas criações e exclusões de arquivos, a utilização deve ser mantida abaixo de 80% para proteger o desempenho". imprecisa, porque é realmente sobre o espaço livre dentro de um pool e não o sistema de arquivos?
Pavel
21

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 bloco livre empregado com o ZFS. Ao contrário de outros sistemas de arquivos como NTFS ou ext3, não há bitmap de bloco mostrando quais blocos estão ocupados e quais são livres. Em vez disso, o ZFS divide seu zvol em (geralmente 200) áreas maiores chamadas "metaslabs" e armazena as árvores AVL 1 de informações de bloco gratuitas (mapa de espaço) em cada metasslab. A árvore AVL balanceada permite uma busca eficiente de um bloco adequado ao tamanho da solicitação.

Embora esse 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 de espaço. Assim que todos os metasslabs transportam 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 o pool está vazio. Se o ZFS precisar alocar 2 MB de espaço, ele começará a ler e avaliar os mapas espaciais de todos os metaslabs para encontrar um bloco adequado ou uma maneira de dividir os 2 MB em blocos menores. Isso, claro, leva algum tempo. O pior é o fato de que custará muitas operações de E / S, pois o ZFS de fato leria todos os mapas de espaço dos discos físicos . Para qualquer uma de suas gravações.

A queda no desempenho pode ser significativa. Se você gosta de imagens bonitas, dê uma olhada na publicação no Delphix, que tem alguns números retirados de um pool zfs (simplificado, mas ainda válido). Estou roubando descaradamente um dos gráficos - observe as linhas azul, vermelha, amarela e verde neste gráfico, que representam (respectivamente) os conjuntos com 10%, 50%, 75% e 93% de capacidade desenhada contra a taxa de transferência de gravação em KB / s enquanto se fragmenta com o tempo: degradação do desempenho do zpool

Uma solução rápida e suja para isso tem sido tradicionalmente o modo de depuração do metaslab (apenas echo metaslab_debug/W1 | mdb -kwem tempo de execução para alterar instantaneamente a configuração). Nesse caso, todos os mapas de espaço seriam mantidos na RAM do SO, removendo o requisito de E / S excessiva e cara em cada operação de gravação. Por fim, isso também significa que você precisa de mais memória, especialmente para grandes pools, por isso é uma espécie de RAM para o comércio de cavalos. Seu pool de 10 TB provavelmente custará de 2 a 4 GB de memória 2 , mas você poderá direcioná-lo para 95% de utilização sem muito aborrecimento.


1 é um pouco mais complicado, se você estiver interessado, veja o post de Bonwick nos mapas espaciais para obter detalhes

2 Se você precisar calcular um limite superior para a memória, use zdb -mm <pool>para recuperar o número segmentsatualmente em uso em cada metasslab, divida-o por dois para modelar o pior cenário (cada segmento ocupado seria seguido por um livre) ), multiplique pelo tamanho do registro para 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, somariam 32 bytes, embora as pessoas pareçam geralmente assumir 64 bytes para alguns razão).

zdb -mm tank | awk '/segments/ {s+=$2}END {s*=32/2; printf("Space map size sum = %d\n",s)}'

Referência: o esboço básico está contido nesta postagem por Markus Kovero na lista de discussão do zfs-discuss , embora eu acredite que ele tenha cometido alguns erros no cálculo, que espero ter corrigido no meu.

o wabbit
fonte
syneticon-dj, obrigado por esta explicação! Aumentar a RAM parece ajudar de fato.
Pavel
E o BPR (reescrita do ponteiro de bloco)? Também este blogs.kent.ac.uk/unseenit/2013/10/02/… menciona o uso de um SLOG for ZIL também ajuda. E esse cara nex7.blogspot.com.au/2013/03/readme1st.html diz que você apenas envia e recebe até ficar tudo bem.
CMCDragonkai
@CMCDragonkai Posso garantir, por experiência própria, que o uso de um dispositivo ZIL separado não faz nada em relação ao desempenho devido à fragmentação do mapa espacial. Mas não ter um dispositivo ZIL aumentará a fragmentação geral e será mais provável que você atinja o problema com porcentagens mais baixas de utilização de espaço. O BPR ainda é um vaporware - não existe código demonstrável, muito menos uma implementação estável. A send-receive ciclo é realmente provável que ajuda na obtenção de uma piscina desfragmentado, mas isso vai significar o tempo de inatividade para o enviado dataset / recebida.
the-wabbit
E se você replicasse o conjunto de dados antes de enviar-receber em outro disco? E então basta girar um ciclo de envio e recebimento para cada disco?
CMCDragonkai
@CMCDragonkai, você pode manter o tempo de inatividade curto fazendo um envio completo primeiro e trabalhando com incrementais depois disso. Mas o tempo de inatividade permanece. Se você usar seus conjuntos de dados como armazenamento de back-end para bancos de dados ou virtualização, o tempo de inatividade será prejudicado, mesmo que seja curto. Além disso, você precisará de um pool vazio e separado para que isso funcione.
the-wabbit