Linux - ajuste do controlador RAID de hardware do mundo real (scsi e cciss)

29

A maioria dos sistemas Linux que eu gerencio possui controladores RAID de hardware (principalmente o HP Smart Array ). Todos eles estão executando o RHEL ou o CentOS.

Estou procurando por ajustes do mundo real para ajudar a otimizar o desempenho de configurações que incorporam controladores RAID de hardware com discos SAS (Smart Array, Perc, LSI etc.) e cache com bateria ou com flash. Suponha RAID 1 + 0 e vários eixos (4 ou mais discos).

Eu gasto bastante tempo ajustando as configurações de rede Linux para aplicativos de negociação financeira e de baixa latência. Mas muitas dessas opções estão bem documentadas (alterando os buffers de envio / recebimento, modificando as configurações da janela TCP, etc.). O que os engenheiros estão fazendo no lado do armazenamento?

Historicamente, fiz alterações no elevador de agendamento de E / S , optando recentemente pelos agendadores deadlinee nooppara melhorar o desempenho em meus aplicativos. À medida que as versões RHEL progrediram, também observei que os padrões compilados dos dispositivos de bloco SCSI e CCISS também foram alterados. Isso teve um impacto nas configurações recomendadas do subsistema de armazenamento ao longo do tempo. No entanto, já faz um tempo desde que eu vi recomendações claras. E eu sei que os padrões do SO não são ideais. Por exemplo, parece que o buffer de leitura antecipada padrão de 128kb é extremamente pequeno para uma implantação em hardware de classe de servidor.

Os artigos a seguir exploram o impacto no desempenho da alteração dos valores de cache de leitura antecipada e nr_requests nas filas de blocos.

http://zackreed.me/articles/54-hp-smart-array-p410-controller-tuning
http://www.overclock.net/t/515068/tuning-a-hp-smart-array-p400-with -linux-why-tuning-really-important
http://yoshinorimatsunobu.blogspot.com/2009/04/linux-io-scheduler-queue-size-and.html

Por exemplo, são sugeridas alterações para um controlador HP Smart Array RAID:

echo "noop" > /sys/block/cciss\!c0d0/queue/scheduler 
blockdev --setra 65536 /dev/cciss/c0d0
echo 512 > /sys/block/cciss\!c0d0/queue/nr_requests
echo 2048 > /sys/block/cciss\!c0d0/queue/read_ahead_kb

O que mais pode ser ajustado com confiabilidade para melhorar o desempenho do armazenamento?
Estou procurando especificamente pelas opções sysctl e sysfs nos cenários de produção.

ewwhite
fonte

Respostas:

38

Descobri que, quando tive que ajustar a latência mais baixa versus a taxa de transferência, reduzi o nr_requests do padrão (para apenas 32). A ideia de ser lotes menores é igual a menor latência.

Também para read_ahead_kb, descobri que, para leituras / gravações sequenciais, aumentar esse valor oferece melhor taxa de transferência, mas descobri que essa opção realmente depende da carga de trabalho e do padrão de IO. Por exemplo, em um sistema de banco de dados que eu ajustei recentemente, alterei esse valor para corresponder a um único tamanho de página de banco de dados, o que ajudou a reduzir a latência de leitura. Aumentar ou diminuir além desse valor provou prejudicar o desempenho no meu caso.

Quanto a outras opções ou configurações para filas de dispositivos de bloco:

max_sectors_kb = Eu configurei esse valor para corresponder ao que o hardware permite uma única transferência (verifique o valor do arquivo max_hw_sectors_kb (RO) no sysfs para ver o que é permitido)

nomerges = isso permite desativar ou ajustar a lógica de pesquisa para mesclar solicitações io. (desativar isso pode economizar alguns ciclos de CPU, mas não vi nenhum benefício ao alterar isso para meus sistemas, então deixei o padrão)

rq_affinity = Ainda não tentei isso, mas aqui está a explicação por trás dos documentos do kernel

