Volver al blog
31 de agosto de 2026Sergei Solod10 min de lectura

Mi VPS de FDCServers funcionó bien con más de 3 TB de tráfico. Después, las lecturas de disco empezaron a tardar 18 segundos

Mi VPS de FDCServers manejó tráfico real con normalidad y transfirió más de 3 TB de datos antes de que aparecieran los problemas. Después, una carga normal empezó a provocar bloqueos graves del disco virtual: el CPU iowait llegó al 100%, la presión de I/O de Linux rozó el 100%, las lecturas alcanzaron 18,7 segundos y los flush superaron los 53 segundos.

FDCServersVPSLinuxE/S de discoDevOps

No escribo esto como una reseña negativa de FDCServers. Tampoco intento decirle a nadie si debería o no comprarles un VPS. Tuve un servidor, una carga de trabajo y una secuencia concreta de problemas. Eso no basta para juzgar a toda una empresa de hosting.

Es simplemente uno de mis días como desarrollador. El VPS llevaba un tiempo funcionando con normalidad y ya había transferido más de 3 TB de tráfico. Después, una carga habitual empezó a producir retrasos extremos. Las páginas podían tardar muchísimo en responder o terminar en timeout. Al principio sospeché de lo habitual: la aplicación, Nginx, la memoria, la red, los límites de conexiones o un exceso de carga. Las métricas de Linux apuntaban a otro sitio.

El VPS no fue lento desde el principio

Entre incidentes, la máquina podía parecer completamente sana. Durante un periodo normal no había procesos en D-state, el CPU iowait rondaba el 0%, la latencia del disco estaba aproximadamente entre 2 y 4 ms y el I/O PSI era casi cero:

D-state processes: 0
CPU iowait:        ~0%
disk latency:      ~2–4 ms
I/O PSI some:      0.04
I/O PSI full:      0.04

Si solo me hubiera conectado en ese momento y hubiera mirado top, free -h, df -h y systemctl status nginx, probablemente habría concluido que el VPS estaba bien. Después volvió la carga normal y el estado de la máquina cambió radicalmente.

Lecturas de 18,7 segundos cambiaron la investigación

Una de las muestras más claras de iostat fue esta:

r_await = 18744 ms
f_await = 53561 ms
aqu-sz  = 128.54
util    = 100.10%
read    = 88 KB/s

Lo importante es interpretar los números en conjunto. Las lecturas completadas tardaban de media unos 18,7 segundos. La latencia de flush era de unos 53,6 segundos. La cola media de I/O superaba 128 y, pese a ello, el throughput útil de lectura era de solo 88 KB/s. No era simplemente un disco ocupado moviendo muchos datos: el camino de almacenamiento pasaba una cantidad enorme de tiempo esperando a que terminaran las operaciones.

iowait y PSI mostraron presión de I/O en todo el sistema

En los peores periodos, vmstat mostraba entre 4 y 9 procesos bloqueados, un CPU iowait de aproximadamente 97–100% y 0% de CPU idle. iowait no significa que la aplicación esté consumiendo toda la CPU. Significa que el trabajo útil está esperando a que terminen operaciones de I/O pendientes.

Linux Pressure Stall Information hizo el cuadro todavía más claro:

I/O PSI some avg10 = 99.14
I/O PSI full avg10 = 95.55

En reproducciones posteriores, full se acercó al 98%. La utilización del disco me dice que un dispositivo está ocupado; PSI me dice hasta qué punto el workload está detenido por ese recurso. Una presión de I/O sostenida del 95–98% no es una pequeña pérdida de rendimiento.

D-state y los stacks del kernel apuntaron por debajo de la aplicación

Después revisé qué procesos estaban bloqueados. Al mismo tiempo aparecían jbd2, systemd-journald, workers de Nginx, procesos de caché de Nginx y otras actividades del sistema de archivos en D-state. Si solo se hubiera bloqueado mi aplicación, habría investigado la aplicación. Cuando Nginx, el journal del sistema y el journal de EXT4 se bloquean a la vez, el almacenamiento se convierte en la dependencia común más evidente.

Las rutas de journaling de EXT4 incluían:

wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transaction

Los workers de Nginx esperaban en lecturas normales de archivos:

folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64

En un momento dado, el kernel informó de que una tarea de Nginx llevaba bloqueada más de 122 segundos. Nginx todavía podía aparecer como active, pero eso no significaba que sus workers pudieran completar trabajo útil. running y saludable no son lo mismo.

Una respuesta del backend en 3 ms separó la aplicación del sistema de archivos

La comparación más limpia fue entre Nginx y el backend local. Las peticiones a través de Nginx devolvían HTTP=000 por timeouts de conexión o TLS. Una petición directa al backend terminaba en unos 3 ms:

connect = 0.000423 s
TTFB    = 0.003063 s
total   = 0.003139 s

El código HTTP exacto no era importante para esta prueba. El backend aceptaba la conexión, procesaba la petición y producía una respuesta casi de inmediato. Al mismo tiempo, los workers de Nginx estaban visibles esperando lecturas de EXT4. Eso separó la ejecución normal de la aplicación del camino dependiente del sistema de archivos que tenía delante.

El fallo era reproducible y también podía desaparecer

Antes de una reproducción, la máquina parecía normal:

HTTP:          200
D-state:       0
CPU iowait:    3%
r_await:       ~1.18 ms
I/O PSI full:  ~2.95%

Unos treinta segundos después:

D-state:       4
CPU iowait:    91%
CPU idle:      0%
I/O PSI some:  86.11%
I/O PSI full:  78.02%
r_await:       236.50 ms
HTTP:          000

Más tarde, el CPU iowait llegó al 96–100%, el I/O PSI full rozó el 98%, la cola HTTPS llegó a 512 y las comprobaciones HTTP seguían fallando. Era una evidencia mucho más útil que decir que el VPS parecía lento.

Al retirar la carga, la transición contraria podía producirse rápidamente:

D-state:      0
CPU iowait:   6%
r_await:      ~0.98 ms
queue depth:  ~0.07
HTTP:         200

Por eso los problemas intermitentes de almacenamiento son difíciles de analizar después. El proveedor puede revisar el servidor tras recuperarse y ver una latencia realmente normal. Eso no explica lo sucedido diez minutos antes. Los timestamps UTC exactos pasaron a ser esenciales.

Dos métricas que pueden engañar: await=0 y el espacio libre

En algunos intervalos problemáticos veía r_await = 0 mientras iowait era alto, había procesos en D-state, seguían existiendo peticiones en vuelo y casi no terminaban lecturas. Las estadísticas de latencia se basan en I/O completado. Si una operación permanece bloqueada y no termina durante la ventana de muestreo, no puede aportar una latencia completada a la media. Por eso un cero no siempre significa un disco instantáneo.

También consideré el espacio ocupado. Más adelante el sistema de archivos quedó más lleno de lo que normalmente permitiría, pero el mismo tipo de fallo ya había aparecido cuando el filesystem raíz estaba utilizado solo en torno al 24%. En ese momento había aproximadamente 1,2 GiB de RAM disponible, el uso de inodos rondaba el 5% y la interfaz de red no mostraba errores ni paquetes descartados. La ocupación del disco no podía explicar todo el incidente.

Lo que pude demostrar y lo que no

Desde el VPS podía observar la aplicación, Linux VFS, EXT4 y el dispositivo de bloques virtual. Después comienza la infraestructura del proveedor: virtualización, almacenamiento distribuido, red de almacenamiento, dispositivos físicos, scheduling y otras capas que no puedo inspeccionar desde el guest.

Por tanto, no puedo afirmar honestamente que estuviera averiado un SSD físico concreto ni señalar un nodo de almacenamiento, una ruta de red o un componente de virtualización específico como causa raíz.

Lo que sí puedo afirmar es más limitado y está bien respaldado: el camino de almacenamiento virtual presentado a mi guest Linux entraba repetidamente en estados en los que las operaciones normales de I/O del sistema de archivos tardaban segundos o no terminaban en un plazo razonable. La evidencia procedía de iostat, PSI, D-state, stacks de espera del kernel, esperas de EXT4/jbd2, esperas de Nginx en el sistema de archivos, profundidad de cola y tiempos de las peticiones. Eso bastaba para el diagnóstico de ingeniería que necesitaba, pero no para identificar una causa física.

Por qué los más de 3 TB anteriores no contradicen los stalls posteriores

Al principio esto me confundió. Si el almacenamiento tenía problemas, ¿cómo había podido el VPS transferir varios terabytes correctamente antes?

Porque el tráfico de red no es lo mismo que el I/O físico del disco. Un archivo puede leerse una vez desde el almacenamiento, quedarse en el page cache de Linux y servirse muchas veces después desde memoria. Tres terabytes transferidos por la red no significan tres terabytes de lecturas físicas únicas.

Las condiciones de infraestructura también cambian con el tiempo: estado de caché, carga de almacenamiento, colas, ubicación del host y otros workloads pueden variar. Que un VPS funcione bien ayer no garantiza exactamente el mismo comportamiento del almacenamiento hoy.

Finalmente dejé de esperar una causa raíz más profunda

Recopilé timestamps exactos, vmstat, iostat, PSI, capturas de procesos bloqueados, stacks del kernel, esperas del sistema de archivos, profundidades de cola y tiempos HTTP. Envié los diagnósticos a FDCServers y esperé una explicación más profunda a nivel de infraestructura.

Esperé bastante tiempo. Finalmente dejé de esperar. Desde mi lado ya sabía lo suficiente para tomar una decisión operativa: el problema era reproducible, grave, visible por debajo de la capa de aplicación y la causa física estaba fuera de lo que podía observar desde mi VPS.

Pedí un reembolso y FDCServers me devolvió el dinero

Envié a FDCServers un resumen de los problemas y los diagnósticos que había recopilado, pedí cancelar el servicio y solicité un reembolso. Me devolvieron el dinero.

Así que la historia no termina en una larga pelea económica. Esperé una explicación técnica definitiva, decidí que ya no quería seguir esperando, envié las pruebas que tenía y pedí mi dinero. FDCServers lo devolvió.

Qué cambié después

El resultado útil no fue decidir si una empresa de hosting es buena o mala. Fue cambiar cómo diagnostico servidores Linux lentos.

Sigo usando comandos básicos como top, free -h y df -h, pero ahora recurro mucho antes a estos:

date -u
uptime
cat /proc/pressure/io
cat /proc/pressure/memory
cat /proc/pressure/cpu
vmstat 1 10
iostat -x 1 10
ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'
ss -lntp
journalctl -k --since '30 min ago' --no-pager

También pruebo por separado las distintas rutas cuando es posible: petición pública, Nginx local, backend directo, sistema de archivos y métricas del dispositivo de bloques. La pregunta ya no es simplemente por qué está lento el servidor. Es: ¿en qué capa deja de completarse el trabajo útil?

Cuando puedo, capturo las pruebas antes de reiniciar. Un reboot puede recuperar el servicio, pero también puede borrar justo el D-state, PSI, las colas y la latencia que permiten diagnosticar un incidente intermitente.

Reflexión final

No compré un VPS de FDCServers porque quisiera material para un artículo sobre hosting. Quería un servidor con mucho ancho de banda. Durante un tiempo obtuve exactamente eso: manejó carga real y transfirió más de tres terabytes.

Después, una carga normal empezó a producir de forma reproducible iowait de hasta 100%, I/O PSI cercano al 100%, lecturas de hasta 18,7 segundos, flush de más de 53 segundos, colas grandes, Nginx bloqueado en lecturas del sistema de archivos y EXT4/jbd2 esperando I/O.

Nunca supe qué componente físico o del host lo causaba, y no necesito fingir que lo sé. Identifiqué la capa donde se manifestaba el fallo, reuní pruebas suficientes para distinguirlo de un problema de aplicación, dejé de esperar una explicación más profunda y pedí que me devolvieran el dinero. FDCServers lo hizo.

Esto no es un veredicto sobre todos los VPS de FDCServers. Es un recordatorio bien documentado de que un servicio puede aparecer como active, un proceso como running y, aun así, la máquina puede pasar casi todo su tiempo útil esperando al almacenamiento.