O comportamento padrão de 'nice' é ajustar a prioridade 'io' do aplicativo também quando a gentileza muda.
Obviamente, tudo depende da sua carga de trabalho, mas um dos principais aspectos de qualquer sistema operacional é como ele aloca seus recursos e como ele lida com disputas .
É realmente importante entender o que a gentileza faz porque, quando está sob carga de processos concorrentes, a maneira como o sistema operacional se comporta pode ter um impacto no restante de sua carga de trabalho.
A contenção é a medida de como diferentes aplicativos competem pelo mesmo recurso (como CPU).
Movimentação de carga
Desde que o agendador completamente justo foi introduzido, nice é apenas uma interface para a cláusula 'peso' de cada processo. Que pode ser visto em proc.
$ cat /proc/self/sched
---------------------------------------------------------
...
se.load.weight : 1024
...
Mudar a gentileza apenas altera o peso:
$ nice -n 5 cat /proc/self/sched
---------------------------------------------------------
...
se.load.weight : 335
...
A medida para contenção de CPU é feita pelo algoritmo de programação completamente justo. Cada aplicativo recebe um valor de 'peso' e, no caso de tempo de CPU rival, o tempo é dividido entre processos, totalizando todo o processamento disputado pelo tempo de CPU e atribuindo a eles o menor tempo de CPU de denominação comum com base em seu valor de peso.
Se eu tenho 3 aplicativos, todos querendo usar o tempo da CPU, por padrão, eles recebem 1024 como o peso normal. Se eu tiver um processo com um bom +5 como acima, todos os três pesos serão totalizados em 2383, o processo niced receberá, portanto, cerca de 15% do tempo da CPU em um determinado segundo, se todos os três processos estiverem solicitando a CPU nesse segundo .
Por que é necessário ter diferentes prioridades de CPU e IO?
A gentileza realmente está apenas brincando com o que fazer quando o sistema está sob carga, ou seja - como o sistema operacional divide o tempo entre processos concorrentes, conforme definido por quaisquer fatores necessários.
O modo como isso afeta ou é relevante para você é limitado por quais prioridades de entrega diferentes aplicativos têm entre si e pelo tempo necessário para entregar cada aplicativo.
A gentileza realmente faz algo apenas quando o sistema está sob carga (há mais coisas que requerem atenção do que a CPU ou o disco pode suportar). Apenas instrui o kernel como alocar recursos nessas circunstâncias.
Existe algum uso no mundo real para tê-los diferentes?
Se você possui vários processos concorrentes ou trabalho a ser feito além do que pode ser feito pela CPU, a gentileza oferece algumas garantias relativamente estáveis quanto ao trabalho finalizado primeiro. Isso pode ser importante para você, se você diz produzir um relatório que deve ser entregue antes que outro relatório seja concluído.
Em um sistema de desktop, a gentileza pode ser ainda mais importante. Certos aplicativos têm um comportamento em tempo real, pelo qual eles são ativados com mais frequência durante o carregamento, impedindo que os dados fiquem obsoletos. O Pulseaudio se enquadra nessa categoria, por exemplo.
Podem ser necessários outros aplicativos para distribuir o trabalho para aplicativos dependentes. Por exemplo, muitas solicitações do apache para dizer que um servidor SQL como o MySQL pode bloquear por um longo período de tempo porque o SQL não está servindo rápido o suficiente porque - digamos que outro relatório esteja competindo pelo tempo da CPU. Portanto, não apenas o SQL está parado, mas o Apache. Às vezes, o SQL pode prejudicar aqui, porque geralmente há muito menos threads de trabalho que os threads do apache que competem como um grupo para serem pesados de forma mais favorável pelo planejador, portanto, dando mais tempo de CPU ao SQL reduz as coisas.
O UpdateDB (um programa que indexa arquivos) é executado tarde da noite e é muito pesado em disco. Pode ser útil reduzir sua prioridade de programação de E / S para que outros aplicativos naquele momento tenham prioridade sobre algo que não é tão importante na ordem das coisas.
Que casos de uso do mundo real você encontrou que precisam de diferentes prioridades de CPU e IO?
Muito pouco. A gentileza é uma abordagem de melhor esforço. Como regra geral, eu me importar menos sobre o quão bem as aplicações executar e mais sobre o quanto eles poderiam executar. Isso pode parecer inverso no começo, mas tenho garantias de prestação de serviços para atender às mais importantes para mim.
Quero que a confiança diga "suas coisas, mesmo em um dia ruim, serão feitas no período X". Se for mais rápido, é apenas um bônus.
Normalmente, começarei gerando especificações acordadas, como:
- É garantido que todos os aplicativos da Web concluam solicitações em 0,3 segundos.
- Todas as solicitações SQL em um sistema são garantidas para serem concluídas em 0,1 segundos.
- O aplicativo da Web deve lidar com não mais que 50 IOPS e entregar arquivos de 1k.
- A pegada de memória dos aplicativos da web não ultrapassa 250Mb no total.
E elabore requisitos para atender como:
- Todas as solicitações da web devem ser concluídas em 0,05 segundos.
- Todas as solicitações SQL devem ser concluídas em 0,02 segundos.
- Deve haver memória suficiente para lidar com todos os pedidos.
- Os requisitos de IO devem ser atendidos.
Desde que as especificações sejam verdadeiras, eu atendo a esses objetivos sem fazer virtualização, usando a abordagem muito mais eficiente dos grupos de controle.
Grupos de controle permitem que eu garanta garantias de nível de serviço bastante confiáveis para alocação de recursos, desde que o aplicativo se comporte dentro dos limites especificados. Isso significa que, mesmo em um sistema sob carga, posso garantir a disponibilidade de recursos para o aplicativo em questão e garantir espaço para outros aplicativos na mesma caixa!
Se dermos o seu exemplo de CPU e E / S. Estabeleci limites que atendem a esses requisitos:
# cd /sys/fs/cgroup/blkio/apache
# echo "253:0 100" >blkio.throttle.read_iops_device
# echo "253:0 50" >blkio.throttle.write_iops_device
# echo "253:0 102400" >blkio.throttle.read_bps_device
Então, 100k bytes para ler 100 iops.
# cd /sys/fs/cgroup/cpu/apache
# echo 1000000 >cpu.cfs_period_us
# echo 60000 >cpu.cfs_quota_us
De um período de 1 segundo, dê 0,06 segundos de CPU.
# cd /sys/fs/cgroup/cpu/sql
# echo 1000000 >cpu.cfs_period_us
# echo 20000 >cpu.cfs_quota_us
De um período de 1 segundo, dê 0,02 segundos de CPU.
Fornecer outros cgroups concorrentes não faz nada bobo, estar sob carga é menos um fator na minha prestação de serviços, porque eu sei como a CPU está sendo lançada para cada aplicativo.
Grupos de controle dessa natureza ainda são o melhor esforço, mas oferecem muito mais controle sobre esse esforço do que a gentileza e a ionicidade.