Selección de un programador de E / S de Linux

82

Leí que supuestamente es posible cambiar el programador de E / S para un dispositivo en particular en un kernel en ejecución escribiendo en / sys / block / [disk] / queue / Scheduler. Por ejemplo, puedo ver en mi sistema:

anon@anon:~$ cat /sys/block/sda/queue/scheduler 
noop anticipatory deadline [cfq] 

que el predeterminado es el planificador de colas completamente justo. Lo que me pregunto es si es útil incluir los cuatro programadores en mi kernel personalizado. Parecería que no tiene mucho sentido tener más de un programador compilado a menos que el kernel sea lo suficientemente inteligente como para seleccionar el programador correcto para el hardware correcto, específicamente el programador 'noop' para unidades flash y uno de los otros para un dispositivo tradicional. disco duro.

¿Es este el caso?

Robert S. Barnes
fuente

Respuestas:

109

Como se documenta en /usr/src/linux/Documentation/block/switching-sched.txt, el programador de E / S en cualquier dispositivo de bloque en particular se puede cambiar en tiempo de ejecución. Puede haber algo de latencia ya que todas las solicitudes del programador anterior se vacían antes de poner en uso el nuevo programador, pero se puede cambiar sin problemas incluso cuando el dispositivo está sometido a un uso intensivo.

# 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, habría un solo programador para satisfacer todas las necesidades. No parece existir todavía. El kernel a menudo no tiene el conocimiento suficiente para elegir el mejor programador para su carga de trabajo:

  • noop es a menudo la mejor opción para dispositivos de bloque con respaldo de memoria (por ejemplo, discos RAM) y otros medios no rotacionales (flash) donde intentar reprogramar E / S es una pérdida de recursos
  • deadline es un programador ligero que intenta poner un límite estricto a la latencia
  • cfq intenta mantener la equidad en todo el sistema del ancho de banda de E / S

El valor predeterminado fue anticipatorydurante mucho tiempo, y recibió muchos ajustes, pero se eliminó en 2.6.33 (principios de 2010). cfqse convirtió en el predeterminado hace algún tiempo, ya que su rendimiento es razonable y la equidad es un buen objetivo para los sistemas multiusuario (e incluso los escritorios de un solo usuario). Para algunos escenarios, las bases de datos se utilizan a menudo como ejemplos, ya que tienden a tener sus propios patrones de acceso y programación peculiares, y a menudo son el servicio más importante (entonces, ¿a quién le importa la equidad?), anticipatoryTiene una larga historia de ser sintonizable. para obtener el mejor rendimiento en estas cargas de trabajo y deadlinepasa muy rápidamente todas las solicitudes al dispositivo subyacente.

