A tradução do artigo foi preparada em antecipação ao início do curso .

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 —
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:
Leia mais
Fonte: habr.com
