Planificadores de Entrada/Salida en Linux.

Autor: Joel Barrios Dueñas
Correo electrónico: darkshram en gmail punto com
Sitio de Red: http://www.alcancelibre.org/
Jabber ID: darkshram@jabber.org

Creative Commons Reconocimiento-NoComercial-CompartirIgual 2.1

© 1999-2015 Joel Barrios Dueñas. Usted es libre de copiar, distribuir y comunicar públicamente la obra y hacer obras derivadas bajo las condiciones siguientes: a) Debe reconocer y citar al autor original. b) No puede utilizar esta obra para fines comerciales (incluyendo su publicación, a través de cualquier medio, por entidades con fines de lucro). c) Si altera o transforma esta obra o genera una obra derivada, sólo puede distribuir la obra generada bajo una licencia idéntica a ésta. Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de esta obra. Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor. Los derechos derivados de usos legítimos u otras limitaciones no se ven afectados por lo anterior. Licencia completa en castellano. La información contenida en este documento y los derivados de éste se proporcionan tal cual son y los autores no asumirán responsabilidad alguna si el usuario o lector hace mal uso de éstos.

Introducción.

¿Qué son los planificadores de entrada/salida?

La planificación de Entrada/Salida (Input/Output Scheduling o I/O scheduling) consiste en el método mediante el cual los sistemas operativos deciden el orden en que se procesan las peticiones de lectura/escritura en el disco duro o unidad de almacenamiento. Elegir un algoritmo de planificación de Entrada/salida tiene como objetivo disminuir los tiempos de búsqueda (seek times), priorizar las peticiones de ciertos procesos de Entrada/Salida, asignar un ancho de banda más adecuado a cada proceso o garantizar que algunas peticiones se atenderán antes de una fecha de caducidad. Básicamente se diseñó para mitigar la demora de los tiempos de búsqueda que utilizan el brazo y el cabezal de los disco duros para moverse desde una posición hacia otra más alejada.

La mayoría de los planificadores de Entrada/Salida (I/O schedulers) se basan sobre el algoritmo del elevador, el cual determina el movimiento del brazo de un disco y cabezal al servir peticiones de lectura/escritura. Este algoritmo basa su nombre sobre el comportamiento del elevador de un edificio, donde éste continúa su trayectoria actual hacia arriba o hacia abajo hasta que éste se vacía por completo, deteniéndose sólo para permitir que nuevos individuos lo aborden siempre que éstos vayan en la misma dirección actual del elevador.

Planificadores de Entrada/Salida disponibles en el núcleo de Linux.

Anticipatory.

Tiene como objetivo incrementar la eficiencia de la utilización del disco duro al anticipar las operaciones sincrónicas de lectura. Fue el planificador de Entrada/Salida predeterminado del núcleo de Linux desde la versión 2.6.0 hasta la versión 2.6.18. Fue eliminado del núcleo de Linux a partir de la versión 2.6.33, debido a que hoy en día hay muy pocas unidades de almacenamiento basadas sobre los estándares SCSI-1 y IDE/ATA y que aún estén en operación.

Era ideal para servidores HTTP o sistemas de Escritorio con discos duros SCSI-1 o IDE/ATA, pues se lograba un rendimiento superior.

Funciona realizando una demora controlada antes de despachar los procesos de Entrada/Salida para agregar o re-ordenar las operaciones de búsqueda, mejorando el desempeño y reduciendo de manera significativa las operaciones de petición de los discos duros. Está diseñado específicamente para optimizar los sub-sistemas de discos pequeños o bien muy lentos, como es el caso de discos duros con estándar SCSI-1 y algunos antiguos modelos de IDE/ATA.

Es totalmente inadecuado para discos duros modernos, pues éstos utilizan TCQ (Tagged Command Queuing), que es una tecnología consiste en la optimización de peticiones de lectura/escritura desde la propia unidad de disco duro y permiten realizar múltiples peticiones de lectura/escritura. Esta tecnología es utilizada en los discos duros con el estándar SCSI-2, PATA y SATA, es decir todos los modernos disco duros que existen hoy en día en el mercado. Es totalmente inapropiado para unidades de almacenamiento de alto desempeño, así como con arreglos de discos por RAID.

Asumiendo que se está ejecutando CentOS 6 y Red Hat™ Enterprise Linux 6 —y versiones posteriores de éstos— y que se dispone de un disco duro basado sobre el estándar SCSI-1 o bien IDE/ATA que se ha asignado como el dispositivo /dev/sda, este planificador de Entrada/Salida puede aplicarse de manera inmediata ejecutando:

echo "anticipatory" > /sys/block/sda/queue/scheduler

Lo anterior hará que el sistema utilice este planificador de Entrada/Salida hasta el siguiente reinicio. Verifique que realmente se ha establecido como el planificador de Entrada/Salida actual ejecutando lo siguiente:

cat /sys/block/sda/queue/scheduler

Lo anterior debe devolver una salida similar a la siguiente:

[anticipatory] noop deadline cfq

Para hacer el cambio permanente en CentOS 6 y Red Hat™ Enterprise Linux 6 —y versiones anteriores de éstos—, edite el archivo /boot/grub/menu.lst:

vi /boot/grub/menu.lst

Añada a los argumentos de inicio del núcleo la opción elevator, con el valor anticipatory. Ejemplo:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$xU.tiAbo$5a88IZ2yKPvtdYG5ldAmi/
title centos (2.6.32-504.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=UUID=09c6dc39-a62b-409e-8306-5344640cd104 rd_LVM_LV=Swap/LogVol00 rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=es_MX.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=la-latin1 crashkernel=auto rhgb quiet elevator=anticipatory
        initrd /initramfs-2.6.32-504.el6.x86_64.img

CFQ.

CFQ —acrónimo de Completely Fair Queuing o encolado de procesamiento completamente justo— es el planificador de Entrada/Salida predeterminado de CentOS y Red Hat™ Enterprise Linux. Brinda un rendimiento superior para la mayoría de los usos que se le pueda dar al sistema operativo.

Su objetivo es mantener una cola de procesamiento de Entrada/Salida escalable y por proceso que intenta distribuir equitativamente el ancho de banda disponible entre todas las peticiones de Entrada/Salida.

Realiza peticiones sincrónicas enviadas por un proceso dentro de un número de colas de procesamiento por proceso y luego distribuyendo intervalos de tiempo para cada una de las colas de procesamiento. La longitud de estos intervalos —así como el número de peticiones que tiene permitido una cola de procesamiento— depende de la prioridad del mismo procesos de Entrada/Salida. De este modo, las peticiones asincrónicas para todos los procesos son agrupadas y procesadas en menos colas de procesamientos, asignando una por prioridad.

Funciona de modo similar al planificador Anticipatory, es decir manteniendo una buena capacidad de procesamiento al permitir que las colas de procesamiento puedan pausar al finalizar un proceso de Entrada/Salida y anticipando la petición más cercana de ese mismo proceso.

Puede verificar que CFQ es el planificador de Entrada/Salida predeterminado ejecutando lo siguiente:

cat /sys/block/sda/queue/scheduler

Lo anterior debe devolver una salida similar a la siguiente:

[cfq] anticipatory noop deadline

Sólo mantenga o restaure la configuración predeterminada del gestor de arranque para utilizar este planificador.

Deadline.

Funciona de modo similar al tiempo real. Utiliza una política de asignación en circuito (round robin) que intenta distribuir equitativamente las peticiones de Entrada/Salida, evitando se agote la capacidad de procesamiento.

Básicamente impone tiempos de caducidad (deadline) a todas las operaciones de Entrada/Salida a fin de impedir que se agote la capacidad de recibir peticiones. Utiliza cinco colas de procesamiento, dos de las cuales son ordenadas de acuerdo a los tiempos de caducidad, al mismo tiempo que las colas de procesamiento son ordenadas de acuerdo a su número de sector.

Antes de servir la siguiente petición, el algoritmo decide que cola de procesamiento utilizar, otorgando mayor prioridad a las peticiones de lectura, verificando después si ha caducado la primera petición en la cola de procesamiento.

De modo predeterminado los tiempos de caducidad son de 500 ms para las peticiones de lectura y de 5 segundos para las peticiones de escritura.

Se recomienda su uso para servidores dedicados para bases de datos y particularmente para aquellos sistemas que disponen de discos duros con capacidad de TCQ, así como en sistemas con unidades de almacenamiento de alto desempeño, es decir discos duros con el estándar SCSI-2, PATA o SATA

Asumiendo que se dispone de un disco duro o unidad de almacenamiento, que se ha asignado como el dispositivo /dev/sda, este planificador de Entrada/Salida puede aplicarse de manera inmediata ejecutando:

echo "deadline" > /sys/block/sda/queue/scheduler

Lo anterior hará que el sistema utilice este planificador de Entrada/Salida hasta el siguiente reinicio. Verifique que realmente se ha establecido como el planificador de Entrada/Salida actual ejecutando:

cat /sys/block/sda/queue/scheduler

Lo anterior debe devolver una salida similar a la siguiente:

[deadline] anticipatory noop cfq

Para hacer el cambio permanente en ALDOS 1.4, CentOS 6 y Red Hat™ Enterprise Linux 6 —y versiones anteriores de éstos—, edite el archivo /boot/grub/menu.lst:

vi /boot/grub/menu.lst

Añada a los argumentos de inicio del núcleo la opción elevator, con el valor deadline. Ejemplo:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$xU.tiAbo$5a88IZ2yKPvtdYG5ldAmi/
title centos (2.6.32-504.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=UUID=09c6dc39-a62b-409e-8306-5344640cd104 rd_LVM_LV=Swap/LogVol00 rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=es_MX.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=la-latin1 crashkernel=auto rhgb quiet elevator=deadline
        initrd /initramfs-2.6.32-504.el6.x86_64.img

Para hacer el cambio permanente en CentOS 7 y Red Hat™ Enterprise Linux 7 —y versiones posteriores de éstos—, edite el archivo /etc/default/grub:

vi /etc/default/grub

Añada a los argumento de inicio del núcleo la opción elevator, con el valor deadline. Ejemplo:

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="vconsole.font=latarcyrheb-sun16 crashkernel=auto rhgb quiet elevator=deadline"
GRUB_DISABLE_RECOVERY="true"

Ejecute lo siguiente para aplicar el cambio en la configuración de Grub2:

grub2-mkconfig -o /boot/grub2/grub.cfg

Noop.

Es el planificador de Entrada/Salida más simple que existe. Funciona insertando todas las peticiones de Entrada/Salida dentro de una cola de procesamiento tipo FIFO (first in, first out, que se traduce como primero en entrar, primero en salir) e implementando fusión de peticiones.

Asume que la optimización del desempeño de Entrada/Salida será gestionada por otro nivel de la jerarquía de Entrada/Salida, como pudiera ser en el dispositivo de bloque o bien un HBA (Host Bus Adapter o adaptador de transporte del anfitrión) inteligente, como en el caso en los controladores RAID para SAS (Serial Attached SCSI) o bien un controlador conectado de manera externa, como ocurre con los SAN (Storage Area Network o Redes de Área de Almacenamiento).

Se utiliza principalmente con unidades de estado sólido (SSD, Solid State Drives) basadas sobre memoria Flash, NAND o SDRAM y en dispositivos que carecen de dependencia a movimientos mecánicos y que carecen de re-ordenamiento de peticiones múltiples de Entrada/Salida, donde éstas pudieran agruparse todas las que están físicamente cercanas reduciendo el tiempo de petición y la variabilidad del tiempo de servicio de Entrada/Salida.

Asumiendo que se dispone de un disco duro o unidad de almacenamiento que se ha asignado como el dispositivo /dev/sda, este planificador de Entrada/Salida puede aplicarse de manera inmediata ejecutando:

echo "noop" > /sys/block/sda/queue/scheduler

Lo anterior hará que el sistema utilice este planificador de Entrada/Salida hasta el siguiente reinicio. Verifique que realmente se ha establecido como el planificador de Entrada/Salida actual ejecutando:

cat /sys/block/sda/queue/scheduler

Lo anterior debe devolver una salida similar a la siguiente:

[noop] anticipatory deadline cfq

Para hacer el cambio permanente en ALDOS 1.4, CentOS 6 y Red Hat™ Enterprise Linux 6 —y versiones anteriores de éstos—, edite el archivo /boot/grub/menu.lst:

vi /boot/grub/menu.lst

Añada a los argumento de inicio del núcleo la opción elevator, con el valor noop. Ejemplo:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$xU.tiAbo$5a88IZ2yKPvtdYG5ldAmi/
title centos (2.6.32-504.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=UUID=09c6dc39-a62b-409e-8306-5344640cd104 rd_LVM_LV=Swap/LogVol00 rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=es_MX.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=la-latin1 crashkernel=auto rhgb quiet elevator=noop
        initrd /initramfs-2.6.32-504.el6.x86_64.img

Para hacer el cambio permanente en CentOS 7 y Red Hat™ Enterprise Linux 7 —y versiones posteriores de éstos—, edite el archivo /etc/default/grub:

vi /etc/default/grub

Añada a los argumento de inicio del núcleo la opción elevator, con el valor noop. Ejemplo:

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="vconsole.font=latarcyrheb-sun16 crashkernel=auto rhgb quiet elevator=noop"
GRUB_DISABLE_RECOVERY="true"

Ejecute lo siguiente para aplicar el cambio en la configuración de Grub2:

grub2-mkconfig -o /boot/grub2/grub.cfg

¿Cuál planificador de Entrada/Salida elegir?

Depende del tipo de unidad(es) de almacenamiento, servicios utilizados en el sistema, capacidades de procesamiento y los tipos de procesos que se quieran priorizar.

En general, se puede utilizar:

Se recomienda realizar pruebas de desempeño y de rendimiento, antes de elegir el planificador de Entrada/salida definitivo para un sistema en particular. Elija el que se considere que funcione mejor.

Bibliografía.