Configuração do kernel Linux para GlusterFS

A tradução do artigo foi preparada em antecipação ao início do curso «Administrador Linux. Profissional».

Configuração do kernel Linux para GlusterFS

Ocasionalmente, surgem perguntas sobre as recomendações do Gluster em relação à configuração do kernel e se isso é necessário.

Essa necessidade é rara. Na maioria das cargas de trabalho, o kernel funciona muito bem. No entanto, há um lado oposto. Historicamente, o kernel Linux tende a consumir muita memória, se tiver a oportunidade, inclusive para cache como uma forma principal de aumentar o desempenho.

Na maioria dos casos, isso funciona muito bem, mas sob alta carga pode causar problemas.

Temos ampla experiência com sistemas que consomem muita memória, como CAD, EDA e similares, que começam a desacelerar sob alta carga. E às vezes encontramos problemas no Gluster. Observando cuidadosamente o uso de memória e o tempo de espera dos discos, percebemos sobrecargas, altos iowait, erros de kernel (kernel oops), travamentos, etc.

Este artigo é o resultado de muitos experimentos na configuração de parâmetros realizados em diversas situações. Graças a esses parâmetros, não apenas melhoramos a capacidade de resposta geral, mas também estabilizamos consideravelmente a operação do cluster.

Quando se trata de ajustar a memória, a primeira coisa a observar é o subsistema de memória virtual (VM, virtual memory), que possui muitas opções que podem confundir.

vm.swappiness

Parâmetro vm.swappiness determina o quanto o kernel utiliza o swap em comparação com a memória RAM. No código-fonte, é também definido como "tendency to steal mapped memory" (tendência a roubar memória mapeada). Um valor alto de swappiness significa que o kernel terá maior propensão a descarregar páginas mapeadas. Um valor baixo de swappiness significa o oposto: o kernel irá menos descarregar páginas da memória. Em outras palavras, quanto maior o valor vm.swappiness, mais o sistema usará swap.

Um alto uso de swap é indesejável, pois enormes blocos de dados são carregados e descarregados da memória RAM. Muitas pessoas afirmam que o valor de swappiness deve ser alto, mas pela minha experiência, a configuração em "0" leva a um aumento de desempenho.

Você pode ler mais aqui — lwn.net/Articles/100978

No entanto, novamente, essas configurações devem ser aplicadas com cautela e apenas após testar a aplicação específica. Para aplicações de streaming com alta carga, esse parâmetro deve ser definido como "0". Alterar para "0" melhora a responsividade do sistema.

vm.vfs_cache_pressure

Esse parâmetro controla a memória consumida pelo núcleo para o cache de objetos de diretório e descritores de índice (dentry e inode).

Com o valor padrão de 100, o núcleo tentará liberar o cache dentry e inode com "justiça" em relação ao pagecache e swapcache. Reduzir o vfs_cache_pressure faz com que o núcleo mantenha os caches dentry e inode. Quando o valor é "0", o núcleo nunca limpará o cache dentry e inode devido à falta de memória (memory pressure), o que pode facilmente levar a um erro de esgotamento de memória. Aumentar o vfs_cache_pressure para mais de 100 faz com que o núcleo priorize a descarga de dentry e inode.

Ao usar GlusterFS, muitos usuários com grandes volumes de dados e muitos arquivos pequenos podem facilmente consumir uma quantidade significativa de memória no servidor devido ao cache de inode/dentry, o que pode resultar em diminuição do desempenho, já que o núcleo precisa processar estruturas de dados em um sistema com 40 GB de memória. Configurar esse parâmetro para mais de 100 ajudou muitos usuários a conseguir um cache mais justo e melhorar a responsividade do núcleo.

vm.dirty_background_ratio e vm.dirty_ratio

O primeiro parâmetro (vm.dirty_background_ratio) define a porcentagem de memória com páginas sujas, ao alcançar a qual é necessário iniciar o descarregamento em segundo plano de páginas sujas no disco. Enquanto essa porcentagem não for alcançada, as páginas não são descarregadas no disco. E quando o descarregamento começa, ele é realizado em segundo plano, sem interromper os processos em execução.

O segundo parâmetro (vm.dirty_ratio) determina a porcentagem de memória que pode ser ocupada por páginas sujas antes do início da limpeza forçada (forced flash). Ao atingir esse limite, todos os processos se tornam síncronos (são bloqueados) e não podem continuar a execução até que a operação de entrada e saída solicitada seja realmente concluída e os dados sejam gravados no disco. Em situações de alta carga de entrada e saída, isso causa problemas, pois não há cache de dados, e todos os processos que realizam entrada e saída ficam bloqueados aguardando a I/O. Isso resulta em um grande número de processos travados, alta carga, operação instável do sistema e baixo desempenho.

