Descobri que, quando tive que sintonizar uma baixa latência versus uma taxa de transferência, afinei nr_requests do padrão (para um valor tão baixo quanto 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 E / S. 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 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 este valor para combinar com o que o hardware permite para uma única transferência (verifique o valor do arquivo max_hw_sectors_kb (RO) em sysfs para ver o que é permitido)
nomerges = isso permite desabilitar ou ajustar a lógica de pesquisa para mesclar as solicitações do io. (desligar isso pode economizar alguns ciclos de cpu, mas eu não vi nenhum benefício ao mudar isso para os meus sistemas, então deixei o padrão)
rq_affinity = Eu não tentei isso ainda, mas aqui está a explicação por trás dele a partir dos documentos do kernel
If this option is '1', the block layer will migrate request completions to the cpu "group" that originally submitted the request. For some workloads this provides a significant reduction in CPU cycles due to caching effects.
For storage configurations that need to maximize distribution of completion processing setting this option to '2' forces the completion to run on the requesting cpu (bypassing the "group" aggregation logic)"
scheduler = você disse que tentou o prazo e o noop. Eu testei tanto o noop quanto o prazo, mas encontrei o prazo final para os testes que fiz recentemente para um servidor de banco de dados.
O NOOP teve um bom desempenho, mas para nosso servidor de banco de dados eu ainda consegui obter um melhor desempenho ajustando o agendador de prazos.
Opções para o planejador de prazo localizado em / sys / block / {sd, cciss, dm -} * / queue / iosched /:
fifo_batch = como nr_requests, mas específico para o agendador. A regra prática é ajustá-la para baixa latência ou para taxa de transferência. Controla o tamanho do lote de solicitações de leitura e gravação.
write_expire = define o tempo de expiração para o padrão de gravação de lotes é de 5000 ms. Mais uma vez, diminuir esse valor diminui sua latência de gravação enquanto aumenta o valor aumenta a taxa de transferência.
read_expire = define o tempo de expiração para o padrão de leitura de lotes é de 500 ms. As mesmas regras se aplicam aqui.
front_merges = Eu tenho a tendência de desativar isso e está ativado por padrão. Eu não vejo a necessidade de o agendador desperdiçar ciclos de CPU tentando fazer frente às solicitações de IO.
writes_starved = desde que o prazo final é direcionado para leituras, o padrão aqui é processar 2 lotes de leitura antes que um lote de gravação seja processado. Eu encontrei o padrão de 2 para ser bom para minha carga de trabalho.