Cuellos de botella en Linux

Los cuellos de botella se pueden producir en múltiples lugares del sistema. Detectarlos es importante para saber como está rindiendo una máquina.

CPU
Detección de cuello de botella en la CPU debido a su carga

Usando top, uptime, o cualquier comando que devuelva al carga media:

load average: 1,23, 1,42, 1,54

Estos valores indican el número medio de procesos que hay en cola para entrar al procesador.
Si estos valores superan o se acercan el número de cores del procesador, es probable que los procesos estén esperando por acceder a la CPU mucho más que el tiempo que tardan en hacer el cambio de contexto.
En este ejemplo, es una máquina con 2 cores. La CPU aún no es cuello de botella para su rendimiento. Un 10% por debajo del número de cores es señal de alarma.

Nota: Existe un caso en el que los valores de 'load average' crecen muy por encima del número de cores y sin embargo no se percibe una pérdida de rendimiento en el sistema. Habitualmente estos valores altos son debidos a procesos que realizan operaciones de E/S que se quedan en espera o bloqueados. El consumo real de CPU es  mínimo pero se contabilizan como procesos en cola. En estos casos, el % de uso de la CPU está por debajo del 100%.

DISCO
Detección de cuellos de botella en el almacenamiento (disco)
Los cuellos de botella en el sistema de E/S están normalmente relacionados con la carga de CPU debida a las operaciones de E/S, la latencia del almacenamiento y sus IOPS máximas.

Idealmente es necesario saber de antemano cual es la latencia mínima e IOPS máximas que el almacenamiento puede ofrecer. Un disco SATA de 7200rpm suele dar en números redondos una latencia de 5 ms y unas 90 IOPS.
Cuando el almacenamiento está llegando a su límite de rendimiento (es decir, alcanzando su límite de IOPS), la latencia comienza a aumentar de forma considerable. Esta es la señal de alarma.

Si los procesos realizan muchas operaciones de Entrada/Salida, puede darse en caso de que saturen la CPU, el almacenamiento o ambos.

IOSTAT
Herramienta para saber en tiempo real el número de IOPS sobre un dispositivo de almacenamiento: iostat

iostat -d /dev/sda 1

'tps': Operaciones totales realizadas desde la última actualización (1 segundo). IOPS en 'tiempo real'
kB_read/s, kB_wrtn/s: KBs leidos/escritos por segundo.

Cuando el valor de 'tps' se acerca al límite del máximo que puede ofrecer el almacenamiento, este es un cuello de botella.

Se puede obtener más información interesante jugando con los parámetros de 'iostat':

 Las medidas *await hacen referencia a la 'latencia'. Son una medida de lo que tarda (ms) una operación de E/S al disco 'sda' contando (OJO!) tanto el tiempo de sistema para el procesado de la petición como el tiempo de espera para que el disco devuelva la respuesta.

svctm indica la espera (ms) debida específicamenteal dispositivo del almacenamiento. Según el tipo de sistema, un svctm por debajo de 10ms en entornos 'enterprise' ó de 50ms en entornos de 'escritorio' son aceptables. Por encima de eso la pérdida de rendimiento es evidente.
Estos valores se deben comparar con los valores teóricos que debe dar el dispositorio de almacenamiento recurriendo a las specs del fabricante.

El valor '%util' indica la carga del procesador que es debida a las operaciones de E/S. Si este valor es alto (especialmente si es del 100% o cercano), el sistema se está saturando en operaciones de E/S. Puede estar relacionado con la saturación del propio disco o sistema de almacenamiento, pero no en todos los casos.
iostat 

RAM
MEMORIA RAM
El tiempo de acceso a la memoria principal del sistema es constante en todos los casos salvo averías o algunos sistemas NUMA.
Por lo tanto, detectar fallas de rendimiento debido a la memoria RAM se centra en:
  1. Descubrir si el sistema está haciendo swapping y en que medida.
  2. Descubrir el tiempo de espera para acceder a la memora
free

El sistema tieme partición de swap activa y se está utilizando (~11MB) .
vmstat

La cantidad de swap utilizada es de 11812KB y en ratios de 1 segundo se aprecia que las operaciones de lectura/escritura (si/so) sobre ella son nulas.
Si la swap tiene un uso intensivo (si/so >>0) el rendimiento del sistema disminuye.

La cantidad de espacio libre en la memoria principal (free) "no es reprententativo" ya que la memoria RAM se utiliza como caché del almacenamiento para agilizarlo.
Si la memoria se llena totalmente nuevos procesos no podrán ejecutarse, pero el rendimiento dependiente de su uso no se ve afectado (con excepciones). El cuello de botella a tener en cuenta en lo que a la memoria respecta es el swapping.


MISCELANEA

Ordenar procesos por:

Uso de CPU:
ps aux --sort=-pcpu

Acceso a disco:
iotop
Tamaño en memoria por KBs y %:
ps aux --sort -rss
Columna RSS: KBs
Columna %CPU: %CPU

Uso de swap:
http://yoseman.blogspot.com.es/2014/06/quien-esta-consumiendo-swap.html

Acceso a swap
iotop (columna SWAPIN)
Uso de red
Usando el programa "nethogs"

Procesos con uso de CPU <> 0
ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm \ 
--sort=+pcpu | awk '$8!=0.0 {print}' | awk 'NR>1'
Prioridad de procesos
ps -lax  (Columna NI)

Mapas de memoria (off-topic)
Herramienta:
pmap

Demonio bash linux

Esquema de script muy sencillo para hacer un demonio en bash corriendo en background:

#!/bin/bash

# At first you have to redirect stdout and stderr to /dev/null
exec >/dev/null
exec 2>/dev/null

# Fork and go to background
(
while true; do
    echo 'hi' >> ~/hihihi
    sleep 10
done
)&
# Parent process finished but child still working


Visto en: http://stackoverflow.com/questions/41258219/how-to-daemonize-a-script

Resumen SYSTEMD

Conceptos fundamentales:

unit Definición de un proceso (unidad mínima)
target Agrupación de 'units' para manejar un servicio o varios
journal Sistema de logs de todas las operaciones y salidad de SYSTEMD

Comandos para gestión de servicios

systemctl status SERVICIO service SERVICIO status
systemctl start SERVICIO service SERVICIO start
systemctl stop SERVICIO service SERVICIO stop
systemctl reload SERVICIO service SERVICIO reload
systemctl restart SERVICIO service SERVICIO restart
systemctl enable SERVICIO chkconfig SERVICIO on
systemctl disable SERVICIO chkconfig SERVICIO off
systemctl is-active SERVICIO chkconfig SERVICIO
systemctl is-enabled SERVICIO chkconfig --list | grep SERVICIO
systemctl is-failed SERVICIO
systemctl list-units
systemctl list-units -all
systemctl list-units --all --state=inactive
systemctl linst-units --type=service
systemctl list-unit-files --type=service chkconfig --list
systemctl list-dependencies SERVICIO --after
systemctl list-dependencies SERVICIO --before

UNIT: Concepto de mínimo recurso que maneja "systemd".
Las UNIT se definen en archivos.

Tipo de UNITExtensión del ficheroDescription
Service unit .service Un servicio clásico
Target unit .target Grupo de units
Automount unit .automount Filesystem
Device unit .device Dispositivo (reconocido por el kernel)
Mount unit .mount Punto de montaje
Path unit .path Ruta
Scope unit .scope Proceso creado externamente a systemd
Slice unit .slice Conjunto jerárquico de units organizadas para manejar un grupo de procesos del sistema.
Snapshot unit .snapshot Un estado salvado de la configuración de systemd
Socket unit .socket Socket
Swap unit .swap Dispositivo o archivo swap
Timer unit .timer Cronómetro


Rutas
Path Descripción Prioridad
/run/systemd/system/ Creadas en tiempo de ejecución 1
/etc/systemd/system/ Enlazadas a /usr/lib/systemd/system al habilitar un servicio 2
/usr/lib/systemd/system/ Definiciones de Units con las que se instalan los paquetes (rpm) 3

Archivo Unit
Aspecto de un archivo de definición de 'Unit' (sshd.service):
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service    #Orden específico de arranque
Wants=sshd-keygen.service                            #Otra unit necesaria para este 

[Service]
Type=forking
PIDFile=/var/run/sshd.pid
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd $OPTIONS      #Comando de start
ExecReload=/bin/kill -HUP $MAINPID    #Comando de reload
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target      
             #Otra unit de la cual forma parte

Runlevels
Desaparece el concepto clásico. Se sustituyen por 'targets'.
Varios targets pueden estar activos a la vez si las dependencias lo permiten.

systemctl get-default Target por defecto
systemctl set-default graphical.target
Establecer target por defecto
systemctl list-units --type=target Targets activos
systemctl list-unit-files --type=target Targets disponibles
systemctl rescue|halt|poweroff|reboot shortcut a single-user|halt|apagar|reiniciar

Journal

journalctl Ver todos los logs desde el principio
journalctl -f Modo seguimiento. Ver en tiempo real
journal -u UNIDAD Ver logs de una unidad en particular


Referencias:

Uso de memoria RAM por proceso en Linux

La salida del clásico comando:
ps aux
...suele ser suficiente para ver el consumo de memoria de cada proceso.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  10644   708 ?        Ss   jun30   0:05 init [2] 
root         2  0.0  0.0      0     0 ?        S    jun30   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    jun30   0:14 [ksoftirqd/0]
root         6  0.0  0.0      0     0 ?        S    jun30   0:07 [migration/0]
[...]

