SSD Nodes Learn 🎉 VPS desde $4.99/mes
Guías Matt ConnorPor Matt Connor

CPU steal time en un VPS: detectar vecinos ruidosos

Aprende a leer la columna st de vmstat y a distinguir un vecino ruidoso de la sobrecarga propia cuando tu VPS pierde tiempo de CPU disponible.

Qué mide realmente el tiempo de CPU robado

El tiempo de CPU robado es la proporción de tiempo durante la que la CPU virtual estaba lista para ejecutarse, sin nada que esperar, mientras el hipervisor asignaba el núcleo físico a otro guest. El trabajo estaba en cola. El núcleo estaba asignado a otra máquina virtual. Linux cuenta esos ciclos por separado y los informa como st. Esto permite distinguir entre «mi servidor está ocupado» y «mi servidor está esperando su turno».

Esa diferencia es el motivo por el que existe el contador. El tiempo que sus propios procesos pasan en la CPU se informa como us (usuario) o sy (sistema). El tiempo que una tarea pasa bloqueada esperando almacenamiento se informa como wa (espera de E/S). Una vCPU (CPU virtual) que puede ejecutarse, está en la cola de ejecución, no tiene operaciones de E/S pendientes y aun así no se está ejecutando se informa como st. Nada dentro de su servidor puede eliminar ese estado, porque la decisión de planificación se toma un nivel por debajo, en el host.

Esto se deriva directamente de cómo comparte un VPS una máquina física entre muchos guest. La causa habitual es un vecino: otro guest del mismo nodo está usando mucha CPU y el host distribuye los núcleos entre ambos. Hay una segunda causa que suele pasarse por alto. Muchos proveedores limitan una vCPU compartida a una fracción de un núcleo físico. En varios hipervisores, ese límite impuesto se contabiliza como tiempo robado dentro del guest. Por tanto, un valor alto de st indica que el núcleo no se le asignó. No siempre indica quién lo estaba usando.

De dónde procede el valor de steal

El kernel no puede medir steal por sí solo porque no puede ver el host. El hipervisor se lo comunica. En KVM, el host escribe un contador por vCPU en una página compartida con el guest, y el guest lo acumula cuando el kernel se compila con CONFIG_PARAVIRT_TIME_ACCOUNTING, como ocurre con todos los kernels de las distribuciones. Xen informa del mismo dato mediante su área de estado de ejecución. El total llega al espacio de usuario en un único lugar:

head -1 /proc/stat

La línea cpu contiene diez contadores, expresados en ticks de USER_HZ desde el arranque y en este orden: user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice. steal es el octavo valor después de la etiqueta. Todas las herramientas siguientes, vmstat, top, mpstat y cualquier exportador de Prometheus, leen ese mismo campo y convierten dos muestras en un porcentaje.

Una consecuencia es más importante que las demás. Si el hipervisor nunca exporta el contador, el campo permanece en cero para siempre y todas las herramientas basadas en él muestran un 0.0 tranquilo mientras el host está sobrecargado. KVM y Xen lo exportan. Los guests en VMware y Hyper-V suelen informar de un cero constante. Compruebe la plataforma antes de confiar en un cero:

systemd-detect-virt

Este comando muestra el nombre de la plataforma, como kvm, xen, vmware o microsoft, y none en bare metal. Dentro de un contenedor informa del runtime en su lugar, como lxc, docker o podman, lo que proporciona información sobre el contenedor, no sobre la máquina subyacente. En kvm, un cero es una prueba real de que el host le está dando un buen trato. En una plataforma que nunca rellena el campo, un cero no demuestra nada, y la contención debe evaluarse midiendo el tiempo de ejecución de trabajo real.

¿Cómo compruebo el tiempo de steal de CPU en un VPS?

vmstat forma parte del paquete procps. Está presente en casi todas las imágenes de VPS de Ubuntu y Debian, pero falta en algunas imágenes mínimas de contenedores, así que instálelo antes de depender de él.

sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5

vmstat --version muestra una línea como vmstat from procps-ng 4.0.4. Si aparece, la herramienta está instalada y está leyendo contadores reales del kernel. vmstat 1 5 toma después una muestra por segundo, cinco veces.

procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 1  0      0 3216484  98304 1284360    0    0     4    18   62  110  3  1 96  0  0  0
 2  0      0 3216232  98304 1284360    0    0     0     0  248  431  6  2 84  0  8  0

Busque la columna st en el bloque cpu de la derecha. Las compilaciones actuales de procps-ng muestran después una columna gu para el tiempo del invitado KVM, por lo que st es la segunda empezando por la derecha y no la última. Lea la columna por su nombre de encabezado, porque esa posición ha cambiado entre versiones.

Dos hábitos ayudan a interpretar el resultado correctamente. La primera línea de datos es el promedio desde el arranque, así que ignórela y lea las líneas siguientes. Además, una sola muestra no es una medición, porque el steal llega en ráfagas: ejecute vmstat 1 60 y monitorice un minuto completo antes de sacar conclusiones.

top informa del mismo valor en su línea de resumen %Cpu(s), en el campo marcado como st:

%Cpu(s):  6.2 us,  2.1 sy,  0.0 ni, 83.9 id,  0.0 wa,  0.0 hi,  0.3 si,  7.5 st

Para obtener información por núcleo, añada sysstat:

sudo apt-get install -y sysstat
mpstat -P ALL 1 5

mpstat muestra una fila por CPU con una columna %steal, que indica si todas las vCPU están afectadas o sólo una. Para conservar el historial que necesita un ticket de soporte, guarde las muestras en lugar de leerlas directamente en pantalla:

date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.log

Ejecute esto desde cron durante las horas en las que sospeche que ocurre el problema. El archivo permite pasar de decirle a un proveedor «anoche parecía lento» a mostrarle los diez minutos exactos.

¿Qué significan los valores de steal?

  • Un valor estable de 0.0. Es normal, o la plataforma no informa de steal. Confírmelo con systemd-detect-virt antes de darlo por bueno.
  • Picos de unos pocos puntos porcentuales durante varios segundos. Es normal en cualquier nodo compartido. Puede iniciarse una compilación de otro usuario o el host puede ejecutar sus copias de seguridad.
  • Entre 1 y 5 por ciento de forma sostenida en un plan compartido. Es lo esperado. El precio refleja el uso compartido de la CPU.
  • Entre 5 y 10 por ciento de forma sostenida. Es una ralentización medible. Empiece a recopilar pruebas y compare las mismas horas durante varios días.
  • Más de 10 por ciento durante horas. El nodo está sobreasignado para su carga de trabajo. Este nivel justifica abrir un ticket de soporte o migrar a otro nodo.

Considere estos intervalos como una guía de interpretación y no como una especificación, porque ningún proveedor garantiza un valor de steal en un plan compartido. Evalúelos en función de lo que ejecuta. Un trabajo por lotes nocturno puede absorber un 15 por ciento de steal sin que nadie lo note. Un servicio sensible a la latencia lo refleja en el p99 mucho antes de que la media resulte alarmante. Por eso, las cargas de trabajo sensibles a la latencia, como los bots de trading deben ejecutarse en núcleos dedicados.

¿Cuánto le cuesta el steal time?

El cálculo es breve. Si se toma una fracción s de su tiempo de CPU, un trabajo que necesita una cantidad fija de CPU tarda 1 / (1 - s) veces más tiempo de reloj. Para un trabajo que necesita 60 segundos de CPU:

ChartWall clock time for a job needing 60 seconds of CPU
The data behind this chart
[
  {
    "steal_percent": 0,
    "wall_clock_seconds": "60.0"
  },
  {
    "steal_percent": 3,
    "wall_clock_seconds": "61.9"
  },
  {
    "steal_percent": 8,
    "wall_clock_seconds": "65.2"
  },
  {
    "steal_percent": 15,
    "wall_clock_seconds": "70.6"
  },
  {
    "steal_percent": 25,
    "wall_clock_seconds": "80.0"
  },
  {
    "steal_percent": 40,
    "wall_clock_seconds": "100.0"
  }
]

