En Mi Local Funciona

Technical thoughts, stories and ideas

Linux. Pruebas de rendimiento I/O a disco

Publicado por Víctor del Barco el

Cloudlinuxrendimiento

Uno de los mayores desafíos que nos encontramos ante un problema de rendimiento en nuestras aplicaciones o sistemas, se produce cuando dicho problema está en una capa que de forma habitual tiene un comportamiento adecuado y necesitamos trabajar con herramientas cuyo uso no es tan habitual.

En este post, vamos a ahondar en alguna de estas herramientas y métodos cuando nos enfrentamos ante un problema de rendimiento de discos en sistemas Linux.

¿Cómo identificar problemas de I/O en Linux?

Para hacer una detección básica del rendimiento de un disco en un sistema Linux/Unix e identificar problemas de escritura, podemos seguir estos sencillos pasos para hacer un primer diagnóstico a nivel básico.

Identificación de volúmenes

Lo primero es identificar los volúmenes que tenemos disponibles y sobre los que queremos operar:

[root@xxxxxxxxxx]/root# df -k
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda3             11025272   8604420   1851752  83% /
/dev/sda7             10153988   1599432   8030440  17% /usr
/dev/sda6             10153988    951912   8677960  10% /var
/dev/sda5             20315812  16919124   2348048  88% /u01
/dev/sda1               194442     11887    172516   7% /boot
tmpfs                 10245144         0  10245144   0% /dev/shm
/dev/appjava1         51606124  33864592  15120096  70% /oracle/oas10gR3
/dev/appforms1        51606124  13161444  35823244  27% /oracle/appserver
Test de rendimiento

Una vez tenemos los discos (/dev) y los puntos de montaje, comenzamos a probar el rendimiento de cada uno de ellos realizando una escritura intensiva sobre los mismos:

for i in 1 2 3 4 5 6 7 8 9 10; do
  dd if=/dev/zero of=/write.img bs=8k count=256k conv=fdatasync
done

En ese script sustituimos "/write.img" por el filesystem donde queremos escribir que se corresponderá con el que estamos analizando. Este comando realizará 10 iteraciones escribiendo un fichero de pruebas de 2gb de forma sostenida y nos dará un resultado como este:

262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 20.451 s, 98 MB/s
262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 20.4202 s, 101 MB/s
.....

El comando hará 10 iteraciones ya que, si bien las primeras puede dar unos buenos resultados, a medida que el buffer de escritura del disco se va llenando, y no ser capaz de escribir a una velocidad suficiente, dicha tasa de escritura desciende, y arrojará un resultado como éste:

262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GG) copied, 81.5432 s, 24.2 MB/s
262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 108.41 s, 19.8 MB/s
Análisis del test

Revisando en detalle las tasas de velocidad, se ve claramente la drástica reducción de rendimiento, motivado porque estamos saturando el I/O del disco.

Los valores de rendimiento en Mb/s dependerán mucho del disco en si y de su arquitectura (nas, san, scsci, ...) y los valores pueden variar enormemente, es decir, una tasa de escritura lenta, no tiene que significar siempre un problema si ésta se mantiene estable durante la prueba.

De cualquier forma, durante la misma, podemos ejecutar el siguiente comando desde otro terminal y poder ver en tiempo real el rendimiento de los dispositivos en análisis:

iostat -d -m -x 2
Device:         rrqm/s   wrqm/s   r/s   w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     6.50  0.00  5.00     0.00     0.04    18.40     0.03    5.60   5.00   2.50
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda3              0.00     5.50  0.00  2.00     0.00     0.03    30.00     0.01    6.50   5.00   1.00
sda4              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00     1.00  0.00  3.00     0.00     0.02    10.67     0.01    5.00   5.00   1.50

En ella podemos ver el comportamiento del disco para que en caso de que tengamos una tasa de escritura lenta, obtengamos detalle de las distintas operaciones y así, ayudar a determinar el origen del problema de rendimiento.

Ejemplo práctico

Si estamos identificando una tasa de escritura lenta, nos debemos fijar en los datos que nos arroja el comando descrito en el punto anterior.

Por ejemplo, ejecutamos la secuencia completa en un entorno:

[root@xxxxxxxx]/root# for i in 1 2 3; do
> dd if=/dev/zero of=/write.img bs=8k count=256k conv=fdatasync
> done
262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 22.2793 seconds, 96.4 MB/s
262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 22.2579 seconds, 96.5 MB/s
262144+0 records in
262144+0 records out
2147483648 bytes (2.1 GB) copied, 22.8519 seconds, 94.0 MB/s

Vemos que se mantiene en una tasa sostenida (solo hemos hecho 3 iteraciones con una tasa de alrededor de 95 MB/s), mientas que el iostat, nos arroja los siguientes resultados:

Device:         rrqm/s   wrqm/s   r/s   w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00 25837.50  0.00 689.00     0.00   102.58   304.91   143.01  207.15   1.45 100.05

Como vemos, en dicho disco, tenemos las tasas de escritura como en el comando anterior, pero los valores que nos interesan más por su significado, son el await y el %util:

  • await es el tiempo en milisegundos que el disco está tardando en procesar las peticiones de I/O.
  • %util el tiempo que el disco está en uso.

Normalmente, a medida que la cola se va llenando, el rendimiento del disco empeora, es decir, que no importa que el uso esté al 100% y haya cierto await, mientras los valores no crezcan demasiado y empiece a bajar la tasa de transferencia en Mb/s.

Un disco sin problemas, tendría este aspecto, si lanzamos un iostat con opciones 2 10:

[root@xxxxxxx]/root# iostat 2 10
Linux 2.6.18-194.el5 (xxxxxxxx)       05/23/2016

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.40    0.03    0.19    0.67    0.00   98.71

Mientras que un entono con problemas tendría este aspecto:

CPU     %user     %nice   %system   %iowait    %steal     %idle
all      1.25      0.00      2.50     70.00      0.00     26.25

Donde vemos que la máquina apenas tiene carga (CPU por debajo del 5%) y tiene un iowait del 70%.

Una vez identificado que el sistema tiene algún problema relacionado con las esperas de I/O, podemos ir al detalle de los distintos discos de dicho sistema:

Device:         rrqm/s   wrqm/s   r/s   w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.50  0.00  0.60     0.00     0.00    12.00     1.73 3664.67 1668.67 100.02
dm-2              0.00     0.00  0.00 673.13     0.00     2.63     8.00 11734.53 21798.66   1.49 100.02

Y ahí es donde podemos identificar que tenemos un problema de escritura en disco.

Los siguientes pasos, en un caso como éste, continúan con la investigación del disco identificado con problemas de escritura que pueden ser de diferentes tipos y, por tanto, con diferentes tipos de soluciones:

  • El disco no está preparado para las labores que se necesitan realizar (escritura intensiva)
  • Configuración no adecuada del disco
  • Configuración del sistema operativo
  • Cabina de discos
  • Drivers
Conclusiones

Ante un problema de rendimiento de una aplicación, lo primero de todo, es identificar el origen del problema. En este caso, nos hemos centrado en un problema relacionado con los discos de un sistema montado con Linux.

Este sistema operativo nos proporciona unas herramientas bastante útiles para la realización de un test de rendimiento y detallar el comportamiento de los discos y así poder acotar el origen del problema de rendimiento de nuestra aplicación.