Se essa opção for '1', a camada de bloco migrará as conclusões da solicitação para o "grupo" da CPU que originalmente enviou a solicitação. Para algumas cargas de trabalho, isso fornece uma redução significativa nos ciclos da CPU devido aos efeitos de armazenamento em cache.
Para configurações de armazenamento que precisam maximizar a distribuição do processamento de conclusão, definir esta opção como '2' força a conclusão a ser executada na CPU solicitante (ignorando a lógica de agregação de "grupo") "

scheduler = você disse que tentou prazo e noop. Testei o noop e o prazo, mas descobri o prazo final para os testes que fiz recentemente para um servidor de banco de dados.

O NOOP teve um bom desempenho, mas para o nosso servidor de banco de dados eu ainda era capaz de obter melhor desempenho ajustando o agendador de prazos.

Opções para o planejador de prazos localizado em / sys / block / {sd, cciss, dm -} * / fila / iosched /:

fifo_batch = como nr_requests, mas específico para o planejador. A regra geral é ajustar isso para latência mais baixa ou aumento da taxa de transferência. Controla o tamanho do lote das solicitações de leitura e gravação.

write_expire = define o tempo de expiração dos lotes de gravação padrão: 5000ms. Mais uma vez, diminuir esse valor diminui a latência de gravação enquanto aumenta o valor aumenta a taxa de transferência.

read_expire = define o tempo de expiração dos lotes de leitura, o padrão é 500ms. As mesmas regras se aplicam aqui.

front_merges = Costumo desativar isso, e está ativado por padrão. Não vejo a necessidade do agendador desperdiçar ciclos da CPU tentando frontear solicitações de E / S.

write_starved = como o prazo é voltado para leituras, o padrão aqui é processar 2 lotes de leitura antes que um lote de gravação seja processado. Eu achei o padrão 2 bom para minha carga de trabalho.

rtorti19
fonte
7
... e é assim que você publica sua primeira resposta em um site. Bem feito!
Jeff Ferland
1
É um bom começo e a execução de testes repetidos em condições controladas me ajudou a ajustar um pouco o desempenho do aplicativo. Também é útil ver como posso ajustar o armazenamento para tendências gerais de carga de trabalho.
ewwhite
4

Mais do que tudo, tudo depende da sua carga de trabalho.

read_ahead_kbpode ajudá-lo se for realmente útil ler muitos dados de algum arquivo com antecedência, como ao transmitir vídeo. Às vezes isso pode te machucar muito. Sim, os 128 KB padrão podem parecer pequenos, mas com simultaneidade suficiente começam a parecer grandes! Por outro lado, com um servidor como um servidor de codificação de vídeo que apenas converte os vídeos de um formato para outro, pode ser uma boa ideia ajustar.

nr_requests, quando atenuado, pode facilmente inundar seu controlador RAID, o que prejudica novamente o desempenho.

No mundo real, você precisa observar as latências . Se você está conectado à SAN, dê uma olhada com iostat, sarou o que você gostaria de usar, e veja se os tempos pedido I / O de serviços são através do telhado. É claro que isso também ajuda com os discos locais: se as latências forem muito grandes, considere ajustar as configurações do elevador de E / S fazendo o downgrade de max_requests e outras configurações.

Janne Pikkarainen
fonte
Quais outras configurações?
ewwhite
4

FYI read_ahead_kbe blockdev --setrasão apenas maneiras diferentes de definir a mesma configuração usando unidades diferentes (kB x setores):

foo:~# blockdev --setra 65536 /dev/cciss/c0d0
foo:~# blockdev --getra /dev/cciss/c0d0
65536
foo:~# cat /sys/block/cciss\!c0d0/queue/read_ahead_kb
32768
foo:~# echo 2048 > /sys/block/cciss\!c0d0/queue/read_ahead_kb
foo:~# cat /sys/block/cciss\!c0d0/queue/read_ahead_kb
2048
foo:~# blockdev --getra /dev/cciss/c0d0
4096

Então o

blockdev --setra 65536 /dev/cciss/c0d0

no seu exemplo não tem efeito.

ntherning
fonte