Con 3 por ciento, un valor habitual en un plan compartido, el trabajo tarda 61.9 segundos en lugar de 60.0. Nadie abre un ticket por eso. Con 8 por ciento tarda 65.2 segundos. Con 40 por ciento, el mismo trabajo necesita 100.0 segundos, y una cola que antes se vaciaba empieza a crecer.

Son valores calculados, no mediciones. El modelo supone un único hilo ejecutable y que el steal se distribuye uniformemente durante el intervalo. Los servicios reales suelen verse más afectados que lo que indica la curva, porque una porción de tiempo robada puede interrumpir una petición y el retraso se propaga a todo lo que espera a esa petición. Para obtener su propio valor en lugar de usar una fórmula, haga un benchmark de la VPS durante una hora con poca carga y repítalo durante una hora con mucha carga. Registre st en ambas ventanas.

¿Es steal o es otra cosa?

Steal se confunde fácilmente con otros síntomas. Lea los contadores juntos, en la misma línea de vmstat.

  • st alto mientras r y us se mantienen bajos: el host no le está asignando la CPU. Eso es steal.
  • r muy por encima del número de vCPU, con us alto y st cercano a cero: está ejecutando más trabajo del que sus propias CPU pueden procesar. Compare r con la salida de nproc. Esto es una sobresuscripción propia, no un vecino.
  • wa alto con st cercano a cero: las tareas están bloqueadas esperando al almacenamiento. Es un problema distinto y requiere otra solución.
  • Load average alto mientras st y us están bajos: la métrica de carga también cuenta las tareas no interrumpibles. Por lo general, esto indica un dispositivo bloqueado o un montaje de red detenido, no un problema de CPU.

Los planes burstable requieren una explicación aparte. Proporcionan un saldo de créditos que aumenta mientras está inactivo y disminuye mientras está ocupado. Cuando se agota, el proveedor limita el rendimiento a una tasa base. En algunas plataformas, ese límite se informa como steal. En otras, no es visible desde el sistema invitado y simplemente recibe menos ciclos por segundo. Lea la descripción del plan antes de atribuir el problema a un vecino.

Por qué un contenedor no muestra tiempo de steal

Steal es una propiedad de la máquina virtual, no del contenedor que se ejecuta dentro de ella. Un contenedor Docker en su propio VPS comparte el /proc del host, por lo que un valor de st leído desde dentro es el steal del VPS, que es el valor que necesita. La virtualización basada en contenedores que se ofrece como VPS funciona de otra manera. Cuando lxcfs está habilitado, /proc/stat dentro del contenedor se genera a partir de la contabilidad de cgroups, y steal es cero por diseño. Una pila de monitorización que recopila datos sólo desde dentro puede mostrar un cero estable y tranquilo mientras la máquina física subyacente se queda sin CPU.

Dentro de un contenedor, el contador con el mismo significado es la limitación por cuota de CPU. En cgroup v2:

cat /sys/fs/cgroup/cpu.stat

nr_throttled cuenta los periodos de aplicación en los que el grupo alcanzó su cuota de CPU, y throttled_usec suma el tiempo que permaneció bloqueado. Un valor creciente de nr_throttled indica que el proceso estaba listo para ejecutarse, pero no se estaba ejecutando. La experiencia es la misma que con steal, pero la causa es un límite configurado por usted. Compruebe sus propios límites antes de culpar al host, especialmente si ejecuta sus servicios en Docker en un VPS con límites de CPU en el archivo compose. La virtualización en capas añade otro punto donde puede perderse tiempo, porque una máquina virtual dentro de su VPS acumula el steal del VPS y su propio retraso de planificación. Téngalo en cuenta si ejecuta virtualización anidada en un VPS.

Qué hacer ante un steal sostenido

Ningún ajuste dentro del guest corrige el steal, porque el scheduler que toma la decisión se ejecuta fuera del guest. Hay cuatro medidas efectivas.