USER: Propietario del proceso
PID: Identificador del proceso
%CPU: Relación de tiempo que el proceso usa CPU respecto al que está corriendo. Ojo, no es sobre el total del sistema.
%MEM: Relación de memoria (no swapeada) que el proceso usa respecto al total del sistema.
VSZ: Memoria virtual usada por el proceso completo.
RSS: Resident Set Size. Memoria no swapeada usada por el proceso.
TTY: Terminal asociado.
STAT: Estado del proceso.
START: Fecha de inicio del proceso.
TIME: Total de CPU usado desde que se inició.
COMMAND: Comando que lanzó el proceso.

Buceando por Internet he encontrado algunas filigranas dignas de mención y enormemente útiles para obtener la misma información:

  • Ordenado por orden de consumo:
ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS

  • Human readable:
 ps -eo size,pid,user,command | sort -rn | awk '{ hr[1024^2]="GB"; hr[1024]="MB"; for (x=1024^3; x>=1024; x/=1024) { if ($1>=x) { printf ("%-6.2f %s ", $1/x, hr[x]); break } } } { printf ("%-6s %-10s ", $2, $3) } { for ( x=4 ; x<=NF ; x++ ) { printf ("%s ",$x) } print ("\n") }'
  • Un script python fantástico
 Private  +   Shared  =  RAM used    Program

 80.0 KiB +  22.5 KiB = 102.5 KiB    init
116.0 KiB +  12.5 KiB = 128.5 KiB    minissdpd
116.0 KiB +  14.5 KiB = 130.5 KiB    chrome-sandbox
148.0 KiB +  20.5 KiB = 168.5 KiB    in.tftpd
[...]
101.6 MiB + 734.5 KiB = 102.3 MiB    nxserver.bin (2)
111.0 MiB +   1.4 MiB = 112.5 MiB    remmina
118.9 MiB +   6.1 MiB = 125.0 MiB    Xorg
134.9 MiB +  21.0 MiB = 155.9 MiB    chrome (5)
199.1 MiB +   3.7 MiB = 202.9 MiB    thunderbird
468.7 MiB +   5.5 MiB = 474.3 MiB    firefox
---------------------------------
                          1.7 GiB
=================================

¿Quien está consumiendo SWAP?

Excelente linea de comando para saber que procesos están ocupando SWAP y cuanto:


 for i in $( ls -d /proc/[0-9]* ) ; do SWAP=$(egrep --color '^VmSwap:[[:space:]]*[^0 ][0-9]* kB' "$i/status" 2>/dev/null ) && { cat "$i/cmdline" ; echo -n " (" $( basename $i ) ; echo -n "): " ; echo $( echo $SWAP | tr -s ' ' | cut -d' ' -f2- ) ; } ; done | sort -t':' -k2 -n

Nota: Este código no es mio. Lo encontré en Internet hace tiempo y tomé nota. Si eres la fuente original, por favor pásame el enlace para referenciarlo. Gracias.

Comandos útiles para "Space Reclaim"

Especialmente si se utilizan volúmenes de almacenamiento en SAN que están siendo ofrecidos en formato thin, es muy habitual que las salidas de comandos df no coincidan con los espacios en uso reportados por los propios sistemas SAN.
Esto se debe a que la mayoría de sistemas operativos no ejecutan la función unmap o trim cuando eliminan un archivo (conjunto de bloques en general), por lo que la SAN no es consciente de que ese espacio vuelve a estar libre.

Algunos sistemas de ficheros como Ext4 lo hacen automáticamente si se montan con la opción discard, pero no es lo habitual.

En casi todos los sistemas lo que sí existe es alguna forma de hacer un barrido al sistema de archivos para que ejecute las llamadas unmap sobre todos los bloques liberados para que la SAN se de por enterada. Son los siguientes:

Linux
#> fstrim /mountpoint

Vmware ESXi (>5)
#> cd /vmfs/volumes/DATASTORENAME
#> vmkfstool -y 60

El parámetro 60 hace referencia al porcentaje de espacio libre que se va a intentar reclamar. Este puede/debe ser ajustado de forma manual, pero 60 es un buen valor para comenzar y así lo recomienda VMWare.

Referencias:

http://linoxide.com/file-system/linux-reclaim-storage-space-ext4-unmap-feature/

Gestión de hora en dominio windows


Escenario

Un servidor de hora fiable dentro de una organización o acceso a uno (vg.- hora.roa.es).
Controladores de dominio de windows deben tomar la hora de este servidor de hora para servidrla a través del PDC al resto de servidores y PCs Windows (esto es automático).

Comandos


Comprobar de donde toma la hora un "Domain Controller":
w32tm /query /configuration

Forzar una resincronización
w32tm /resync

Añadir el servidor externo como proveedor de hora:
w32tm /config /syncfromflags:manual /manualpeerlist: hora.roa.es
w32tm /config /update

Recomendación

Hacer que todos los controladores de dominio de la organización tengan las mismas fuentes de hora.