====== Mejorar el rendimiento frente a problemas de entrada salida a disco (I/O Waits) en GNU/Linux ====== **Consejos para aumentar el rendimiento en operaciones de lectura / escritura a disco**. * Posiblemente optimización de la aplicación problemática (uso de cache, retrasar escrituras a disco, etc.). * Monitorizar la paginacición de los procesos ([[nociones_basicas_sobre_la_memoria#paginas|leer]]). * Usar discos RAID / SSD y sistemas de fichero en espejo como ZFS. * Usar particiones / discos como solo lectura. * Utilizar en fstab o al montar la unidad opciones como "noatime/nodiratime/relatime". * Modificar el valor de "I/O elevator" ([[http://www.redhat.com/magazine/008jun05/features/schedulers/|Leer]] / [[http://algo.ing.unimo.it/people/paolo/disk_sched/|BFQ]]). * Utilizar RAM en vez del disco duro (Ramdisk). * Opciones de optimización para el sistema de ficheros en uso (Ejemplo Ext4: data=writeback, barrier,nobh, etc). * Logs de aplicaciones no muy informativos. * Opciones del Kernel relacionadas con el mapeo y paginación de la cache (vm.dirty_ratio / vm.dirty_background_ratio). * Priorizar actividad I/O de los procesos con ionice. * Quizás en algunos casos dar prioridad a determinados procesos con nice / renice / cgroups pueda ayudar. * Contemplar el uso de herramientas como Zswap / zRAM. * Cuando el problema I/O es en servidores git, probar a optimizar los repositorios con "git gc". * Al programar, utilizar funciones respetuosas con las operaciones de entrada salida (pread(2)/pwrite(2) en vez de lseek(2),mmap(2), etc). ==== Opciones del Kernel para mejorar I/O ==== Variable y valor por defecto en Centos 6.5. * vm.swappiness (10) * vm.vfs_cache_pressure (100) * vm.dirty_ratio (20) * vm.dirty_background_ratio (10) * vm.dirty_expire_centisecs (3000) * vm.dirty_writeback_centisecs (500) Se debe aclarar que el término "memoria sucia" hace referencia a los datos en memoria RAM que han sido modificados,cuando se escribe sobre un fichero, primeramente esto sucede en RAM y posteriormente se escribe a disco generandose una espera. Cambiar la velocidad con la que los cambios son escritos a disco puede repercutir en mejoras de rendimiento en cuanto a I/O. Otro termino concurrente es "Writeback", es el proceso de escribir datos de la RAM al disco, y regular en este contexto significa bloquear procesos temporalmente para evitar que creen nuevos datos que escribir, hasta que los datos actuales hayan sido escritos en el disco. **vm.swappiness** y **vm.vfs_cache_pressure**: [[optimizacion_de_memoria_ram_en_linux|Leer]] **vm.dirty_ratio** :Porcentaje total de la memoria que describe el número de páginas sucias que un proceso puede generar antes de que estas se escriban a disco. Recomendable aumentar su valor en servidores con mucha mejoria RAM. **vm.dirty_background_ratio**: Porcentaje total de la memoria que describe el número de páginas sucias permitidas antes de que pdflush/flush/kdmflush lo pasen a disco. **vm.dirty_background_bytes** y **vm.dirty_bytes** son otra forma de especificar los parámetros de síntesis. Si establece la versión _bytes la versión _ratio se convertirá en 0, y vice-versa. **vm.dirty_expire_centisecs** Es el tiempo que algo puede estar en caché antes de que necesite ser escrito. pdflush/flush/kdmflush comprueban la edad de esas páginas sucias y las escriben a disco. **vm.dirty_writeback_centisecs**: Establece la frecuencia con la que pdflush/flush/kdmflush deben comprobar esas páginas sucias. NOTA: Para que la modificación de esos valores sea efectiva se deben escribir en ///etc/sysctl.conf//. **Comandos de interés para monitorizar la memoria sucia**. watch grep ^Cached /proc/meminfo # Page Cache size. watch grep dirty /proc/meminfo # Dirty pages size. watch grep -A 1 dirty /proc/vmstat # Dirty Pages and writeback to disk activity. watch cat /proc/sys/vm/nr_pdflush_threads # shows of active pdflush threads. ==== Tipos de journaling ==== **Writeback**: //data=writeback// : Solo se realiza journal de la metainformación NO de los datos, es el sistema de journaling mas rápido pero el menos aconsejable a la hora de preservar la información frente a fallas, normalmente de alimentación. Primero escribe la metainformación en el journal, luego en la tabla de inodos del sistema de ficheros y finalmente volcaría los datos al disco. Si la escritura se interrumpe mientras se actualiza la tabla de inodos en el arranque se leerá el journal y se verá que debería de haber una entrada en la tabla que no existe, se generará y se escribirá un fichero de ese tamaño con basura para que el sistema de ficheros siga consistente. Por otro lado si se interrumpe la operación mientras se están volcando los datos al disco, tendremos en el journal que el fichero ocupa X (lo que ocuparía se se hubiese terminado de escribir) y en el sistema de ficheros tenemos un tamaño de Y (los datos a medio escribir en el fichero). En el reinicio se detectaría que X != Y por lo tanto se ha corrompido el fichero, se rellena con basura hasta ocupar X perdiendo así el fichero pero sin perder la integridad del sistema de ficheros ya que todos los ficheros empiezan y terminan donde indica la tabla de inodos. Es el recomendado en entornos donde hay problemas de rendimiento y los datos que se manejen puedan tener cierta tolerancia a fallos. **Ordered**: //data=ordered//: Solo se realiza journal de los metadatos pero se escribe a disco mediante transacciones, este sistema es un poco mas lento que writeback. Se relacionan los metadatos con los datos de tal modo que se forman transacciones atómicas, estas transacciones se escriben a disco y luego se escribe la metainformación en el journal, si ocurre algún problema mientras se vuelcan las transacciones al disco se pierden los datos del fichero, pero el sistema de ficheros siempre estará en un estado consistente ya que no pueden haber datos por un lado y metadatos por otro ya que los dos forman una unidad atómica e indivisible. **Journal**: //data=journal//: Se escribe tanto los datos como los metadatos en el journal y finalmente al disco. Esto supone una penalización considerable en el rendimiento del sistema de I/O pero obtenemos una mayor fiabilidad, el funcionamiento es idéntico al de un journal físico, solo se pierde la información del fichero en caso de no terminar la escritura en el journal. **Enlaces de interés**. * [[https://www.kernel.org/doc/Documentation/sysctl/vm.txt]] (sysctl VM) * [[http://wiki.centos.org/HowTos/Disk_Optimization]] (Optimización de HD) * [[http://www.alfaexploit.com/ficheros_web/leer.php?id=98]] (journaling). * [[http://gomix.fedora-ve.org/projects/fedobetatest/wiki/Kernel_io_elevator]] (elevadores). * [[http://planet.mysql.com/entry/?id=31505]] (MySQL + I/O elevator) ====== Herramientas para analizar el rendimiento de las tareas de entrada salida a disco (I/O Waits) ====== Como realizar un test de velocidad de escritura y lectura a disco sin usar la cache para que el resultado sea lo más real posible # Escritura dd bs=1M count=2048 if=/dev/zero of=test conv=fdatasync,notrunc # Lectura (test es el fichero de gran volumen a leer) flush echo 3 | sudo tee /proc/sys/vm/drop_caches time time dd if=test of=/dev/null bs=8k # Desactivar la cache del disco (Puede ser interesante en algunos momentos). hdparm -W0 /dev/sda Herramientas para obtener estadísticas de operaciones de entrada y salida sobre los discos. Combinando las unas con las otras se puede llegar a conocer en detalle qué proceso/s está/n haciendo uso del disco duro, de qué manera, cuando, en qué cantidad, etc. * top * vmstat * ps * sysstats (pidstat / nfsiostat / iostat) * iotop * hdparm * perf: http://www.brendangregg.com/perf.html * strace (Puede ayudar con las llamadas al sistema que realicen accesos a disco). **Comprobar rendimiento de los dispositivos de almacenamiento**. ([[https://wiki.archlinux.org/index.php/Benchmarking/Data_storage_devices|Leer]]) * gnome-disks (botón benchmark). * hdparm -Tt /dev/sdX * dd/dcfldd **Enlaces de interés**: [[http://www.linuxprogrammingblog.com/io-profiling]]