efímero
fuente
1
¡Excelente información, gracias! Pero mi pregunta básica aún no tiene respuesta, si conecto una unidad flash o mi netbook se ejecuta desde una unidad flash como unidad principal, ¿el kernel es lo suficientemente inteligente como para elegir noop en lugar del cfq predeterminado? ¿O depende completamente de mí hacerlo manualmente?
Robert S. Barnes
3
Puede configurar el kernel para usar un programador diferente de forma predeterminada. Sería inteligente usarlo automáticamente noopen medios no rotacionales, pero el kernel no tiene esa funcionalidad. De alguna manera tiene detección de medios no rotacionales, pero no es confiable ya que algunos discos informan erróneamente de sí mismos y aún no está conectado al código del programador de E / S de todos modos.
Ephemient
8
Puede agregar reglas de udev para definir el programador en función de las características del dispositivo, como en el wiki de Debian ( wiki.debian.org/SSDOptimization#Low-Latency_IO-Scheduler ) # establecer el programador de fecha límite para discos no giratorios ACTION == "agregar | cambiar ", KERNEL ==" sd [az] ", ATTR {queue / rotational} ==" 0 ", ATTR {queue / Scheduler} =" deadline "
Dani_l
@Dani_l Deberías expandir eso y agregarlo como respuesta.
Robert S. Barnes
1
¿Hay alguna forma de cambiarlo para todas las unidades a la vez en tiempo de ejecución? Asimismo, estableciendo el programador predeterminado mediante el parámetro de línea de comandos del kernel "ascensor". Gracias.
SkyRaT
20

Es posible usar una regla udev para permitir que el sistema decida sobre el programador en función de algunas características del hw.
Un ejemplo de regla udev para SSD y otras unidades no rotacionales podría verse como

# set noop scheduler for non-rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop"

dentro de un nuevo archivo de reglas udev (por ejemplo, /etc/udev/rules.d/60-ssd-scheduler.rules). Esta respuesta se basa en la wiki de Debian.

Para verificar si los discos ssd usarían la regla, es posible verificar el atributo de activación por adelantado:

for f in /sys/block/sd?/queue/rotational; do printf "$f "; cat $f; done
Dani_l
fuente
Excelente respuesta para automatizar la detección de medios no rotacionales y aplicar el programador de E / S solo a esos. Se recomienda la fecha límite no solo para los medios que no giran. Oracle recomienda el programador io de fecha límite para cargas de trabajo de bases de datos. Esta recomendación de Oracle probablemente proviene del hecho de que la fecha límite puede manejar mejores escrituras sincrónicas que otros programadores de IO. Busque, por ejemplo, / sys / block / sdX / queue / iosched / writes_starved "fecha límite" programador sintonizable (no existe tal ajuste para lecturas). Las bases de datos pueden tener un rendimiento deficiente si sus rehacer escrituras sincrónicas no se realizan rápidamente.
Tagar
7

El objetivo de que el kernel admita otros diferentes es que pueda probarlos sin reiniciar; Luego, puede ejecutar cargas de trabajo de prueba a través del sistema, medir el rendimiento y luego convertirlo en el estándar para su aplicación.

En el hardware moderno de nivel de servidor, solo el noop uno parece ser útil. Los demás parecen más lentos en mis pruebas.

MarkR
fuente
¿Cómo lo cambia realmente en tiempo de ejecución?
Robert S. Barnes
El rendimiento de noop en relación con los demás programadores depende en gran medida del hardware y de la carga particular. Por curiosidad, ¿qué discos, controladores y pruebas estaba ejecutando?
ephemient
1
Sí, noop es bueno cuando tienes controladores RAID inteligentes y otras cosas en las que sabe más que el kernel sobre los mejores patrones de acceso. La fecha límite tampoco está mal.
Zan Lynx
1
Este es simplemente un ejercicio de aprendizaje para mí en el que estoy tratando de configurar el kernel de arranque más pequeño y más rápido posible que brinde toda la funcionalidad que necesito en mi computadora portátil. He mirado tanto en "Desarrollo de kernel de Linux" como en "Controladores de dispositivo de Linux esenciales" y no he encontrado una respuesta satisfactoria a esta pregunta, ¿qué tan inteligente es el kernel para elegir un Programador en tiempo de ejecución o simplemente usa siempre el predeterminado lo configuró manualmente en otra cosa?
Robert S. Barnes
ephemient> que estaba en los controladores DELL PERC, también en DELL Powervault MD3000. Parecía mejor que el predeterminado (CFQ) en ambos.
MarkR
0

Puede configurar esto en el arranque agregando el parámetro "ascensor" a la línea cmd del kernel (como en grub.cfg)

Ejemplo:

elevator=deadline

Esto hará que "deadline" sea el programador de E / S predeterminado para todos los dispositivos de bloque.

Si desea consultar o cambiar el programador después de que el sistema se haya iniciado, o si desea usar un programador diferente para un dispositivo de bloque específico, le recomiendo instalar y usar la herramienta ioschedset para facilitar esta tarea.

https://github.com/kata198/ioschedset

Si está en Archlinux, está disponible en aur:

https://aur.archlinux.org/packages/ioschedset

Algunos ejemplos 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

El uso debe ser autoexplicativo. Las herramientas son independientes y solo requieren bash.

¡Espero que esto ayude!

EDITAR: Descargo de responsabilidad, estos son los guiones que escribí.

Tim Savannah
fuente
-3

El kernel de Linux no cambia automáticamente el programador de E / S en tiempo de ejecución. Con esto quiero decir, el kernel de Linux, a día de hoy, no es capaz de elegir automáticamente un programador "óptimo" dependiendo del tipo de dispositivo de almacenamiento secundario. Durante el inicio o durante el tiempo de ejecución, es posible cambiar el planificador de E / S manualmente .

El planificador predeterminado se elige al inicio en función del contenido del archivo ubicado en /linux-2.6 /block/Kconfig.iosched . Sin embargo, es posible cambiar el planificador de E / S durante el tiempo de ejecución al echointroducir un nombre de planificador válido en el archivo ubicado en / sys / block / [DEV] / queue / planificador. Por ejemplo,echo deadline > /sys/block/hda/queue/scheduler

Codificación KZ
fuente
8
No entiendo por qué esta respuesta merece tantos votos negativos. En realidad, no es incorrecto.
DepressedDaniel