A redução dos valores desses parâmetros faz com que os dados sejam despejados no disco com mais frequência e não permaneçam na RAM. Isso pode ajudar sistemas com muita memória, onde é normal despejar em disco um cache de páginas de 45 a 90 GB, resultando em um enorme tempo de espera para aplicações frontend, diminuindo a responsividade e interatividade geral.

«1» > /proc/sys/vm/pagecache

O cache de páginas (page cache) é um cache onde são armazenados os dados de arquivos e programas executáveis, ou seja, são páginas com o conteúdo real dos arquivos ou dispositivos de bloco. Esse cache é usado para reduzir a quantidade de leituras do disco. O valor «1» significa que 1% da RAM é usado para o cache e haverá mais operações de leitura do disco do que da RAM. Não é necessário alterar este parâmetro, mas se você for paranoico quanto ao controle do cache de páginas, pode utilizá-lo.

«deadline» > /sys/block/sdc/queue/scheduler

O planejador de I/O (I/O scheduler) é um componente do núcleo do Linux que gerencia as filas de leitura e escrita. Teoricamente, para um controlador RAID inteligente, é melhor usar «noop», pois o Linux não sabe nada sobre a geometria física do disco, então é mais eficiente deixar o controlador, que conhece bem a geometria do disco, processar o pedido o mais rápido possível. Mas parece que «deadline» melhora o desempenho. Você pode ler mais sobre os planejadores na documentação do código fonte do núcleo do Linux: linux/Documentation/block/*osched.txt. E também observei um aumento na largura de banda de leitura durante operações mistas (muitas operações de gravação).

«256» > /sys/block/sdc/queue/nr_requests

O número de solicitações de entrada e saída no buffer antes de serem enviadas para o planejador. O tamanho da fila interna de alguns controladores (queue_depth) é maior do que nr_requests do planejador de E/S, de modo que o planejador de E/S tem poucas chances de priorizar corretamente e realizar a mesclagem de solicitações. Para os planejadores deadline e CFQ, é melhor que nr_requests seja duas vezes maior que a fila interna do controlador. A mesclagem e a reorganização de solicitações ajudam o planejador a ser mais responsivo sob alta carga.

echo "16" > /proc/sys/vm/page-cluster

O parâmetro page-cluster controla o número de páginas escritas no swap de uma vez. No exemplo acima, o valor é definido como "16" de acordo com o tamanho do stripe (stripe size) RAID de 64 KB. Isso não faz sentido com swappiness = 0, mas se você definiu swappiness como 10 ou 20, o uso desse valor pode ajudá-lo quando o tamanho do stripe RAID é 64 KB.

blockdev --setra 4096 /dev/<devname> (-sdb, hdc ou dev_mapper)

As configurações padrão dos dispositivos de bloco para muitos controladores RAID frequentemente resultam em um desempenho terrível. A adição da opção acima configura a leitura antecipada para 4096 * 512 bytes setores. Pelo menos para operações sequenciais, a velocidade aumenta, preenchendo o cache embutido do disco por meio da leitura antecipada durante o período que o núcleo utiliza para preparar a E/S. Os dados que serão solicitados na próxima leitura podem ser armazenados no cache. Leituras antecipadas excessivas podem prejudicar a E/S aleatória para arquivos grandes, se utilizar potencialmente tempo útil do disco ou carregar dados para além do cache.

Aqui estão mais algumas recomendações a nível de sistema de arquivos. Mas elas ainda não foram testadas. Certifique-se de que seu sistema de arquivos conheça o tamanho do stripe e o número de discos na matriz. Por exemplo, que esta é uma matriz raid5 com um tamanho de stripe de 64K de seis discos (na verdade cinco, pois um disco é utilizado para paridade). Essas recomendações são baseadas em suposições teóricas e coletadas de vários blogs/artigos de especialistas em RAID.

-> ext4 fs, 5 discos, stripe de 64K, unidades em blocos de 4K
mkfs -text4 -E stride=$((64/4))
-> xfs, 5 discos, stripe de 64K, unidades em setores de 512 bytes
mkfs -txfs -d sunit=$((64*2)) -d swidth=$((5*64*2))

Para arquivos grandes, pode-se considerar aumentar os tamanhos de stripe mencionados acima.

ATENÇÃO! Tudo o que foi descrito acima é extremamente subjetivo para certos tipos de aplicativos. Este artigo não garante melhorias sem testes prévios dos aplicativos relevantes por parte do usuário. Deve ser aplicado somente se necessário para melhorar a responsividade geral do sistema ou se resolver problemas atuais.

Materiais adicionais:

Configuração do kernel Linux para GlusterFS

Leia mais

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster