Rendimiento en Linux

Texto íntegro de Carlos Morales, 29 Enero del 2003
is06200@salleurl.edu
-

Dependiendo de la configuración que tenga el sistema Operativo se puede sacar más provecho al Hardware. El rendimiento (o performance en inglés) es el trabajo útil de los programas. Un programa con menos rendimiento puede hacer lo mismo pero ser más lento.
Para mejorar el rendimiento de la máquina es básico saber cuantificarlo. Estos son los comandos más importantes para verlo:
ps
Report Process Status.
top
Display top CPU processes.
vmstat
Report virtual memory statistics

Discos duros
Recomendaciones para los discos duros.
df
Report filesystem disk space usage
hdparm
get/set hard disk parameters
-

ps da una imagen de los procesos que están corriendo. Si quieres una vista que se vaya actualizando se debe usar top.
La orden básica de ps muestra solo los procesos que pertenecen al usuario que lo ejecuta.

$ps
  PID TTY          TIME CMD
20652 pts/0    00:00:00 bash
20859 pts/0    00:00:00 ps
	
Muestra dos procesos, bash y ps, sus números de procesos (20652 y 20859 respectivamente), el terminal y el tiempo de CPU.

$ps aux
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  1356  528 ?        S     2002   0:05 init [3]
root         2  0.0  0.0     0    0 ?        SW    2002   0:00 [keventd]
root         3 47.4  0.0     0    0 ?        SW    2002   0:56 [kapm-idled]
root         4  0.0  0.0     0    0 ?        SW    2002   0:05 [kswapd]
root         5  0.0  0.0     0    0 ?        SW    2002   0:00 [kreclaimd]
root         6  0.0  0.0     0    0 ?        SW    2002   0:04 [bdflush]
root         7  0.0  0.0     0    0 ?        SW    2002   0:06 [kupdated]
root         8  0.0  0.0     0    0 ?        SW<   2002   0:00 [mdrecoveryd]
root       497  0.0  0.3  1456  652 ?        S     2002   0:27 syslogd -m 0
root       506  0.0  0.5  1912 1088 ?        S     2002   0:00 klogd -2
root       520  0.0  0.6  2600 1236 ?        S     2002   3:32 sshd
[etc.]
	
Muestra mucha más información. Aquí mustra todos los procesos que se están ejecutando en el sistema.

$pstree
init-+-bdflush
     |-crond
     |-httpd---4*[httpd]
     |-kapm-idled
     |-keventd
     |-klogd
     |-kreclaimd
     |-kswapd
     |-kupdated
     |-master-+-pickup
     |        `-qmgr
     |-mdrecoveryd
     |-6*[mingetty]
     |-sshd---sshd---bash---pstree
     |      `-sshd---bash---pine    
     |-syslogd
     `-xfs	
El comando pstree muestra un árbol de dependencias. Como puede verse todos los procesos derivan del proceso init (con PID 1). En el ejemplo puede verse como hay dos sesiones en el servidor ssh, cada uno con su bash, uno usando la orden pstree y el otro con el comando pine.

-

El comando top muestra una imagen de todos los procesos del sistema, pero la diferncia con top la imgaen se va acutalizando, pueden mostrarse los procesos según el uso de memoria o cpu, matar un proceso y otras muchas más funciones.

$top
1:48pm  up 336 days, 22:18,  2 users,  load average: 0.00, 0.00, 0.00
47 processes: 45 sleeping, 2 running, 0 zombie, 0 stopped
CPU states:  0.1% user, 49.5% system,  0.0% nice, 50.2% idle
Mem:   191296K av,  188420K used,    2876K free,       0K shrd,   16296K buff
Swap:  522072K av,       0K used,  522072K free                   92544K cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
    3 root      18   0     0    0     0 SW   48.7  0.0  3840h kapm-idled
21085 carlosm   13   0  1068 1068   852 R     0.9  0.5   0:01 top
    1 root       8   0   528  528   460 S     0.0  0.2   0:05 init
    2 root       9   0     0    0     0 SW    0.0  0.0   0:00 keventd
    4 root       9   0     0    0     0 SW    0.0  0.0   0:05 kswapd
    5 root       9   0     0    0     0 SW    0.0  0.0   0:00 kreclaimd
    6 root       9   0     0    0     0 SW    0.0  0.0   0:04 bdflush
    7 root       9   0     0    0     0 SW    0.0  0.0   0:06 kupdated
    8 root      -1 -20     0    0     0 SW<   0.0  0.0   0:00 mdrecoveryd
  497 root       9   0   652  652   536 S     0.0  0.3   0:27 syslogd
  506 root       9   0  1088 1088   452 S     0.0  0.5   0:00 klogd
  520 root       9   0  1236 1236  1100 S     0.0  0.6   3:32 sshd
[etc.]
	
-

Con esta utilidad se averigua información sobre procesos, memoria, I/O (entrada/salida), interrupciones y CPU.
VMSTAT 1 (Red Hat)
$vmstat
procs                      memory    swap          io     system         cpu
 r  b  w   swpd   free   buff  cache  si  so    bi    bo   in    cs  us  sy  id
 0  0  0      0   4012  15652  93272   0   0     1     0    1     0   0   0   1
	
Estas estadísticas son de una máquina (Red Hat) con poco trabajo. Mirar abajo para saber qué indica cada cosa.
VMSTAT 2 (Debian)
$vmstat
procs     memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr f0 s0 s1 --   in   sy   cs us sy id
 0 0 0 2176976 245456 20 38 26  0  0  0  0  0  0  2  0  151 3799  265  7 14 79
	
Estas estadísticas son de una máquina Debian con mucho trabajo. A parte del la cantidad de trabajo, el tipo de estadísticas no son exactamente iguales, para saber que es cada cosa hacer un man vmstat en una máquina Debian.
Procs - Procesos. Lo mejor es que todos estuviesen a cero.
r: número de procesos esperando para ser ejecutados.
b: número de procesos en modo uninterruptable sleep.
w: número de procesos en swapped pero en modo ejecutable.
Memory
swpd: cantidad de memoria virtual(kB).
free: cantidad de memoria libre (kB).
buff: cantidad de memoria usada como buffers (kB).
Swap
si: cantidad de memoria intercambiada (swapped) de disco(kB/s).
so: cantidad de memoria intercambiada (swapped) a disco (kB/s).
IO
bi: Bloques enviados al block device (blocks/s).
bo: Bloques recividos del block device (blocks/s).
System - Nos da una idea de la cantidad de procesos (jobs) que se están ejecutando. Cuanto menos mejor.
in: El número de interrupciones por segundo, incluida la del clock.
cs: El número de cambios de contexto por segundo.
CPU - Son tantos por ciento de tiempo de la CPU asignados a:
us: Tiempo Usuario
sy: Tiempo Sistema
id: Tiempo inactivo (idle time)
-

A partir de aquí se comenta como mejorar el rendimiento del disco duro. Todas las aplicaciones que usen el disco duro son por ello inherentemente lentas. La mayoría de veces, el disco es el cuello de botella de un sistema.
Recomendaciones:
Mejor SCSI que IDE. Mejor SAN que SCSI.
Los discos duros más baratos son los IDE o los EIDE (Enhanced IDE), y lo son porque están controlados por la CPU misma y no necesitan de controladores adicionales. Pero esta misma ventaja hace que a la hora de transferir datos a disco la CPU no puede hacer otras operaciones, bajando el rendimiento general del sistema. Por lo tanto primera mejora, el sistema SCSI no sobrecarga tanto el sistema. La segunda mejora es que SCSI tiene mejores capacidades de transferencia que IDE.
De la misma manera la solución SAN (Storage-Area Network), es mejor que SCSI. Esta solución es mucho más cara, pero necesaria para sistemas que requieran mucha demanda de almacenamiento de datos. Se trata de equipos Hardware que se conectan a canales de fibra óptica y sólo disponibles para grandes empresas.
Multiples discos.
Ya sea SCSI o IDE la solución, está casi oblidado a usar varios discos si se toma en serio el rendimiento. De esta manera se disemina las entradas y salidas a disco entre varios equipos, minimizando el tiempo de espera.
Se usa un disco duro para el Sistema Operativo y software, y otro disco duro para los datos. Para los servidores web es recomendable usar un tercer disco para los logs generados.
RAID
RAID o Reduntant Array of Indpendent Disks son sistemas que ofrecen redundancia entre varios discos duros, de esta manera si un disco duro falla o se estropea, existe redundancia para no perder los datos almacenados. Dependiendo del tipo de RAID (0,1,3,5) el tiempo a escritura cambia, para RAID 5 al copiar la misma información en varios discos duros el tiempo es menor que si se escribiese la misma información a un disco duro.
-

Con esta orden se puede observar el estado de todas las particiones. No ayuda a saber el rendimento, pero si es muy importante para conocer el estado de los discos y si debe redimensionar su tamaño.

$df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/hda10            6.7G  439M  6.0G   7% /
/dev/hda7             7.7G  2.0G  5.3G  28% /apache
/dev/hda5              23M  1.5M   20M   7% /boot
/dev/hda11            3.5G  3.2G   99M  97% /home
/dev/hda6             2.9G   42M  2.7G   2% /root
/dev/hda13            2.9G   16k  2.7G   0% /tmp
/dev/hda12            2.9G  2.5G  221M  92% /var
/dev/hda9             996M   12k  945M   0% /var/ftp

Muy importante darse cuenta que la partición de /var esta llenandose, aquí se almacenan los logs del sistema, y puede hacer que fallen devido a que no tiene más espacio. Puede observarse también como la partición /dev/hda11, que pertenece al home está repleto y puede ser peligroso para los usuarios, ya que pueden quedarse sin espacio.

-

Se puede conseguir un mejor rendimiento de los discos IDE. Pero antes de empezar a afinar el disco duro necesitamos determinar lo bien que funciona. hdparm es una herramienta para medir el rendimiento del sistema de discos.
Antes de hacer cualquier cambio al sistema es muy importante hacer copia de seguridad de los documentos, como dice Murphy "cuando se espera que algo no falle, seguro fallará".
Suponiendo que el disco duro está en /dev/hda:

$hdparm /dev/hda
 /dev/hda:
 multcount    =  0 (off)
 IO_support   =  1 (32-bit)
 unmaskirq    =  1 (on)
 using_dma    =  1 (on)
 keepsettings =  0 (off)
 readonly     =  0 (off)
 readahead    =  8 (on)
 geometry     = 3720/255/63, sectors = 59777640, start = 0
	

Aquí puede verse como la mitad de operaciones estan usándose. Aunque para sacar más información debemos usar el siguiente comando:

$hdparm -i /dev/hda
/dev/hda:

 Model=ST330630A, FwRev=3.21, SerialNo=3CK0B6ZX
 Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs RotSpdTol>.5% }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=0
 BuffType=unknown, BuffSize=2048kB, MaxMultSect=16, MultSect=off
 CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=59777640
 IORDY=on/off, tPIO={min:240,w/IORDY:120}, tDMA={min:120,rec:120}
 PIO modes:  pio0 pio1 pio2 pio3 pio4
 DMA modes:  mdma0 mdma1 mdma2
 UDMA modes: udma0 udma1 *udma2 udma3 udma4
 AdvancedPM=no WriteCache=enabled
 Drive conforms to: device does not report version:  1 2 3 4

Muestra la información del disco duro cuando se arrancó el sistema: el modelo, configuración, geometría del disco (RawCHS-> Cylinders, heads y sectors), tamaño de track, tamaño del sector, tamaño del buffer, si soporta DMA, etc. mucha de esta información es necesaria para mejorar el rendimiento.
La siguiente orden prueba el disco.

$hdparm -Tt /dev/hda
/dev/hda:
 Timing buffer-cache reads:   128 MB in  0.79 seconds =162.03 MB/sec
 Timing buffered disk reads:  64 MB in  4.09 seconds = 15.65 MB/sec

Estos datos son antes de afinar el sistema. La opción -T testea la cache del sistema (memoria, CPU y buffer cache). El -t muestra estadísticas del disco leyendo datos que no están en la cache.
Para mejorar el rendimiento del disco empecemos cambiando la cantidad de sectores que puede transferir el sistema por interrupción, es el MaxMultSect. En la orden hdparm /dev/hda la variable multcount en modo off indica que está apagada esta opción, y en cambio en la orden hdparm -i /dev/hda nos indica que el disco duro puede transmitir hasta 16 sectores a la vez, indicado en la variable MaxMultSect. Cambiemos entonces el número de sectores al máximo disponible.

$hdparm -m16 /dev/hda
/dev/hda:
 setting multcount to 16
 multcount    = 16 (on)
 	
Para ver si de verdad se ha mejorado el rendimiento probar el ratio de transferencia otra vez.

$hdparm -Tt /dev/hda
/dev/hda:
 Timing buffer-cache reads:   128 MB in  0.79 seconds =162.03 MB/sec
 Timing buffered disk reads:  64 MB in  3.89 seconds = 16.45 MB/sec
 	
Se ve una mejora de 15.65 a 16.45 MB/sec, una mejora de 0,8 MB/sec. No es mucho pero es una mejora.

En mi caso las transferencias se hacen a 32-bits, pero en caso de estar a 16 bits se puede cambiar a 32 bits.

$hdparm -c3 /dev/hda
/dev/hda:
 setting 32-bit IO_support flag to 3
 IO_support   =  3 (32-bit w/sync)
 	
La mayoría, por no decir todos los discos duros nuevos aceptan esa transferencia. Con la opción -c se puede seleccionar: 0 activa el soporte por defecto de 16-bit I/O
1 activa el soporte 32-bit I/O
3 activa el soporte 32-bit I/O con una sincronización requerida para muchos procesadores IDE/EIDE (este es el valor que aceptan la mayoría de sistemas)
En el caso de que el disco duro soporte la DMA (direct memory access), se puede activar su soporte mediante la orden -d en conjuto con -X. Mirar en la orden hdparm -i /dev/hda si se puede usar el dma. En mi caso indica que el disco duro trabaja a udma2.

$hdparm -d1 -X66 /dev/hda
/dev/hda:
 setting using_dma to 1 (on)
 setting xfermode to 66 (UltraDMA mode2)
 using_dma    =  1 (on)
 	
También se puede mejorar el rendimiento diciendo al driver del disco que puede permitir otras interrupciones mientras se procesa una interrupción a disco. Esto significa que el sistema operativo puede aceptar otras interrupciones mientras espera que se termine la transferencia de datos con en disco duro.

$hdparm -u1 /dev/hda
/dev/hda:
 setting unmaskirq to 1 (on)
 unmaskirq    =  1 (on)
	

Comentarios: