Cómo medir bien el rendimiento de un VPS
Ejecute yabs.sh primero y después fio, sysbench e iperf3. Interprete CPU, memoria, disco y red, y repita las pruebas: una sola medición casi no sirve.
Qué significa comparar el rendimiento de un VPS
Para comparar el rendimiento de un VPS, mida cuatro aspectos: la velocidad de un solo núcleo de CPU, el ancho de banda de memoria disponible en la máquina, la cantidad de operaciones pequeñas y aleatorias de disco que el almacenamiento atiende cada segundo y el rendimiento que ofrece el enlace de red. Una ejecución de yabs.sh proporciona resultados de CPU, disco y red en unos diez minutos; use la prueba de memoria independiente que aparece más adelante para medir el ancho de banda de memoria. Interpretar el resultado es más difícil, porque un VPS (servidor privado virtual) comparte el hardware físico con otros usuarios. Por eso, la misma máquina puede mostrar un valor a las 03:00 y otro muy distinto a las 20:00.
El plan consiste en ejecutar yabs.sh para obtener una visión rápida y, después, ejecutar manualmente las herramientas que utiliza internamente. Ejecutarlas directamente permite cambiar un indicador, observar cómo cambia el valor y entender qué estaba midiendo realmente. Hágalo después de configurar la máquina, no antes. Los pasos de los primeros diez minutos en un VPS nuevo deben realizarse primero, porque un sistema que todavía está aplicando su primera ronda de actualizaciones ofrece resultados de referencia deficientes por motivos que no tienen relación con el hardware.
Examine la máquina antes de medirla
La mitad de cada benchmark defectuoso se debe a una máquina que su 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. La impresión de systemd-detect-virt, 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 el límite de CPU del cgroup del contenedor; la siguiente ruta se aplica cuando ese cgroup está montado en /sys/fs/cgroup.
cat /sys/fs/cgroup/cpu.maxmax 100000 significa que este cgroup no tiene una cuota propia; los cgroups antecesores aún pueden imponer una. 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á resultados equivalentes a cuatro núcleos. Las herramientas de benchmark pueden identificar esta restricción: VoxelBench informa de las cuotas de CPU y marca una CPU compartida o limitada cuando el host expone muchas más CPU de las que el servidor puede usar.
df -hT / importa por otro motivo: la columna Type. Si muestra overlay, está dentro de un contenedor y los resultados de disco describirán el almacenamiento que haya debajo de esa capa overlay. Anótelo ahora.
Supervise el steal time durante toda la prueba
El steal time es el porcentaje de tiempo que la CPU virtual esperó de forma involuntaria mientras el hipervisor no la planificaba. Es una señal útil de que no hay tiempo de CPU disponible, pero no permite distinguir entre vecinos con mucha carga y el proveedor aplicando la cuota de CPU.
vmstat 1 10Lea la columna st de la derecha. Un steal time sostenido significa que la CPU no estuvo disponible para el sistema invitado, pero un valor superior al 5% no demuestra que el host esté sobresuscrito. Los proveedores pueden exponer deliberadamente la aplicación de la cuota de CPU como steal time. top muestra la misma cifra que %st en la línea de CPU. Mantenga vmstat 1 en ejecución en otra sesión SSH mientras realiza las pruebas de rendimiento y anote la cifra de steal junto a cada resultado.
Comience con yabs.sh
yabs.sh (Yet Another Bench Script) es un script de shell que ejecuta fio, iperf3 y Geekbench, y muestra un único resumen. Usa fio e iperf3 si ya están instalados y descarga binarios estáticos si no lo están. Es el formato común en los debates sobre benchmarks de VPS, por lo que una salida de yabs es la forma más rápida de comparar resultados con otra persona.
La forma de una sola línea del propio proyecto es la siguiente.
curl -sL yabs.sh | bashEsto pasa directamente a un shell todo lo que la URL sirva en ese momento. Descárguelo, léalo y después ejecútelo.
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 de 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 tres 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.jsonDebe conocer dos aspectos 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 esa prueba. Además, la fase de iperf3 genera tráfico real hacia servidores de varias regiones, y ese tráfico se descuenta de la cuota mensual de ancho de banda. En un enlace de 1 Gbit/s, una fase de red completa puede transferir decenas de gigabytes. Use -r si la cuota es reducida y -i si el enlace se factura según el 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 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 corresponde a copias de seguridad y vídeo, donde se mueven 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. Considere un valor bajo como una pregunta, no como una conclusión, porque los servidores públicos de iperf3 son compartidos y suelen estar 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 estimar la rapidez con la que termina una petición, una compilación o una consulta. La puntuación de varios núcleos indica principalmente cuántos núcleos recibió realmente.
Disco: ejecutar fio directamente
fio (flexible IO tester) es la herramienta que usa la sección de disco de yabs. Ejecutarla directamente permite entender qué hace cada opción.
sudo apt update && sudo apt install -y fio sysbench iperf3Una prueba de lectura aleatoria de 4k, con una profundidad de cola de 32 y 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 formato.
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 más útil para informar, porque indica cuánto esperó la solicitud más lenta de cada cien. La latencia media oculta precisamente las pausas que nota 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. Esa 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, una profundidad de E/S superior a 1 no hace nada, por lo que se mide una solicitud cada vez.--time_based --runtime=60ejecuta la prueba durante 60 segundos fijos 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 sigue siendo válida.--size=2Gestablece el tamaño del archivo de prueba. Manténgalo mayor que cualquier caché de la ruta y compruebe antes 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 cercana al tráfico real, use --rw=randrw --rwmixread=70. La clase de almacenamiento utilizada influye en estos resultados más que cualquier opción. Esta diferencia se explica en la diferencia entre el almacenamiento SSD NVMe y SATA en un VPS.
Cuando fio se detiene con Unknown error -1
La E/S directa no está disponible en todos los sistemas de archivos. Por eso, cuando fio falla en su primera solicitud con --direct=1 establecido, lo primero que debe descartarse es la E/S directa. El error puede tener este aspecto:
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 primero df -hT .. Un Type de overlay, el sistema de archivos que Docker proporciona de forma predeterminada a un contenedor, no es la causa por sí solo. overlayfs pasa O_DIRECT al sistema de archivos subyacente y sólo lo rechaza cuando ese sistema de archivos no admite E/S directa. Por tanto, --direct=1 --ioengine=libaio funciona sobre un overlay basado en ext4 o xfs. Cuando el sistema de archivos subyacente al archivo de prueba realmente no admite E/S directa, fio suele indicarlo al abrir el archivo: fio: looks like your file system does not support direct=1/buffered=0. En ese caso, dirija --filename a una ruta del almacenamiento local real, como un volumen montado con 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 permite al menos confirmar 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-testfileSea preciso sobre lo que demuestra 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 prueba para confirmar que fio está instalado y que las opciones se interpretan correctamente. No la presente nunca como un resultado del disco.
Por qué dd no es una prueba de rendimiento de disco
dd aparece en muchos hilos sobre VPS y responde a una 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 único subproceso y una sola solicitud en curso. Es una comprobación de coherencia razonable. No dice nada sobre la E/S aleatoria ni sobre lo que ocurre cuando llegan 32 solicitudes a la vez. Si se omite oflag=direct, las escrituras pasan por la caché de páginas, pero conv=fdatasync sigue obligando a almacenar los datos de salida antes de que termine el comando. Si también se omite ese parámetro, el resultado puede medir principalmente la rapidez con la que el kernel acepta las escrituras en memoria. Por eso las cifras de dd citadas en publicaciones de foros suelen ser absurdas.
CPU: sysbench cpu
sysbench cpu --cpu-max-prime=20000 --threads=1 run
sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) runLa cifra que debe conservar es events per second. Ejecute primero la prueba con un solo hilo. Ese resultado determina la rapidez con la que finaliza una petición de PHP o se completa una tarea 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. Así verá cómo escala el rendimiento con todas las vCPU asignadas.
Debe tener claro qué mide esta prueba: sysbench cpu busca repetidamente números primos mediante división por prueba. Para cada candidato, calcula primero una raíz cuadrada de doble precisión y después prueba los divisores mediante módulo de enteros de 64 bits. Cada divisor se compara con ese límite de coma flotante. Por tanto, combina operaciones con enteros y con coma flotante. No somete el ancho de banda de memoria, las unidades vectoriales ni la caché a una carga que se parezca a una carga de trabajo real. 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. No se compare nunca con una cifra publicada 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. Mantenga --memory-block-size en 1M y utilice exactamente el mismo valor en todos los hosts que compare. En 1K el valor se desploma porque el coste por operación se aplica mil veces más a menudo. Por tanto, se mide el coste del bucle en lugar del ancho de banda de la memoria. Este es el indicador que más suele diferir entre las puntuaciones de memoria publicadas.
Red: iperf3
La forma correcta de probar el rendimiento es hacerlo contra un segundo equipo que controle, porque así sabe qué está haciendo cada extremo.
En el extremo remoto:
iperf3 -sEl servicio escucha en TCP 5201. Abra el puerto sólo para la dirección desde la que hará 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 8El primer comando mide la velocidad de subida desde el equipo probado. -R invierte la dirección y mide la velocidad de 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 sólo puede mantener tantos datos sin confirmar como permite 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, por rápida que sea la conexión subyacente. El resultado del flujo único indica qué velocidad obtendrá una descarga individual. El resultado paralelo indica la capacidad de la conexión.
Vigile el límite de ancho de banda mientras hace 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
Los datos de este gráfico
[
{
"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 4k en resultados publicados. Un SSD SATA local alcanza aproximadamente 90,000. El almacenamiento de bloques conectado por red, donde cada solicitud atraviesa la red antes de llegar al disco, se acerca más a 12,000, mientras que un disco mecánico ofrece 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 con un solo objetivo: 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 4k en la prueba de rendimiento, confirma primero que --direct=1 estaba activado. Si lo estaba, comprueba los límites de IOPS y los créditos de ráfaga del plan, además de la contención del almacenamiento y el hardware anunciado.
Por qué una sola 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. Conserve las ejecuciones en las que
stfue alto e investigue si reflejan contención o la cuota de CPU del plan; descartarlas puede ocultar el rendimiento que realmente recibe. - Ejecute la prueba de disco con dos duraciones. Muchos planes proporcionan una asignación de IOPS de ráfaga que se repone con el tiempo, pero ni una ejecución de fio de 60 segundos ni
--runtime=600garantizan que haya medido el rendimiento mínimo. Los créditos de AWS gp2 pueden mantener 3,000 IOPS durante al menos 30 minutos con el saldo completo, por lo que ambas ejecuciones pueden medir el rendimiento de ráfaga. Compruebe el modelo de créditos del proveedor y supervise el saldo de créditos antes de considerar que un resultado representa un rendimiento sostenido. - Compruebe que no se esté ejecutando ninguna otra tarea.
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 sólo tarda un segundo. - Cambie una sola variable cada vez. Las distintas versiones de las herramientas, los tamaños de bloque o los números de subprocesos producen cifras que no se pueden comparar, por 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.
Compare primero tu propia carga de trabajo
Las herramientas sintéticas clasifican las máquinas. Sólo tu propia carga de trabajo indica si una máquina es suficiente. Mide el tiempo de la tarea que realmente realizas.
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 a la vez y cambia cuando cambia cualquiera de los dos. La advertencia de Removing leading / from member names es normal. Mejor aún, mide el tiempo de tu propia compilación, de tu consulta más lenta o de tu propia renderización de páginas. Una compilación que tarda 4 minutos en un host y 7 en otro resuelve la cuestión, independientemente de lo que haya indicado 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 CPU física, almacenamiento y red con otros clientes, por lo que el resultado depende de lo que hagan en ese momento. Ejecute vmstat 1 durante la prueba y lea la columna st: un steal time sostenido registra tiempo de CPU no disponible, pero puede reflejar tanto que el proveedor está aplicando la asignación de CPU contratada como la contención en el host. Un valor superior a 5% no demuestra la causa. La respuesta está en el método, no en el ajuste. Ejecute cada prueba cinco veces o más, en distintas horas, y comunique la mediana junto con la dispersión.
¿Por qué fio informa 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, un 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é de la ruta. Si entonces --direct=1 falla, ejecute df -hT . y compruebe sobre qué está ubicado el archivo de prueba. Un tipo overlay no es el problema por sí mismo, porque overlayfs transmite O_DIRECT al almacenamiento subyacente. Mueva el archivo de prueba a almacenamiento local real sólo si el sistema de archivos subyacente rechaza las operaciones de E/S directas.
¿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 se quiere saber por qué un número tiene ese valor, porque no permite cambiar 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 número predice cómo percibiré el rendimiento de 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 suelen parecer impresionantes, pero rara vez determinan algo, porque una petición típica es pequeña. Informe del percentil 99 del bloque clat percentiles de fio en lugar de la media, ya que la petición lenta de cada cien es la que percibe 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 se ejecuta en Bash y necesita curl o wget para las descargas, además de tar para extraer Geekbench; sin tar, omite Geekbench. Usa fio e iperf3 cuando están instalados y descarga binarios estáticos cuando faltan. Elimine todos los archivos de prueba al terminar, porque un archivo de fio de 2G dejado en un disco de 20G puede convertirse en una alerta de disco lleno semanas después.