Selecionando um O Scheduler / Linux I
-
06-07-2019 - |
Pergunta
Eu li que é supostamente possível mudar o I / O programador para um dispositivo específico em um kernel em execução, escrevendo para / sys / block / [disco] / queue / scheduler. Por exemplo, eu posso ver no meu sistema:
anon@anon:~$ cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]
que o padrão é o programador filas completamente justo. O que eu estou querendo saber é se existe alguma utilidade em incluir todos os quatro programadores no meu kernel personalizado. Parece que não há muito sentido em ter mais de um programador compilado a menos que o kernel é bastante inteligente para selecionar o programador correto para o hardware correto, especificamente o 'noop' agendador para drives flash baseado e um dos outros para um tradicional disco rígido.
É este o caso?
Solução
Como documentado em /usr/src/linux/Documentation/block/switching-sched.txt
, o I / o programador em qualquer dispositivo bloco específico pode ser alterado em tempo de execução. Pode haver alguma latência como pedidos do agendador anterior são liberadas antes de trazer o novo programador em uso, mas pode ser alterado sem problemas, mesmo quando o dispositivo está em uso pesado.
# cat /sys/block/hda/queue/scheduler
noop deadline [cfq]
# echo anticipatory > /sys/block/hda/queue/scheduler
# cat /sys/block/hda/queue/scheduler
noop [deadline] cfq
Idealmente, haveria um único programador para satisfazer todas as necessidades. Não parece existir ainda. O kernel muitas vezes não tem conhecimento suficiente para escolher o melhor programador para sua carga de trabalho:
-
noop
é muitas vezes a melhor escolha para dispositivos de bloco lastreados em memória (por exemplo ramdisks) e outros meios de comunicação não-rotacionais (flash), onde a tentar reagendar I / O é um desperdício de recursos -
deadline
é um agendador de leve, que tenta colocar um limite rígido sobre a latência -
cfq
tenta manter a imparcialidade de todo o sistema de I / O bandwidth
O padrão foi anticipatory
por um longo tempo, e recebeu um monte de ajuste, mas foi removido em 2.6.33 (início de 2010). cfq
tornou-se o padrão algum tempo atrás, como seu desempenho é razoável e justiça é uma boa meta para sistemas multi-usuário (e até mesmo desktops de usuário único). Para alguns cenários - bancos de dados são frequentemente utilizados como exemplos, como eles tendem a já têm seus próprios padrões de agendamento peculiar e de acesso, e são muitas vezes o mais serviço importante (para quem se preocupa com a justiça?) - anticipatory
tem uma longa história de ser ajustável para melhor desempenho nestas cargas de trabalho, e deadline
passa muito rapidamente todos os pedidos até o dispositivo subjacente.
Outras dicas
É possível utilizar uma regra udev para deixar o sistema decidir sobre o programador com base em algumas características do hw.
Uma regra de exemplo udev para SSDs e outras unidades não rotativas, pode parecer
# set noop scheduler for non-rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop"
dentro de um novo arquivo de regras do udev (por exemplo, /etc/udev/rules.d/60-ssd-scheduler.rules
). Essa resposta é baseada na debian wiki
Para verificar se os discos SSD usaria a regra, é possível verificar o atributo gatilho com antecedência:
for f in /sys/block/sd?/queue/rotational; do printf "$f "; cat $f; done
O objetivo de ter o apoio do kernel os diferentes é que você pode experimentá-los sem uma reinicialização; então você pode executar cargas de trabalho de teste através do sytsem, medir o desempenho, e depois que o padrão para seu aplicativo fazer.
No hardware moderno servidor-grade, apenas o noop parece ser em tudo útil. Os outros parecem mais lento em meus testes.
Você pode definir esta na inicialização, adicionando o parâmetro "elevador" para o cmdline kernel (como em grub.cfg)
Exemplo:
elevator=deadline
Isso fará com que "deadline" o padrão I / O programador para todos os dispositivos de bloco.
Se você gostaria de consulta ou alterar a agenda após a inicialização do sistema, ou gostariam de usar um programador diferente para um dispositivo de bloco específico, eu recomendo instalar e usar a ferramenta ioschedset para fazer isso fácil.
https://github.com/kata198/ioschedset
Se você estiver em Archlinux ele está disponível em aur:
https://aur.archlinux.org/packages/ioschedset
Alguns exemplo de uso:
# Get i/o scheduler for all block devices
[username@hostname ~]$ io-get-sched
sda: bfq
sr0: bfq
# Query available I/O schedulers
[username@hostname ~]$ io-set-sched --list
mq-deadline kyber bfq none
# Set sda to use "kyber"
[username@hostname ~]$ io-set-sched kyber /dev/sda
Must be root to set IO Scheduler. Rerunning under sudo...
[sudo] password for username:
+ Successfully set sda to 'kyber'!
# Get i/o scheduler for all block devices to assert change
[username@hostname ~]$ io-get-sched
sda: kyber
sr0: bfq
# Set all block devices to use 'deadline' i/o scheduler
[username@hostname ~]$ io-set-sched deadline
Must be root to set IO Scheduler. Rerunning under sudo...
+ Successfully set sda to 'deadline'!
+ Successfully set sr0 to 'deadline'!
# Get the current block scheduler just for sda
[username@hostname ~]$ io-get-sched sda
sda: mq-deadline
Uso deve ser auto-explicativo. As ferramentas são autônomos e necessita apenas de bash.
Espero que isso ajude!
EDIT: Disclaimer, estes são scripts que eu escrevi
.O Linux Kernel não muda automaticamente o IO Scheduler em tempo de execução. Com isto quero dizer, o kernel Linux, a partir de hoje, não é capaz de escolher automaticamente um programador "ideal", dependendo do tipo de legado de armazenamento secundário. Durante o arranque, ou durante o tempo de execução, é possível alterar a agenda de IO manualmente .
O agendador padrão é escolhido no arranque com base no conteúdo do arquivo localizado na /linux-2.6 /block/Kconfig.iosched . No entanto, é possível alterar a agenda de IO durante o tempo de execução por echo
ing um nome programador válida para o arquivo localizado em / sys / block / [DEV] / queue / scheduler. Por exemplo, echo deadline > /sys/block/hda/queue/scheduler