Análisis de dispositivos de almacenamiento con Fio

Como ingenieros, tenemos que diseñar sistemas informáticos y realizar pruebas en hardware para garantizar que tareas específicas funcionen correctamente. Una de las pruebas más comunes es verificar el sistema de almacenamiento, mediante el uso de software de terceros o escribiendo códigos para evaluar su desempeño y obtener una información específica.

Al usar nuestros códigos, tenemos la libertad de crear conjuntos de pruebas especializados y diversificados. Pero desafortunadamente, estos códigos no nos permiten realizar una adecuada interpretación y comparación de los resultados con respecto a una referencia bien establecida y ampliamente aceptada por la comunidad de investigadores e ingenieros. De esta forma, tenemos que buscar herramientas que nos ayuden a realizar una evaluación comparativa de almacenamiento (storage benchmarking).

Debido a esta necesidad, Jens Boe creó Fio (Flexible I/O Tester, probador de E/S flexible), una herramienta open source de evaluación comparativa (benchmark) que permite probar dispositivos de almacenamiento a través de la simulación de cargas de trabajo. Actualmente, Fio posee soporte para múltiples plataformas como, Debian, Ubuntu, Windows, Berkeley Software y Distributions (BSDs).

A continuación te mostraremos algunas definiciones relacionadas al sistema de almacenamiento que debes conocer antes de ejecutar Fio. Pero si ya estás al tanto de ellas, solo ve a la sección de Primeros pasos con Fio.

Principales métricas en dispositivos de almacenamiento

Memoria caché y búfer

El buffer es una región de la memoria física que almacena información de forma temporal durante una transferencia de datos entre dispositivos de entrada y salida. El buffer también ayuda a compensar la diferencia de velocidad entre dos procesos con diferentes tiempos de ejecución (por ejemplo, enviar un documento a imprimir).

Por otro lado, la memoria caché es una área de almacenamiento temporal que almacena archivos para su posterior lectura. El objetivo principal de la memoria caché es aumentar el desempeño de la transferencia de información, almacenando una copia de un archivo para evitar la lectura de datos desde una capa subyacente del sistema de almacenamiento, lo que reduce el tiempo de lectura.

Si deseas conocer el uso de las memorias buffer y caché de tu sistema, solo debes escribir en el terminal de tu pc el comando free -h (utiliza la opción -h para elegir el formato “legible para humanos”). 

luis@Desktop:~$ free -h

Enseguida verás un reporte general del estado de uso de las memorias y mostradas de la siguiente forma:

               total     used     free    shared   buff/cache   available
Mem:            15Gi     6.4Gi   9.3Gi       17Mi       223Mi       9.4Gi
Swap:           27Gi     17 Mi   27Gi

donde buff/cache es la suma de la memoria búfer y caché. Puedes usar free –help para obtener más información.

IOPS

El valor de IOPS (Input/Output Operations Per Second, operaciones de entrada y salida por segundo) es una métrica para estimar la cantidad máxima de operaciones que el disco puede manejar en un intervalo de un segundo. Las IOPS se miden comúnmente en KiB (kibibyte) o MiB (mebibyte) y sus valores responden al tipo de unidad de almacenamiento, el número de operaciones de lectura y escritura, al uso de patrones de acceso secuencial o aleatorio, tamaños de bloques de datos (por ejemplo, 256 bloques de 4 KiB) y otras precondiciones.

Con respecto a sus elementos de construcción, el número de operaciones que puede realizar un HDD (Hard-Disk Drive, unidad de disco duro) depende de la latencia de rotación que describe el tiempo requerido por rotar el disco hacia un sector específico y del tiempo de búsqueda que describe el tiempo de desplazamiento del brazo de lectura, lo que resulta en una velocidad en la escala de 102 IOPS. Por otro lado, un SSD (Solid-State Drive, unidad de estado sólido) no cuenta con elementos mecánicos, por lo que alcanza mayores velocidades que un HDD tradicional. Las velocidades típicas están en la escala de 103 IOPS.

Un SSD será útil en situaciones en las que se desee acceder a una base de datos, mover archivos grandes o ejecutar un programa de forma frecuente, ya que te brindará un número más alto de IOPS, por otro lado, un HDD es menos costoso y responde mejor a procesos de múltiples tareas como ejecutar un análisis de virus, usar un programa y abrir tu navegador web al mismo tiempo.

Rendimiento (throughput)

El rendimiento del disco (disk throughput) representa la velocidad (en MiB/s) con la que el disco puede escribir o leer de forma continua. Ya sea que tu aplicación se ejecute en un sitio web, una base de datos, un servidor u otro dispositivo, esta es una de las métricas más observadas ya que brinda una visión general de la capacidad de la tasa de transferencia de datos.

Latencia

Como consecuencia de la velocidad máxima de procesamiento de tareas y de parámetros constructivos, el tiempo necesario para realizar una transferencia de datos, o latencia, varía de acuerdo al tipo de disco. De esta forma, una unidad magnética será mucho más lenta que una de estado sólido, lo que implica en una transferencia de datos más lenta y un menor desempeño de todo el sistema.

Ancho de banda

El ancho de banda determina la cantidad de información que una unidad de almacenamiento puede enviar durante una transferencia de datos. Su capacidad depende de las conexiones físicas y lógicas, así como de otras limitaciones tecnológicas.

Primeros pasos con Fio

Descripción

Fio es una herramienta de evaluación comparativa de código abierto que permite estandarizar las pruebas del sistema de almacenamiento. Fio es un generador de carga de trabajo de entrada y salida (E/S), y lo suficientemente versátil y flexible para admitir configuraciones detalladas.

Instalación de Fio

Para arquitecturas basadas en Linux, las instrucciones de instalación son similares. Solo debes usar el comando:

luis@Desktop:~$ sudo apt-get install fio

Ve a documentación de Fio para conocer más acerca del proceso de instalación en otras plataformas y para obtener información.

Argumentos de entrada de Fio

-- name=strFio creará un archivo de acuerdo con el nombre especificado para ejecutar las pruebas.
--rw=strEspecifica el tipo de patrón de las operaciones de E/S. Puedes elegir entre las siguientes opciones: read, write, randread, randwrite, trim, randtrim, rw,readwrite, randrw, trimwrite y randtrimwrite.
--bs=intEspecifica el tamaño de bloque que utilizará la prueba para generar las operaciones de E/S. Si no se especifica, el valor predeterminado será 4k.
--ioengine=strEspecifica cómo el trabajo emitirá E/S para el archivo de prueba. Ve a la documentación de Fio para ver otros motores de E/S disponibles (por ejemplo, libaio es el motor de E/S estándar en Linux).
--size=intEspecifica el tamaño del archivo con el que Fio ejecutará la prueba. Si no se especifica, las unidades será en MiB.
--numjobs=intEspecifica el número de subprocesos o procesos independientes. Al definir un número más alto que 1, Fio realizará varios procesos haciendo lo mismo. (por ejemplo, al definir –numjobs=5, tendremos 5 archivos de prueba separados con un tamaño definido en –size=int.)
--runtime=intEspecifica el tiempo total establecido para finalizar la prueba. Si el proceso finaliza antes del tiempo determinado, Fio comenzará una nueva prueba hasta que se complete la simulación. Las unidades están en segundos, y comúnmente su valor es 60.
--time_basedSi este es incluido, se especifica que la prueba se ejecutará repetidamente tantas veces como lo permita el tiempo de ejecución.
--group_reportingSi este es incluido, Fio genera un reporte sobre todos los trabajos ejecutados en vez de mostrar de forma individual.
--iodepth=intDefine el número de comandos que estarán en espera para ser ejecutados por la unidad de almacenamiento.

Ejecutando Fio

Antes de ejecutar Fio desde el terminal (o desde un archivo de trabajo), deberás navegar a través del directório para seleccionar el disco o indicarlo junto a los argumentos de Fio. Para reconocer fácilmente el nombre de tu disco, debes usar el siguiente comando:

luis@Desktop:~$ lsblk

Esta herramienta te permite ver detalles de los dispositivos de bloque, que representan los dispositivos conectados a la PC.

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0    7:0    0     4K  1 loop /snap/bare/5
loop1    7:1    0 400.8M  1 loop /snap/gnome-3-38-2004/112
loop2    7:2    0    62M  1 loop /snap/core20/1587
loop3    7:3    0 163.3M  1 loop /snap/firefox/1635
loop4    7:4    0  91.7M  1 loop /snap/gtk-common-themes/1535
loop5    7:5    0  45.9M  1 loop /snap/snap-store/582
loop6    7:6    0    47M  1 loop /snap/snapd/16292
loop7    7:7    0   284K  1 loop /snap/snapd-desktop-integration/14
sda      8:0    0 931.5G  0 disk
├─sda1   8:1    0   512M  0 part /boot/efi
└─sda2   8:2    0   931G  0 part /
sdb      8:16   1  14.4G  0 disk
└─sdb1   8:17   1  14.4G  0 part /media/luis/LUCHO
sr0     11:0    1  1024M  0 rom

En mi caso, tengo un HDD y un disco externo de 931,5 GiB (sda) y 14,1 GiB (sdb), respectivamente. Una vez que hayas identificado el disco a analizar, la dirección debe definirse como –filename=/dev/sdb.

Nota: verifica que la dirección esté correcta, ya que especificar un disco incorrecto puede causar problemas graves.

Puedes ejecutar Fio y simular pruebas al escribir los argumentos en una única línea.

luis@Desktop:~$ sudo fio --filename=/dev/sdb --rw=read --direct=1 --bs=4k --ioengine=libaio --runtime=60 --numjobs=1 --time_based --group_reporting --name=seq_read --iodepth=16

Fio comenzará la prueba de forma inmediata y, una vez completada, mostrará el siguiente reporte.

Seq_read: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
fio-3.28
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=28.8MiB/s][r=7371 IOPS][eta 00m:00s]
seq_read: (groupid=0, jobs=1): err= 0: pid=5028: Fri Oct 21 13:20:15 2022
  read: IOPS=7329, BW=28.6MiB/s (30.0MB/s)(1718MiB/60002msec)
    slat (nsec): min=1550, max=1752.6k, avg=4170.66, stdev=9485.59
    clat (usec): min=307, max=15484, avg=2177.77, stdev=222.49
     lat (usec): min=329, max=15486, avg=2182.10, stdev=222.55
    clat percentiles (usec):
     |  1.00th=[ 1926],  5.00th=[ 2024], 10.00th=[ 2089], 20.00th=[ 2114],
     | 30.00th=[ 2114], 40.00th=[ 2114], 50.00th=[ 2147], 60.00th=[ 2147],
     | 70.00th=[ 2212], 80.00th=[ 2245], 90.00th=[ 2311], 95.00th=[ 2442],
     | 99.00th=[ 2704], 99.50th=[ 2868], 99.90th=[ 4359], 99.95th=[ 4948],
     | 99.99th=[ 7242]
   bw (  KiB/s): min=27920, max=30928, per=100.00%, avg=29333.65, stdev=656.56, samples=119
   iops        : min= 6980, max= 7732, avg=7333.39, stdev=164.13, samples=119
  lat (usec)   : 500=0.04%, 750=0.04%, 1000=0.11%
  lat (msec)   : 2=4.13%, 4=95.53%, 10=0.14%, 20=0.01%
  cpu          : usr=2.39%, sys=4.00%, ctx=54843, majf=0, minf=26
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=439765,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=16
Run status group 0 (all jobs):
   READ: bw=28.6MiB/s (30.0MB/s), 28.6MiB/s-28.6MiB/s (30.0MB/s-30.0MB/s), io=1718MiB (1801MB), run=60002-60002msec
Disk stats (read/write):
  sdb: ios=54619/0, merge=384382/0, ticks=118257/0, in_queue=118258, util=99.90%

Descripción del reporte de Fio

Para comprender mejor los resultados, estos serán descritos individualmente.

slat (nsec): min=1550, max=1752.6k, avg=4170.66, stdev=9485.59

slat es la latencia de envío y está descrita por sus valores mínimo (min), máximo (max), promedio (avg) y desviación estándar (stdev),

clat (usec): min=307, max=15484, avg=2177.77, stdev=222.49

clat denota la latencia de finalización,

lat (usec): min=329, max=15486, avg=2182.10, stdev=222.55

lat es la latencia total (es la suma de clat y slat),

clat percentiles (usec):     
|  1.00th=[ 1926],  5.00th=[ 2024], 10.00th=[ 2089], 20.00th=[ 2114],     
| 30.00th=[ 2114], 40.00th=[ 2114], 50.00th=[ 2147], 60.00th=[ 2147],     
| 70.00th=[ 2212], 80.00th=[ 2245], 90.00th=[ 2311], 95.00th=[ 2442],     
| 99.00th=[ 2704], 99.50th=[ 2868], 99.90th=[ 4359], 99.95th=[ 4948],     
| 99.99th=[ 7242]

clat percentiles describen los percentiles de latencia de finalización (probablemente la información más útil),

bw (  KiB/s): min=27920, max=30928, per=100.00%, avg=29333.65, stdev=656.56, samples=119

bw denota el ancho de banda,

iops        : min= 6980, max= 7732, avg=7333.39, stdev=164.13, 

iops son las estadísticas de IOPS basadas en muestras, 

samples=119lat (usec)   : 500=0.04%, 750=0.04%, 1000=0.11%lat (msec)   : 2=4.13%, 4=95.53%, 10=0.14%, 20=0.01%

lat es la distribución de latencia indicada tanto en microsegundos (usec) como en milisegundos (msec),

cpu          : usr=2.39%, sys=4.00%, ctx=54843, majf=0, minf=26

cpu describe el uso del CPU, 

IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%   
submit       : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%   
complete     : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%  
issued rwts  : total=439765,0,0,0 short=0,0,0,0 dropped=0,0,0,0   
latency      : target=0, window=0, percentile=100.00%, depth=16

IO depths representa el número de E/S emitidas al sistema operativo en un dado período de tiempo, IO submit, y IO complete representan las E/S enviadas y completadas por Fio en un dado período de tiempo, IO issued rwts y IO latency describen la profundidad de E/S requerida para cumplir con el objetivo de latencia especificado (estos valores se usan en simulaciones que emplean latency_target y otras opciones relacionadas).

Run status group 0 (all jobs):READ: bw=28.6MiB/s (30.0MB/s), 28.6MiB/s-28.6MiB/s (30.0MB/s-30.0MB/s), io=1718MiB (1801MB), run=60002-60002msec

Posteriormente, las estadísticas del grupo se imprimen una vez finalizadas las pruebas. Recuerda que en mi caso realicé una única prueba de lectura (READ). Aquí, bw=28,6MiB/s corresponde al ancho de banda agregado de los subprocesos, seguido de sus valores máximo y mínimo (28,6MiB/s-28,6MiB/s), io es la E/S agregada realizada de todos los subprocesos de este grupo, run indica los tiempos de ejecución más pequeños y más largos de los subprocesos.

 Nota: Los valores se imprimen tanto en base 2 (MiB/s) como en base 10 (MB/s).

Disk stats (read/write):  sdb: ios=54619/0, merge=384382/0, ticks=118257/0, in_queue=118258, util=99.90%

Finalmente, se muestran algunas estadísticas del disco, donde el formato read/write señala valores de lectura y escritura. Para esta simulación, Fio mostró estadísticas para el disco sdb, donde ios es el número de E/S, merge es el número de fusiones, ticks es el número de tics (cantidad de tiempo medido en ticks) que mantuvo ocupado el disco, in_queue es el tiempo total gastado en la cola del disco y util es el porcentaje de la utilización del disco.

Resumen

Fio es una herramienta ampliamente aceptada por ingenieros y usada en infraestructuras como Red Hat, Oracle Cloud, Amazon y Azure. Fio tiene soporte para múltiples plataformas y puede ser usada para verificar el desempeño y encontrar errores.

Para obtener más información sobre Fio, ingresa a la documentación de Fio.

Scroll to Top