Cómo medir bien el rendimiento de un VPS
Usa yabs.sh como primera medida y después fio, sysbench e iperf3. Aprende qué mide cada prueba y por qué una sola ejecución no describe el rendimiento real.
Qué significa comparar el rendimiento de un VPS
Para comparar el rendimiento de un VPS se miden cuatro aspectos: la velocidad de un solo núcleo de CPU, el ancho de banda de la memoria, el número de operaciones de disco pequeñas y aleatorias que el almacenamiento puede atender por segundo, y el rendimiento que proporciona el enlace de red. Una ejecución de yabs.sh proporciona los cuatro datos en unos diez minutos. Interpretar el resultado es más difícil, porque un VPS (servidor privado virtual) comparte el hardware físico con otros clientes. Por eso, la misma máquina puede mostrar un valor a las 03:00 y otro muy diferente a las 20:00.
El plan consiste en ejecutar yabs.sh para obtener una vista rápida y, después, ejecutar manualmente las herramientas que utiliza. Ejecutarlas directamente permite cambiar un indicador, observar cómo cambia el valor y entender qué estaba midiendo realmente. Hazlo después de configurar la máquina, no antes. Los pasos de los primeros diez minutos en un VPS nuevo van primero, porque un servidor que todavía está aplicando su primera ronda de actualizaciones obtiene resultados deficientes por motivos que no tienen relación con el hardware.
Examine la máquina antes de medirla
La mitad de cada benchmark incorrecto se debe a una máquina que el autor no entendió.
nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virtHypervisor vendor: KVM significa virtualización completa, por lo que ejecuta su propio kernel. systemd-detect-virt al mostrar lxc o openvz significa virtualización mediante contenedores: comparte el kernel del host, y los límites de CPU y memoria son configuraciones de cgroup (grupo de control), no hardware virtual. En un sistema con cgroup v2 puede leer directamente el límite de CPU.
cat /sys/fs/cgroup/cpu.maxmax 100000 significa que no hay cuota. 200000 100000 significa que puede usar 200000 microsegundos de CPU en cada periodo de 100000 microsegundos, lo que equivale a una cuota de dos núcleos. Un plan anunciado como 4 vCPU con una cuota de dos núcleos nunca obtendrá el resultado de cuatro núcleos, y ninguna herramienta de benchmark muestra una línea que indique el motivo.
df -hT / es importante por otro motivo: la columna Type. Si muestra overlay, está dentro de un contenedor y la prueba de disco que aparece a continuación requiere un cambio. Téngalo en cuenta ahora.
Supervisa el tiempo robado durante toda la prueba
El tiempo robado es la proporción de tiempo durante la cual tu CPU virtual estaba lista para ejecutarse, pero el hipervisor asignó el núcleo físico a otra máquina virtual. Es la señal individual más útil para determinar si un resultado se debe a tus vecinos y no al hardware.
vmstat 1 10Lee la columna st de la derecha. Un valor estable de 0 o 1 es normal. Los valores sostenidos por encima de 5 indican que el host está sobreasignado en ese momento. Por lo tanto, todas las cifras de CPU que registres durante ese intervalo serán bajas sin que tu máquina tenga la culpa. top muestra la misma cifra que %st en la línea de CPU. Mantén vmstat 1 ejecutándose en una segunda sesión SSH mientras realizas la prueba de rendimiento y anota la cifra de tiempo robado junto a cada resultado.
Empieza con yabs.sh
yabs.sh (Yet Another Bench Script) es un script de shell que descarga binarios estáticos de fio, iperf3 y Geekbench, los ejecuta y muestra un único resumen. Es el lenguaje común de las conversaciones sobre benchmarks de VPS, por lo que un resultado de yabs es la forma más rápida de comparar datos con otra persona.
La forma de una sola línea del propio proyecto es la siguiente.
curl -sL yabs.sh | bashEsto envía directamente a un shell lo que la URL proporcione en ese momento. Descárgalo, léelo y después ejecútalo.
curl -sLo yabs.sh https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/yabs.sh
less yabs.sh
bash yabs.shLas opciones van después de -s -- cuando se usa una tubería, o directamente después del nombre del archivo cuando se ejecuta una copia local. Las más útiles son: -f omite la prueba de disco, -i omite la prueba de red, -g omite Geekbench, -r reduce a dos las ubicaciones de iperf3, -j muestra los resultados como JSON y -w results.json escribe ese JSON en un archivo.
bash yabs.sh -r -w yabs-run1.jsonHay dos aspectos que debes conocer antes de la primera ejecución. Geekbench carga el resultado y muestra una URL pública de browser.geekbench.com, por lo que cualquiera que tenga ese enlace puede consultar el modelo de CPU y las puntuaciones. -g omite completamente esta prueba. Además, la fase de iperf3 genera tráfico de red real hacia servidores de varias regiones, y ese tráfico cuenta para la cuota mensual de ancho de banda. En un enlace de 1 Gbit/s, una fase de red completa puede transferir decenas de gigabytes. Usa -r si tienes una cuota pequeña y -i en un enlace con tarificación por consumo.
Qué significa cada parte de la salida de yabs
La sección de disco ejecuta fio con una combinación de lectura y escritura al 50/50 en cuatro tamaños de bloque: 4k, 64k, 512k y 1m. Informa de los IOPS (operaciones de entrada/salida por segundo) y del ancho de banda para cada tamaño. La fila de 4k es la más importante para una base de datos, un servidor de correo o cualquier sistema que realice muchas escrituras pequeñas, porque la mayoría de las operaciones de E/S del servidor son pequeñas y dispersas. La fila de 1m es la relevante para copias de seguridad y vídeo, donde se transfieren secuencias largas de bytes.
La sección de red ejecuta iperf3 contra servidores públicos de varias regiones, en ambas direcciones y mediante flujos paralelos. Interprete aquí un número bajo como una pregunta, no como una respuesta, porque los servidores públicos de iperf3 son compartidos y a menudo están saturados. Por tanto, un resultado bajo puede deberse al extremo remoto.
La sección de Geekbench proporciona una puntuación de un solo núcleo y otra de varios núcleos. La puntuación de un solo núcleo permite prever cuánto tarda en finalizar una solicitud, una compilación o una consulta. La puntuación de varios núcleos indica principalmente cuántos núcleos obtuvo realmente.
Disco: ejecute fio usted mismo
fio (flexible IO tester) es la herramienta que usa la sección de disco de yabs. Ejecutarla directamente permite entender el significado de sus opciones.
sudo apt update && sudo apt install -y fio sysbench iperf3Esta prueba realiza lecturas aleatorias de 4k, con una profundidad de cola de 32, en el sistema de archivos que realmente le interesa:
fio --name=randread4k --filename=./fio-testfile --size=2G --bs=4k \
--rw=randread --ioengine=libaio --iodepth=32 --direct=1 \
--runtime=60 --time_based --group_reportingLa línea de resumen que debe buscar en la salida tiene este aspecto.
read: IOPS=184k, BW=719MiB/s (754MB/s)(42.1GiB/60001msec)Debajo, fio muestra un bloque clat percentiles. El percentil 99.00 es la cifra que conviene citar, porque indica cuánto esperó la solicitud más lenta de cada 100. La latencia media oculta precisamente las esperas que percibe el usuario.
--direct=1abre el archivo conO_DIRECT, por lo que las lecturas omiten la caché de páginas del kernel. Sin esta opción, la segunda pasada sobre un archivo de 2G en una máquina con 8G de RAM se sirve desde la memoria y fio informa de millones de IOPS. La cifra es real, pero corresponde a la memoria.--ioengine=libaioenvía solicitudes asíncronas. Esto permite que--iodepth=32mantenga 32 solicitudes en curso. Con un motor síncrono comopsync, un valor de iodepth superior a 1 no hace nada, por lo que se mide una solicitud cada vez.--time_based --runtime=60ejecuta la prueba durante 60 segundos exactos en lugar de procesar una cantidad fija de trabajo. Así, un disco rápido y uno lento usan el mismo tiempo real y la comparación es justa.--size=2Gestablece el tamaño del archivo de prueba. Manténgalo por encima del tamaño de cualquier caché de la ruta y compruebe primero que haya espacio libre suficiente.
La escritura aleatoria usa el mismo comando con --rw=randwrite. Ejecútela por separado y elimine después el archivo.
fio --name=randwrite4k --filename=./fio-testfile --size=2G --bs=4k \
--rw=randwrite --ioengine=libaio --iodepth=32 --direct=1 \
--runtime=60 --time_based --group_reporting
rm -f ./fio-testfilePara una combinación más parecida al tráfico real, use --rw=randrw --rwmixread=70. El tipo de almacenamiento determina estos resultados más que cualquier opción. Esta diferencia se explica en la diferencia entre el almacenamiento NVMe y SATA SSD en un VPS.
Cuando fio se detiene con Unknown error -1
La E/S directa no está disponible en todos los sistemas de archivos. overlay, el sistema de archivos que Docker proporciona a un contenedor de forma predeterminada, y varios sistemas de archivos de red no admiten O_DIRECT. Por eso, libaio envía una solicitud que el kernel no puede completar y fio abandona la ejecución:
fio: io_u error on file ./fio-testfile: Unknown error -1: read offset=0, buflen=4096
fio: pid=1234, err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1Ejecute df -hT . primero. Si la columna Type indica overlay, asigne --filename a una ruta del almacenamiento real, como un volumen montado mediante bind, o ejecute fio en el host en lugar de hacerlo en el contenedor. Si no puede acceder al almacenamiento real, una ejecución síncrona con búferes al menos confirma que el comando es correcto.
fio --name=randread4k-buffered --filename=./fio-testfile --size=256M --bs=4k \
--rw=randread --ioengine=psync --direct=0 --numjobs=1 \
--runtime=15 --time_based --group_reporting
rm -f ./fio-testfileInterprete correctamente esa ejecución. Después de la primera pasada, el archivo de 256M permanece en la caché de páginas, por lo que la cifra de IOPS describe la RAM. Use esta ejecución para confirmar que fio está instalado y que las opciones se interpretan correctamente. Nunca la presente como un resultado del disco.
Por qué dd no es una prueba de rendimiento del disco
dd aparece en muchos hilos sobre VPS y responde a una sola pregunta concreta.
dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtestMide el rendimiento de escritura secuencial con un hilo y una solicitud en curso. Es una comprobación básica razonable. No dice nada sobre la E/S aleatoria ni sobre lo que ocurre cuando llegan 32 solicitudes a la vez. Si se elimina oflag=direct, mide principalmente la rapidez con la que el kernel acepta las escrituras en la memoria. Por eso, las cifras de dd citadas en las publicaciones de los foros suelen ser absurdas.
CPU: sysbench cpu
sysbench cpu --cpu-max-prime=20000 --threads=1 run
sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) runEl valor que debe conservar es events per second. Ejecute primero la prueba con un solo hilo. Ese valor determina la rapidez con la que finaliza una solicitud PHP o se completa un trabajo de compilación, y es el que más varía entre hosts con el mismo precio. Después, ejecútela con todos los hilos. Esto muestra si sus vCPU son núcleos independientes o partes de un mismo núcleo.
Tenga claro qué mide esta prueba: sysbench busca repetidamente números primos mediante aritmética con enteros de 64 bits. No somete a prueba el ancho de banda de la memoria, las unidades vectoriales ni la caché de una forma que se parezca a una carga de trabajo real. Por tanto, es útil para comparar dos hosts, pero no para predecir cómo se ejecutará su aplicación.
Ubuntu 24.04 incluye sysbench 1.0.20, donde el nombre de la prueba aparece primero. Si copia un comando con --test=cpu de una publicación antigua, obtiene WARNING: the --test option is deprecated. Las puntuaciones de sysbench 0.4 y sysbench 1.0 no son comparables en absoluto. Por eso, nunca se compare con un valor publicado que no indique su versión.
Memoria: sysbench memory
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=write --threads=1 run
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=read --threads=1 runEl resultado se expresa en MiB/sec, y las lecturas son más rápidas que las escrituras en todas las máquinas. Mantenga --memory-block-size en 1M y use el mismo valor en todos los hosts que compare. Con 1K, el valor se desploma porque la sobrecarga por operación se paga mil veces más a menudo. Por tanto, se mide el coste del bucle en lugar del ancho de banda de la memoria. Esta es la opción que más suele presentar valores distintos en las puntuaciones de memoria publicadas.
Red: iperf3
La forma fiable de probar el rendimiento es hacerlo contra una segunda máquina que controle, porque así sabe qué ocurre en ambos extremos.
En el extremo remoto:
iperf3 -sEl comando escucha en TCP 5201. Abra el puerto solo para la dirección desde la que realiza la prueba y ciérrelo al terminar. Reglas básicas del firewall ufw en un VPS explica la sintaxis.
Desde el VPS que está probando:
iperf3 -c 203.0.113.10 -t 30
iperf3 -c 203.0.113.10 -t 30 -R
iperf3 -c 203.0.113.10 -t 30 -P 8La primera prueba mide la subida desde la máquina que se está probando. -R invierte la dirección y mide la descarga. -P 8 abre ocho flujos paralelos.
Ejecute tanto el flujo único como la versión paralela, porque responden a preguntas distintas. Una conexión TCP solo puede mantener tantos datos sin confirmar como permita su ventana, por lo que su límite es aproximadamente el tamaño de la ventana dividido por el tiempo de ida y vuelta. Con una latencia de 80 ms y una ventana de 4 MB, ese límite es de unos 400 Mbit/s, independientemente de la velocidad del enlace subyacente. La cifra del flujo único indica qué velocidad obtendrá una descarga individual. La cifra de los flujos paralelos indica la capacidad del enlace.
Vigile el límite de ancho de banda mientras realiza estas pruebas. Treinta segundos a 1 Gbit/s transfieren unos 3.75 GB, y ejecutará la prueba varias veces en cada dirección.
Cifras de referencia y cómo interpretar las tuyas
The data behind this chart
[
{
"device": "Local NVMe",
"iops_4k_read": "180,000"
},
{
"device": "Local SATA SSD",
"iops_4k_read": "90,000"
},
{
"device": "Network block",
"iops_4k_read": "12,000"
},
{
"device": "Spinning disk",
"iops_4k_read": "180"
}
]Un volumen NVMe local suele alcanzar cerca de 180,000 IOPS de lectura aleatoria de 4k en los resultados publicados. Un SSD SATA local obtiene alrededor de 90,000. El almacenamiento de bloques conectado a la red, donde cada solicitud atraviesa una red antes de llegar al disco, se acerca más a 12,000. Un disco magnético alcanza aproximadamente 180, porque mueve un cabezal físico para cada solicitud aleatoria.
Estas son cifras publicadas habituales para cada clase de almacenamiento, no mediciones de un único host. Úsalas solo para comprobar que tu propio resultado está en el orden de magnitud correcto. Si un plan comercializado como NVMe obtiene unos pocos miles de IOPS de lectura aleatoria de 4k, confirma primero que --direct=1 estaba activado. Si lo estaba, el almacenamiento no corresponde a lo que describe la página del producto o lo compartes con un vecino que genera una carga muy alta.
Por qué una ejecución no es un benchmark
Un único resultado es una instantánea de un minuto en una máquina compartida. Trátelo como una sola muestra.
- Ejecute cada prueba al menos cinco veces, distribuidas en distintas horas y en al menos dos días diferentes. Conserve la mediana y la dispersión. Un resultado publicado sin dispersión es una cifra de marketing.
- Registre el tiempo de steal junto a cada ejecución. Descarte las ejecuciones en las que
sthaya sido alto o, como mínimo, indique que lo fue. - Ejecute la prueba de disco con dos duraciones. Muchos planes ofrecen una asignación de IOPS en ráfaga que se repone con el tiempo, por lo que una ejecución de fio de 60 segundos mide la ráfaga, mientras que
--runtime=600mide el rendimiento mínimo. El rendimiento mínimo es el que obtiene en un día malo. - Compruebe que no haya ningún otro proceso en ejecución.
unattended-upgradesiniciar una transacción de apt en mitad de una prueba de CPU le resta puntos reales, yps -e -o comm= | grep -E 'apt|dpkg'antes de cada ejecución tarda un segundo. - Cambie una sola variable cada vez. Las diferentes versiones de las herramientas, tamaños de bloque o cantidades de subprocesos producen cifras que no se pueden comparar, por muy similares que parezcan.
Cuando compare dos proveedores, ejecútelos a la misma hora del mismo día. De lo contrario, habrá medido la hora del día.
Evalúe su propia carga de trabajo al final
Las herramientas sintéticas clasifican las máquinas. Solo su propia carga de trabajo indica si una máquina es suficiente. Mida el tiempo de la tarea que realmente ejecuta.
time tar -czf /tmp/bench.tgz /usr/share
rm -f /tmp/bench.tgzEsto comprime unos cientos de megabytes, por lo que utiliza la CPU y el disco al mismo tiempo. El resultado cambia cuando cambia cualquiera de los dos. La advertencia de Removing leading / from member names es normal. Mejor aún, mida el tiempo de su propia compilación, de su consulta más lenta o de la generación de su propia página. Si una compilación tarda 4 minutos en un host y 7 en otro, la cuestión queda resuelta, independientemente de lo que indique Geekbench. Esta es también la medición que indica cuándo deja de compensar pagar por una máquina más potente. Conviene saberlo antes de leer cuánto cuesta realmente un VPS al mes o trasladar la carga de trabajo a un servidor dedicado.
FAQ
¿Por qué obtengo un resultado de benchmark diferente cada vez que lo ejecuto?
Un VPS comparte la CPU física, el almacenamiento y la red con otros usuarios, por lo que el resultado depende de lo que estén haciendo en ese momento. Ejecute vmstat 1 durante la prueba y lea la columna st: un steal time sostenido superior a 5 indica que el host estaba ocupado y que la puntuación de CPU es baja por motivos ajenos a su máquina. La solución es aplicar un método, no ajustar parámetros. Ejecute cada prueba cinco veces o más en diferentes horas y, después, informe de la mediana junto con la dispersión.
¿Por qué fio informa de millones de IOPS?
Casi siempre porque falta --direct=1. Sin esta opción, fio lee mediante la caché de páginas del kernel. Después de la primera pasada, el archivo de prueba de 2G se sirve desde la RAM y lo que se ha medido es el ancho de banda de la memoria. Añada --direct=1 y mantenga el archivo de prueba por encima del tamaño de cualquier caché del recorrido. Si --direct=1 falla con err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1, ejecute df -hT .: un Type de overlay no admite O_DIRECT, por lo que debe dirigir la prueba al almacenamiento real.
¿Es suficiente yabs.sh por sí solo?
Para una primera evaluación, sí. Ejecuta fio con cuatro tamaños de bloque, iperf3 en ambas direcciones y Geekbench, y muestra un resumen que otras personas pueden leer. Deja de ser suficiente cuando necesita saber por qué un valor es el que es, porque no puede variar sus flags para cada prueba. Cuando un resultado de yabs parece incorrecto, reprodúzcalo directamente con fio o sysbench y cambie un flag cada vez.
¿Qué único valor predice cómo responderá mi aplicación?
La velocidad de CPU de un solo núcleo y la latencia de lectura aleatoria 4k, en ese orden, para la mayoría de las cargas de trabajo web y de bases de datos. Las cifras de rendimiento parecen impresionantes y rara vez determinan algo, porque una solicitud típica es pequeña. Informe del percentil 99 del bloque clat percentiles de fio en lugar del promedio, ya que la solicitud lenta de cada cien es la que nota el usuario.
¿Necesito instalar algo antes de realizar el benchmark?
fio, sysbench e iperf3 están disponibles en los repositorios de Ubuntu y Debian: sudo apt install -y fio sysbench iperf3. yabs.sh solo necesita curl, porque descarga binarios estáticos para todo lo que falte. Elimine todos los archivos de prueba al terminar, ya que un archivo de fio de 2G dejado en un disco de 20G puede convertirse en una alerta de disco lleno semanas después.