Recopile primero las pruebas. Registre las marcas de tiempo en UTC, la duración de cada episodio, con qué frecuencia se repite y si mpstat muestra que afecta a una vCPU o a todas. Una semana de muestras registradas vale más que una captura de pantalla.

Abra un ticket con esos datos. Haga dos preguntas directas: ¿este nodo está sobresuscrito durante esos intervalos? ¿Pueden mover mi instancia? Incluya la salida de vmstat y las horas exactas. Los proveedores actúan cuando existe un intervalo reproducible, y un ticket que sólo indica que el servidor está lento recibe como respuesta una solicitud de datos concretos. Cuánto de este trabajo puede delegar es una de las diferencias prácticas entre un VPS administrado y uno no administrado.

Solicite una migración. Mover un guest a un nodo con menos carga es una tarea habitual para un proveedor y normalmente requiere un reinicio breve. Es la solución que no tiene coste adicional y resuelve el caso común: un nodo puede alojar temporalmente varios vecinos con una carga elevada.

Elimine la contención mediante una compra. Un plan con vCPU dedicada reserva núcleos físicos para su instancia, por lo que el contador permanece en cero. Cuesta más cada mes y es la respuesta adecuada para una carga de trabajo que no puede absorber esa variabilidad. Si aún no es suficiente, o también quiere disponer en exclusiva del ancho de banda de memoria, el siguiente paso es usar un servidor dedicado en lugar de un VPS.

Mientras espera una de esas medidas, reduzca el impacto del steal. Ejecute menos hilos de trabajo que vCPU disponibles, porque los hilos que no consiguen un núcleo sólo añaden cambios de contexto. Traslade las tareas por lotes a las horas en que el nodo está menos ocupado; su propio registro ya le indica cuáles son. Después, vuelva a medir con el mismo comando durante las mismas horas, para determinar si el cambio funcionó en lugar de hacer suposiciones.

FAQ

¿Cuál es un tiempo de steal normal en una VPS?

En un plan compartido, los picos breves y un valor sostenido inferior a aproximadamente 5 por ciento son normales, porque una CPU compartida implica que el host distribuye los núcleos físicos entre los guests. Un valor de dos dígitos sostenido durante horas no es normal y justifica abrir un ticket. En un plan con vCPU dedicada, la lectura esperada es 0.0, por lo que cualquier otro valor debe notificarse como un fallo. Evalúe el número según su propia carga de trabajo: un proceso por lotes nocturno puede tolerar steal, pero una API sensible a la latencia no.

¿Un plan más grande solucionará un tiempo de steal elevado?

No por sí solo. Tener más vCPU en el mismo nodo compartido implica que hay más CPU virtuales compitiendo por los mismos núcleos físicos congestionados, y el porcentaje puede mantenerse exactamente igual. Lo que elimina steal es una asignación de CPU dedicada o la migración a un nodo con menos carga. Una cuota mayor de una máquina ocupada sigue siendo una cuota de una máquina ocupada.

¿Por qué mi VPS muestra 0 de steal aunque es claramente lenta?

Hay dos razones habituales. Es posible que el hipervisor no exporte el contador, algo habitual en plataformas VMware y Hyper-V, por lo que el campo permanece en cero independientemente de lo que haga el host. Ejecute systemd-detect-virt para comprobar qué plataforma utiliza. Si no es así, el cuello de botella está en otro lugar: compruebe wa para detectar esperas de almacenamiento, compare r con nproc para evaluar su propia sobrecarga y consulte /sys/fs/cgroup/cpu.stat dentro de los contenedores para detectar la limitación por cuota.

¿Puedo reducir el tiempo de steal desde dentro del servidor?

No puede cambiar la planificación del host desde el guest. Sólo puede reducir sus efectos. Ejecute menos hilos de trabajo que vCPU disponibles, para que haya menos trabajo en la cola de ejecución esperando un núcleo que no queda libre. Traslade los procesos por lotes a las horas en que el nodo tenga menos carga. Almacene los resultados en caché para que menos solicitudes necesiten CPU. Los cambios que realmente eliminan steal, como migrar a otro nodo o usar núcleos dedicados, dependen del proveedor.