ZFS zpool iostat -v: Encontrar el disco que arruina la latencia

¿Te fue útil?

Tus usuarios no se quejan de que el rendimiento en throughput sea bajo. Se quejan de que a veces todo se bloquea:
los inicios de sesión se congelan, las consultas caducan, las copias de seguridad “se quedan fijas” y el panel se llena de p99 que parece un monitor cardíaco.
En el mundo ZFS, eso a menudo no significa “la pool es lenta”. Significa “un disco tiene un mal día y todos están invitados”.

zpool iostat -v es cómo atrapas ese disco in fraganti. No después de los hechos. No “quizá SMART dijo algo la semana pasada.”
Ahora mismo—mientras la latencia es fea—puedes aislar al culpable, probarlo con números y decidir si ponerlo offline, reemplazarlo,
o dejar de culpar a ZFS por lo que en realidad es un problema de hardware disfrazado de software.

Modelo mental: ZFS performance es por vdev, no por pool

Empieza aquí, porque cambia la forma en que lees cada gráfica y cada informe de incidente.
Una pool ZFS es una colección de vdevs. Los datos se stripean entre vdevs, pero cada bloque vive en un vdev específico.
Si un vdev se vuelve lento, cualquier carga de trabajo que toque bloques en ese vdev sufre.
Si el vdev es un mirror y un lado está lento, ZFS a veces puede enrutar lecturas alrededor de él—hasta que ya no puede (o hasta que está escribiendo,
o resilverizando, o tu carga es muy dependiente de operaciones síncronas).

También hay una verdad más molesta: ZFS es muy bueno convirtiendo pequeñas miserias intermitentes de un dispositivo en latencia cola para todo el sistema.
Lo hace porque ZFS es consistente: espera por el almacenamiento que solicitó. A tu app no le importa que el 99.9% de las I/O estén bien;
recuerda ese 0.1% que tardó 2 segundos porque un disco decidió hacer mantenimiento interno en el peor momento posible.

Así que el objetivo de zpool iostat -v no es “medir la pool”. Es “encontrar el vdev o disco con una historia distinta al resto.”
No buscas promedios bajos. Buscas outliers, picos, crecimiento de colas y asimetría.

Hechos rápidos e historia que realmente te ayudan a depurar

  • ZFS se construyó alrededor de checksums de extremo a extremo. Eso es excelente para la integridad, pero también significa que ZFS señalará ruidosamente los dispositivos defectuosos intentando reaplicar, sanar y registrar errores en lugar de devolver datos corruptos en silencio.
  • RAIDZ no es “RAID por hardware pero en software”. La matemática de paridad y el comportamiento de asignación de RAIDZ hacen que las escrituras aleatorias pequeñas sean más complejas que en mirrors, lo cual importa cuando un solo disco se ralentiza.
  • “Un disco más lento arruina el vdev” es más antiguo que ZFS. Los arreglos RAID clásicos siempre han quedado limitados por su miembro más lento; ZFS solo te da mejor instrumentación para probarlo.
  • La realidad de sectores 4K lo cambió todo. ZFS ashift existe porque los discos mintieron (o medio-mintieron) sobre tamaños de sector durante años; la desalineación puede amplificar I/O y latencia.
  • Scrub es una característica, no un castigo. ZFS scrubs lee todo intencionadamente; el punto es encontrar errores latentes antes de que un resilver te enseñe la lección por las malas.
  • ZFS puede elegir lados distintos de un mirror para lecturas. Eso puede ocultar un disco lento en lecturas mientras las escrituras siguen sufriendo, llevando a incidentes confusos de “lecturas bien, escrituras horribles”.
  • SLOG no es una caché de escritura. Un dispositivo de log separado acelera las escrituras síncronas solo; no arreglará latencia de escrituras asíncronas ni miembros lentos de la pool.
  • iostat de OpenZFS creció en utilidad con el tiempo. Las implementaciones antiguas eran más limitadas; OpenZFS moderno expone más comportamiento por-vdev, y en algunas plataformas puedes conseguir histogramas de latencia con otras herramientas.
  • Los SSD pueden estar “saludables” y aun así bloquearse. El GC de firmware y el throttling térmico pueden crear picos de latencia sin fallos obvios en SMART—hasta que correlaciones iostat + temperaturas lo revelan.

Qué muestra realmente zpool iostat -v (y lo que oculta)

El comando que realmente usarás

La herramienta de trabajo es:
zpool iostat -v con un intervalo y opcionalmente un conteo.
Sin intervalo obtienes promedios desde el arranque/import—útil para planificación de capacidad, terrible para incidentes.
Con un intervalo obtienes deltas por intervalo. Ahí es donde vive la verdad.

Variantes comunes:

  • zpool iostat -v 1 para vigilancia en tiempo real
  • zpool iostat -v 5 12 para una instantánea de 1 minuto
  • zpool iostat -v -y 1 para suprimir la primera línea “desde el arranque”, que de otro modo distrae en las salas de guerra
  • zpool iostat -v -p para bytes exactos (sin humanización), lo que importa cuando miras deltas pequeños

Qué significan las columnas (y qué debes inferir)

Dependiendo de tu plataforma/versión de OpenZFS, verás columnas como capacity, operations, bandwidth.
La salida típica muestra operaciones de lectura/escritura y ancho de banda de lectura/escritura a nivel de pool, vdev y dispositivo leaf.
Eso es suficiente para detectar muchos verdugos de latencia porque la latencia suele manifestarse como reducción de ops además de distribución desigual y un dispositivo haciendo menos trabajo (o curiosamente más).

Lo que a menudo no verás directamente es la latencia en milisegundos. Algunas plataformas la exponen vía modos extendidos de iostat u otras herramientas,
pero incluso sin columnas explícitas de latencia aún puedes diagnosticar: cuando la carga es estable, un dispositivo lento aparece como una caída en sus ops/bandwidth comparado con sus pares,
más carga incrementada en otros, más bloqueos visibles por los usuarios.

La disciplina: no te quedes mirando los totales de la pool. Los totales pueden verse “bien” mientras un disco silenciosamente causa latencia cola al bloquearse de forma intermitente.
Siempre expande a vdev y a disco.

Broma #1: Si el almacenamiento fuera un deporte de equipo, el disco lento sería el que insiste en “solo una cosa más rápida” antes de cada pase.

Guion de diagnóstico rápido (primero/segundo/tercero)

Primero: confirma que es latencia de almacenamiento, no CPU, red o presión de memoria

Si el sistema está intercambiando, o tu NIC está perdiendo paquetes, o la CPU está ocupada con compresión, el almacenamiento igual recibirá la culpa.
Haz una comprobación de 60 segundos:

  • Promedio de carga vs uso de CPU
  • Actividad de swap
  • Errores de red
  • Tamaño del arc de ZFS y expulsiones

Pero no lo sobrepienses: si la latencia de tu app se correlaciona con un pico de la pool, sigue adelante.

Segundo: ejecuta zpool iostat -v con intervalo y observa asimetría

Ejecuta zpool iostat -v -y 1 durante el incidente. Buscas:

  • Un dispositivo leaf con muchas menos ops que sus hermanos (o intervalos periódicos de cero)
  • Un dispositivo con ancho de banda extraño comparado con el resto (amplificación de lectura, reintentos, tráfico de reconstrucción)
  • Un solo vdev arrastrando las ops de la pool (común con RAIDZ bajo I/O aleatorio)

Tercero: corrobora con telemetría de salud y errores

Una vez que tengas un disco sospechoso, valídalo:

  • zpool status -v para errores, resilver/scrub en curso
  • smartctl para errores de medio, errores CRC, temperatura y patrones de timeouts
  • iostat / nvme para utilización y latencia a nivel de dispositivo (dependiente de plataforma)

El punto de decisión suele ser uno de estos:

  • Poner offline/reemplazar un disco que está fallando
  • Arreglar un path/cable/controlador (errores CRC, reseteos de enlace)
  • Detener una “optimización” que genera I/O destructivo (recordsize incorrecto, uso indebido de sync, timing patológico de scrub)
  • Rebalancear o rediseñar el layout de vdev si lo superaste (ancho RAIDZ, mirrors, special vdev)

Tareas prácticas: comandos, significado de la salida, decisiones

Estos son los movimientos que puedes hacer en un sistema en vivo. Cada uno incluye qué miras y qué decisión impulsa.
Usa un intervalo. Usa -y. Y deja de copiar/pegar promedios de vida útil en canales de incidentes como si significaran algo.

Task 1: Obtener una vista limpia y en tiempo real por disco

cr0x@server:~$ zpool iostat -v -y 1
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
tank        7.12T  3.80T    980    420   120M  38.0M
  raidz2-0  7.12T  3.80T    980    420   120M  38.0M
    sda         -      -    170     70  21.0M  6.2M
    sdb         -      -    165     71  20.8M  6.4M
    sdc         -      -    168     69  20.9M  6.1M
    sdd         -      -     20    180   2.0M  19.3M
    sde         -      -    170     71  21.1M  6.3M
    sdf         -      -    167     70  20.7M  6.2M

Significado: Un disco (sdd) está realizando muchas menos lecturas y muchas más escrituras que sus pares; el patrón es asimétrico.
Eso podría ser un sesgo real de carga, pero en RAIDZ suele indicar reintentos, lecturas de reconstrucción o un dispositivo comportándose de forma extraña.

Decisión: Marca sdd como sospechoso y corrobora con zpool status y SMART. No reemplaces nada todavía, pero deja de discutir sobre “totales de pool.”

Task 2: Reducir ruido y centrarse en una sola pool

cr0x@server:~$ zpool iostat -v -y tank 2 10
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
tank        7.12T  3.80T    950    410   118M  37.6M
  raidz2-0  7.12T  3.80T    950    410   118M  37.6M
    sda         -      -    165     68  20.6M  6.0M
    sdb         -      -    163     67  20.7M  6.1M
    sdc         -      -    164     66  20.5M  5.9M
    sdd         -      -     10    175   1.1M  18.7M
    sde         -      -    166     67  20.8M  6.0M
    sdf         -      -    162     69  20.5M  6.1M

Significado: El desequilibrio persiste a través de intervalos. No es un pico aislado.

Decisión: Escala de “corazonada” a “investigación activa.” Alguien debería iniciar un volcamiento SMART y verificar errores ahora, no después de que termine el incidente.

Task 3: Revisar la salud de la pool y ver si ZFS ya te está diciendo la respuesta

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced.
  scan: scrub repaired 0B in 02:14:33 with 0 errors on Wed Dec 25 03:12:41 2025
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       3     0     0
            sde     ONLINE       0     0     0
            sdf     ONLINE       0     0     0

errors: No known data errors

Significado: sdd tiene errores de lectura. ZFS los corrigió (así que no tienes corrupción), pero pagó latencia por hacerlo.
“Applications are unaffected” significa integridad de datos, no experiencia de usuario.

Decisión: Trata sdd como fallando hasta que se demuestre lo contrario. Prepara el reemplazo y revisa también el cableado/controlador.

Task 4: Volcar SMART y buscar los mentirosos habituales

cr0x@server:~$ sudo smartctl -a /dev/sdd
SMART overall-health self-assessment test result: PASSED
ID# ATTRIBUTE_NAME          VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   100   100   010    Pre-fail  Always       -       12
187 Reported_Uncorrect      100   100   000    Old_age   Always       -       3
197 Current_Pending_Sector  100   100   000    Old_age   Always       -       1
199 UDMA_CRC_Error_Count    200   199   000    Old_age   Always       -       48
194 Temperature_Celsius     031   048   000    Old_age   Always       -       57

Significado: “PASSED” no es una garantía de rendimiento. Sectores reasignados y pendientes indican degradación del medio.
Los errores CRC apuntan a problemas de cableado/backplane/controlador. 57°C es “no estoy muerto, solo estoy lento y molesto.”

Decisión: Si CRC aumenta, vuelve a asentar/reemplaza cable/backplane/ranura. Si hay realloc/pending, planifica reemplazo de disco.
Si la temperatura es alta, arregla el flujo de aire; el calor provoca picos de latencia antes de causar fallos totales.

Task 5: Confirmar el mapeo del disco sospechoso (evitar reemplazar el disco equivocado)

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep sdd | head
lrwxrwxrwx 1 root root  9 Dec 25 09:10 ata-ST12000NM0007_ZL0ABC12 -> ../../sdd
lrwxrwxrwx 1 root root 10 Dec 25 09:10 wwn-0x5000c500a1b2c3d4 -> ../../sdd

Significado: Tienes identificadores estables (WWN/by-id) que sobreviven reinicios y renumeración de dispositivos.

Decisión: Usa by-id/WWN en procedimientos de reemplazo y en zpool replace cuando sea posible.
“Sacamos el disco equivocado” es un tipo de outage clásico.

Task 6: Ver si un scrub/resilver está compitiendo por I/O

cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Wed Dec 25 09:02:11 2025
        3.11T scanned at 1.25G/s, 1.44T issued at 595M/s, 7.12T total
        0B repaired, 20.18% done, 00:18:43 to go

Significado: Un scrub está leyendo la pool activamente. En pools con mucha carga, scrub puede aumentar la latencia saturando colas de disco.
Si un disco está débil, scrub lo hace evidente arrastrando su ritmo.

Decisión: Durante un incidente visible para clientes, considera pausar el scrub (zpool scrub -p) si la política lo permite.
Pero no “arregles” el incidente dejando de hacer scrubs permanentemente; así conviertes errores latentes en pérdida de datos más adelante.

Task 7: Determinar presión de escrituras síncronas (y dejar de culpar al SLOG incorrectamente)

cr0x@server:~$ zfs get -o name,property,value -H sync,logbias tank
tank	sync	standard
tank	logbias	latency

Significado: Las escrituras síncronas se honran normalmente; logbias favorece el dispositivo de log si está presente.
Si la latencia de tu app viene de fsyncs frecuentes, la calidad del SLOG importa. Si no es sincrónica, SLOG no te salvará.

Decisión: Si el incidente es por latencia de escritura y no tienes SLOG (o tienes uno lento), considera añadir un SLOG con seguridad ante pérdida de energía.
Si ya tienes uno, no asumas que funciona—mídelo.

Task 8: Observar comportamiento por-vdev en un mirror (atrapar el caso “un lado está enfermo”)

cr0x@server:~$ zpool iostat -v -y ssdpool 1
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
ssdpool      812G   989G   4200   1800   520M   210M
  mirror-0   812G   989G   4200   1800   520M   210M
    nvme0n1      -      -   4100    900   505M   110M
    nvme1n1      -      -    100    900    15M   110M

Significado: Las lecturas se sirven mayormente desde nvme0n1; las escrituras se espejan así que ambas las reciben.
Este patrón puede ocurrir porque ZFS prefiere el lado más rápido para lecturas. Si nvme1n1 está bloqueándose, puede que no lo notes hasta la latencia de escrituras o un resilver.

Decisión: Investiga igualmente el lado “silencioso”. Ejecuta SMART/NVMe logs y revisa throttling térmico o errores de medio.

Task 9: Revisar salud NVMe por throttling y resets

cr0x@server:~$ sudo nvme smart-log /dev/nvme1
temperature                         : 79 C
available_spare                     : 100%
percentage_used                     : 12%
media_errors                        : 0
num_err_log_entries                 : 27
warning_temp_time                   : 148
critical_comp_time                  : 0

Significado: 79°C más tiempo de advertencia térmica significativo: el dispositivo probablemente está haciendo throttling.
Entradas en el log de errores sugieren resets/timeouts incluso si media_errors es cero.

Decisión: Arregla la refrigeración y revisa firmware/comportamiento del controlador. El throttling es un asesino de latencia que parece “pausas aleatorias de ZFS.”

Task 10: Buscar problemas de controlador o enlace en logs del kernel

cr0x@server:~$ sudo dmesg | egrep -i "sdd|ata|reset|timeout|I/O error" | tail -n 8
[ 8123.441122] ata7: hard resetting link
[ 8123.771090] ata7: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 8124.112904] blk_update_request: I/O error, dev sdd, sector 223456789 op 0x0:(READ)
[ 8124.112970] sd 7:0:0:0: [sdd] tag#12 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 8124.113001] sd 7:0:0:0: [sdd] Sense Key : Medium Error [current]

Significado: Reseteos de enlace y errores de I/O. Eso no es “ZFS lento.” Es el dispositivo o el path.

Decisión: Reemplaza/repara el path (cable/backplane/puerto HBA) y probablemente el disco. Si los errores persisten tras arreglar el path, el disco es culpable.

Task 11: Confirmar ashift y evitar amplificación de escritura accidental

cr0x@server:~$ zdb -C tank | egrep "ashift|vdev_tree" -n | head -n 12
56:        vdev_tree:
78:            ashift: 12

Significado: ashift: 12 significa sectores 4K. Bueno para discos modernos.
Si ves 9 (512B) en medios 4K, puedes crear un comportamiento brutal de read-modify-write y latencia bajo escrituras aleatorias.

Decisión: Si ashift está mal, la solución real es reconstruir la pool correctamente. No finjas que un tunable te salvará.

Task 12: Determinar si un special vdev es el cuello de botella oculto

cr0x@server:~$ zpool status tank | sed -n '1,120p'
  pool: tank
 state: ONLINE
config:

        NAME           STATE     READ WRITE CKSUM
        tank           ONLINE       0     0     0
          raidz2-0     ONLINE       0     0     0
            sda        ONLINE       0     0     0
            sdb        ONLINE       0     0     0
            sdc        ONLINE       0     0     0
            sdd        ONLINE       3     0     0
            sde        ONLINE       0     0     0
            sdf        ONLINE       0     0     0
        special
          mirror-1     ONLINE       0     0     0
            nvme2n1    ONLINE       0     0     0
            nvme3n1    ONLINE       0     0     0

Significado: Hay un special vdev mirror. Si está subdimensionado o limitándose, cargas de trabajo ricas en metadata se ralentizan aunque el RAIDZ principal parezca bien.
Si el special vdev muere, la pool puede quedar comprometida según lo que esté asignado ahí.

Decisión: Monitorea el special vdev como si fuera crítico de producción (porque lo es). Si está caliente o con errores, arréglalo primero.

Task 13: Correlacionar comportamiento a nivel ZFS con utilización de bloque

cr0x@server:~$ iostat -x 1 5
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          11.20    0.00    6.10    9.40    0.00   73.30

Device            r/s     w/s   rkB/s   wkB/s  avgrq-sz avgqu-sz   await  svctm  %util
sda             168.0    70.0 21000.0  6200.0    224.2     1.10    5.20   1.40  33.2
sdb             166.0    69.0 20800.0  6100.0    223.9     1.08    5.10   1.35  32.9
sdc             167.0    68.0 20900.0  6000.0    224.1     1.12    5.30   1.38  33.5
sdd              10.0   175.0  1100.0 18700.0    225.0    18.40  115.00   5.90  99.8
sde             167.0    69.0 21100.0  6100.0    224.0     1.09    5.20   1.37  33.1
sdf             165.0    70.0 20700.0  6200.0    224.3     1.11    5.10    1.36  33.0

Significado: sdd tiene una cola enorme (avgqu-sz), alto await y 99.8% de utilización.
Los pares están funcionando al ~33% de util con awaits de ~5ms. Ese es tu villano de latencia.

Decisión: Tienes suficiente evidencia para actuar. Si la redundancia lo permite, pon offline y reemplaza sdd, o arregla su path.
No esperes a que “falle más.”

Task 14: Poner offline un disco de forma segura (cuando sabes lo que haces)

cr0x@server:~$ sudo zpool offline tank sdd

Significado: ZFS deja de usar ese dispositivo. En un vdev RAIDZ2 puedes sobrevivir hasta dos dispositivos faltantes; en un mirror puedes sobrevivir a uno.

Decisión: Haz esto solo si la redundancia lo permite y estás seguro de la identidad del dispositivo. Poner offline puede mejorar la latencia inmediatamente al sacar el dispositivo que se bloquea de la ruta I/O.

Task 15: Reemplazar usando by-id y observar la distribución de I/O durante el resilver

cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d4 /dev/disk/by-id/wwn-0x5000c500d4c3b2a1

Significado: Estás reemplazando el dispositivo WWN exacto por uno nuevo. Esto evita la ruleta de nombres de dispositivo.

Decisión: Después del reemplazo, usa zpool iostat -v durante el resilver para asegurar que el disco nuevo se comporte como sus pares y que la pool permanezca responsiva.

Cómo interpretar los patrones: firmas de latencia de fallas comunes

Firma 1: Un disco muestra menos ops y ocasionales intervalos “en blanco”

Verás un disco con ops de lectura/escritura cayendo a casi cero durante un intervalo, y luego “poniéndose al día.”
Esto es clásico de stalls de firmware, GC interno (SSD) o reseteos de enlace SATA.
El total de la pool puede no hundirse porque otros dispositivos siguen trabajando, pero tu p99 se verá terrible.

Qué hacer: Revisa dmesg por reseteos/timeouts y los logs SMART/NVMe. Verifica temperaturas. Si es recurrente, reemplaza.

Firma 2: Un disco está al 100% de util con colas enormes; los pares están relativamente inactivos

Eso es evidencia contundente. ZFS está emitiendo lo que puede, pero el dispositivo no da abasto.
En RAIDZ, un disco al 100% puede estrangular lecturas de reconstrucción y operaciones de paridad. En mirrors, el lado lento aún puede perjudicar escrituras.

Qué hacer: Confirma con iostat -x. Si es un problema de path (errores CRC), arregla el cableado. Si es medio, reemplaza el disco.

Firma 3: Las escrituras son lentas en todas partes, pero las lecturas están bien

A menudo son escrituras síncronas. O un slog que no es realmente rápido. O una propiedad del dataset que fuerza sync (o tu app llama a fsync constantemente).
Los mirrors ocultan problemas de lectura mejor que las escrituras; RAIDZ suele castigar las escrituras aleatorias.

Qué hacer: Confirma las propiedades del dataset (sync, logbias), revisa si hay un dispositivo SLOG y valida que sea de baja latencia y seguro ante pérdida de energía.
También revisa si estás sufriendo fragmentación + registros pequeños en RAIDZ.

Firma 4: Durante scrub/resilver, todo se vuelve una papa

Scrub/resilver es un deporte de contacto total. ZFS competirá con tu carga por tiempo de disco.
Si tienes un disco marginal, scrub lo convierte en el centro de atención.

Qué hacer: Programa scrub. Considera limitarlo mediante herramientas de planificación de I/O a nivel de sistema (específicas de plataforma) en lugar de deshabilitarlas.
Si el scrub revela errores en un disco específico, no discutas; reemplázalo.

Firma 5: El special vdev o dispositivo de metadata se bloquea y causa “todo lento pero los discos de datos están tranquilos”

La metadata es el cuello de botella para muchas cargas. Si el special vdev está sobrecargado o throttling, las operaciones de fichero y I/O pequeñas pueden arrastrarse.
Verás los dispositivos del special vdev más calientes/ocupados que el vdev principal.

Qué hacer: Monitóralo como un componente de nivel 0. Usa zpool iostat -v y la telemetría de dispositivos para confirmar que no sea throttling térmico.

Una cita para recordar (idea para una nota adhesiva): El mensaje de fiabilidad de John Allspaw: no “previenes” la falla; construyes sistemas que la detectan y se recuperan rápido.

Broma #2: SMART “PASSED” es como un informe corporativo—técnicamente cierto, emocionalmente inútil.

Tres micro-relatos corporativos desde las trincheras de latencia

Micro-relato #1: El incidente causado por una suposición equivocada

Una empresa SaaS mediana ejecutaba un tier NFS respaldado por ZFS para artefactos de CI e imágenes de contenedor. Durante meses fue estable.
Luego apareció lentitud “aleatoria”: builds se detenían, pulls fallaban y el on-call escuchaba repetidamente que “el almacenamiento está lento otra vez.”
El equipo asumió que era saturación de red porque las gráficas de throughput de la pool no se veían terribles.

Pasaron una mañana afinando hilos NFS y discutiendo el MTU. Reiniciaron un switch.
Nada cambió. Los picos de latencia seguían, mayormente en horas punta de commits.
Alguien finalmente ejecutó zpool iostat -v -y 1 durante una ventana de incidente y notó un disco en un vdev RAIDZ2
mostrando muchas menos lecturas que sus hermanos, con intervalos periódicos casi cero.

La suposición equivocada fue sutil: creyeron que “si el throughput está bien, el almacenamiento no es el problema.”
Pero su carga estaba llena de lecturas aleatorias pequeñas (búsquedas de metadata y muchos ficheros pequeños), donde la latencia cola importa más que MB/s agregados.
Un disco estaba reiniciando intermitentemente el enlace SATA. ZFS mantuvo la pool online y sanó, pero los reintentos se tradujeron en bloqueos visibles por los usuarios.

Reemplazaron el disco, y las gráficas no cambiaron mucho. Ese es el punto: el throughput nunca fue el síntoma real.
Los tickets de clientes se detuvieron en la hora porque el p99 dejó de tomar rutas escénicas a través de la recuperación de errores.
La lección que anotaron: no solucionas incidentes ZFS con totales de pool; lo haces con deltas por dispositivo y evidencia.

Micro-relato #2: La optimización que salió mal

Una empresa relacionada con finanzas tenía una pool ZFS sirviendo VMs vía iSCSI. La latencia era decente pero no excelente.
Un ingeniero propuso una “victoria fácil”: cambiar propiedades de dataset para buscar rendimiento—recordsize más pequeño “para bases de datos”, compresión más agresiva,
y un cambio general para tratar escrituras síncronas diferente porque “el UPS nos cubrirá”.

El benchmark inicial mejoró. Luego vino producción.
Las bases de datos empezaron a generar más operaciones I/O por transacción debido a mismatch de recordsize con el patrón de trabajo,
la compresión aumentó CPU en picos, y los cambios de sync crearon comportamiento patológico con los fsync de la aplicación.
Para empeorar las cosas, el equipo añadió un NVMe de consumo como SLOG porque era “rápido”, ignorando características de pérdida de energía y latencia sostenida.

zpool iostat -v contó una historia muy clara: el dispositivo SLOG estaba saturado con altas ops de escritura en horas punta,
y un miembro de un mirror empezó a mostrar distribución desigual cuando se sobrecalentó.
La latencia empeoró exactamente cuando esperaban que mejorara.

El rollback solucionó el incidente. El postmortem no fue de vergüenza; fue de disciplina.
Optimizar cambios que alteran la semántica de escritura no son “tweaks”. Son cambios de arquitectura.
Si no puedes explicar los nuevos modos de fallo—y medirlos en vivo—solo estás moviendo riesgo hasta que caiga sobre un cliente.

Micro-relato #3: La práctica aburrida pero correcta que salvó el día

Un proveedor de salud usaba ZFS para un almacén de documentos. Nadie amaba ese sistema; era “legacy”, lo que significaba crítico y poco financiado.
Pero el ingeniero de almacenamiento tenía un hábito: ventanas de scrub semanales y un runbook simple que incluía capturar zpool iostat -v durante el scrub.
Aburrido. Repetitivo. Efectivo.

Una semana, el tiempo de scrub aumentó notoriamente. No suficiente para alertar, pero suficiente para aparecer en las notas.
Durante el scrub, las estadísticas por disco mostraron un drive leyendo menos y stallando ocasionalmente.
SMART aún decía “PASSED”, porque claro que sí, pero había algunos CRC en aumento y una temperatura elevada.

El ingeniero abrió un ticket para reemplazar el cable y, si hacía falta, el disco en la próxima ventana de mantenimiento.
Reemplazar el cable redujo los CRC pero no eliminó los stalls. Reemplazaron el disco proactivamente, resilverizó limpio y siguieron.

Dos meses después, otro equipo con un chasis similar sufrió un fallo similar y tuvo un incidente desordenado porque no tenían historial de tendencias ni hábito de mirar comportamiento por disco.
La práctica aburrida no solo previno downtime; previno ambigüedad.
Cuando puedes decir “este disco se degrada en semanas”, puedes hacer mantenimiento en lugar de heroísmos.

Errores comunes: síntoma → causa raíz → arreglo

1) Síntoma: El throughput de la pool parece bien, pero la latencia p99 es terrible

Causa raíz: Un disco se bloquea intermitentemente; ZFS reintenta/sana; los promedios ocultan la latencia cola.
O el special vdev está stallando operaciones de metadata.

Arreglo: Usa zpool iostat -v -y 1 durante el evento; encuentra asimetría.
Correlaciona con iostat -x, dmesg y logs SMART/NVMe. Reemplaza disco/path; aborda el sobrecalentamiento.

2) Síntoma: Las escrituras son lentas en un mirror aunque las lecturas sean rápidas

Causa raíz: ZFS puede elegir el lado más rápido para lecturas, ocultando un disco enfermo; las escrituras deben alcanzarlos a ambos.
O escrituras síncronas saturan un SLOG débil.

Arreglo: Busca desequilibrio por leaf en el mirror con zpool iostat -v.
Valida el comportamiento del SLOG. Arregla/reemplaza el miembro lento del mirror o el dispositivo SLOG.

3) Síntoma: Los scrubs hacen la pool inutilizable

Causa raíz: Scrub compite por I/O; la pool está cerca de capacidad o fragmentada; un disco marginal se convierte en cuello de botella.

Arreglo: Programa scrubs en ventanas de baja carga; considera pausarlos durante incidentes.
Investiga el disco lento con zpool iostat -v y SMART; reemplázalo si arrastra. Mantén espacio libre saludable.

4) Síntoma: La pool RAIDZ tiene peor latencia de escritura aleatoria de lo esperado

Causa raíz: Overhead de paridad de RAIDZ más bloques pequeños; recordsize incorrecto; ashift desalineado; carga síncrona sin diseño apropiado.

Arreglo: Confirma ashift. Alinea recordsize con la carga. Para I/O aleatorio pesado, prefiere mirrors o ajusta ancho de vdev y patrones de carga.
No “tunes” la paridad hasta desaparecerla.

5) Síntoma: El disco muestra muchos errores CRC pero sin reasignaciones

Causa raíz: Problemas de cableado/backplane/HBA causando corrupción a nivel de enlace y reintentos.

Arreglo: Reemplaza/reasienta cables, cambia puertos, revisa backplane. Observa si CRC sigue incrementando después de la reparación.

6) Síntoma: Reemplazar un disco no ayudó; la latencia sigue con picos

Causa raíz: El path/controlador es el problema real; o la carga está golpeando escrituras síncronas; o el special vdev está limitando.

Arreglo: Usa dmesg y telemetría del controlador. Valida sync/logbias y SLOG.
Inspecciona iostat del special vdev y termales NVMe.

7) Síntoma: “zpool iostat no muestra nada malo” pero la app sigue lenta

Causa raíz: Estás mirando promedios desde hace mucho (sin intervalo), o el incidente es intermitente y lo perdiste.
O el cuello de botella está por encima de ZFS (CPU, memoria, red) o por debajo (multipath, SAN, hypervisor).

Arreglo: Usa siempre modo intervalo. Captura durante el evento. Añade muestreo continuo ligero en tu monitorización para poder reproducir el momento.

Listas de verificación / plan paso a paso

Paso a paso: atrapar el disco lento en menos de 10 minutos

  1. Ejecuta estadísticas por intervalo.

    cr0x@server:~$ zpool iostat -v -y 1
    

    Decisión: Identifica cualquier dispositivo leaf con ops/bandwidth que no coincida con sus hermanos.

  2. Confirma salud de la pool y actividad en segundo plano.

    cr0x@server:~$ zpool status -v
    

    Decisión: Si scrub/resilver está activo, decide si pausarlo para mitigar el incidente.

  3. Correlaciona con cola y await a nivel de dispositivo.

    cr0x@server:~$ iostat -x 1 3
    

    Decisión: Alta await y cola en un disco = acción. No esperes.

  4. Revisa logs por reseteos/timeouts.

    cr0x@server:~$ sudo dmesg | egrep -i "reset|timeout|I/O error|blk_update_request" | tail -n 30
    

    Decisión: Si existen reseteos de enlace, sospecha cableado/HBA/backplane aun cuando SMART esté silencioso.

  5. Extrae logs SMART/NVMe del dispositivo sospechoso.

    cr0x@server:~$ sudo smartctl -a /dev/sdX
    

    Decisión: Pending/reallocated/CRC/temp deciden reemplazo vs arreglo de path.

  6. Si la redundancia lo permite, pon offline al culpable para restaurar latencia.

    cr0x@server:~$ sudo zpool offline tank sdX
    

    Decisión: Usa como mitigación de emergencia, no como estilo de vida permanente.

  7. Reemplaza usando identificadores estables y monitoriza el resilver.

    cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/OLD /dev/disk/by-id/NEW
    

    Decisión: Si el iostat del disco nuevo difiere de los pares, detente y valida hardware/firmware.

Checklist: qué capturar para un postmortem útil

  • zpool iostat -v -y 1 muestras durante la ventana del incidente (incluso 60 segundos ayuda)
  • zpool status -v incluyendo conteos de errores y estado de scan
  • Logs SMART/NVMe del disco sospechoso (incluyendo temperatura y CRC)
  • iostat -x para confirmar cola/await/util
  • Logs del kernel alrededor del pico (reseteos, timeouts)
  • Qué cambió recientemente (firmware, cables movidos, cambios de carga, ajustes del dataset)

Checklist: decisiones que deberías tomar explícitamente (no por sensaciones)

  • ¿El problema está aislado a un disco, un vdev o es sistémico?
  • ¿Tenemos redundancia para poner offline ahora?
  • ¿Es un problema de path (CRC/reseteos) o del medio (pending/realloc/uncorrectables)?
  • ¿Un scrub/resilver está amplificando el problema y se puede pausar de forma segura?
  • ¿Necesitamos cambiar la arquitectura (mirrors vs RAIDZ, dimensionado de special vdev) en lugar de tunear?

Preguntas frecuentes

1) ¿Por qué un disco lento perjudica toda la pool?

Porque ZFS emite I/O a vdevs específicos. Si un bloque vive en el vdev lento (o requiere reconstrucción que lo involucre), la petición espera.
La latencia cola está dominada por el peor participante, no por el participante promedio.

2) ¿Muestra zpool iostat latencia?

Usualmente muestra ops y ancho de banda, no milisegundos. Pero la latencia aparece indirectamente como reducción de ops, distribución desigual y crecimiento de colas
confirmado con iostat -x o herramientas de latencia específicas de la plataforma.

3) ¿Por qué debo usar siempre un intervalo (como zpool iostat -v 1)?

Sin intervalo estás viendo promedios desde import/boot. Los incidentes viven en picos y deltas.
El modo intervalo te da la realidad por segundo (o por N segundos).

4) Veo un lado del mirror realizando casi todas las lecturas. ¿Es eso malo?

No automáticamente. ZFS puede preferir el lado más rápido. Es malo cuando el lado “ignorado” está ignorado porque está enfermo
(throttling térmico, timeouts, errores). Verifícalo con telemetría del dispositivo.

5) SMART dice PASSED. ¿Puede el disco aun ser el problema?

Sí. El estado general de SMART es grueso. Mira atributos específicos (sectores pendientes, reasignados, errores CRC, temperatura)
y logs de error. También revisa dmesg por reseteos/timeouts.

6) ¿Debería pausar el scrub durante un incidente?

Si el scrub compite con I/O crítico de producción y necesitas restaurar servicio, pausarlo puede ser razonable a corto plazo.
Pero reprograma y averigua por qué scrub perjudica tanto—a menudo revela un disco débil o un diseño sobresuscrito.

7) ¿Agregar un SLOG arregla la latencia?

Puede arreglar la latencia de escritura síncrona cuando la carga es realmente sync-heavy y el dispositivo SLOG es de baja latencia y seguro ante pérdida de energía.
No hace nada por escrituras asíncronas o lecturas, y un mal SLOG puede empeorar las cosas.

8) ¿Cómo sé si es un problema de cable/backplane en vez de un disco?

Un incremento en UDMA_CRC_Error_Count en dispositivos SATA es una fuerte pista, junto con reseteos de enlace en dmesg.
Errores de medio (pending/realloc/uncorrectable) apuntan más al disco mismo. A veces obtienes ambos; arregla el path primero y luego reevalúa.

9) ¿Por qué RAIDZ suele ser peor para latencia de escritura aleatoria que mirrors?

La paridad requiere lecturas/escrituras adicionales y coordinación entre discos; las escrituras pequeñas pueden convertirse en ciclos read-modify-write.
Los mirrors realizan escrituras más simples. Si necesitas IOPS y baja latencia cola, los mirrors suelen ser la elección directa.

10) ¿Cuál es la “prueba” más rápida que puedo mostrar a personas no especializadas en storage?

Una captura breve de zpool iostat -v -y 1 más iostat -x 1 donde un dispositivo tiene await y cola dramáticamente más altos
mientras los pares están normales. Es visual, repetible y no requiere creer en folklore de almacenamiento.

Conclusión: qué hacer ahora, hoy

Cuando la latencia de ZFS se desvía, no empieces por “tunear ZFS.” Empieza por probar si un disco o un vdev se están comportando mal.
zpool iostat -v con un intervalo es tu linterna; encuentra asimetría rápido.
Luego corrobora con zpool status, logs SMART/NVMe y mensajes del kernel.

Pasos prácticos siguientes:

  • Pon zpool iostat -v -y 1 en tu runbook de incidentes, no en tu memoria personal.
  • Durante la próxima ventana de scrub, captura comportamiento por disco y estabi­lízalo. Las líneas base aburridas hacen los incidentes excitantes más cortos.
  • Si encuentras un dispositivo sospechoso, decide rápido: arreglo de path, offline o reemplazo. La latencia cola rara vez se cura sola.
  • Si tu arquitectura está desajustada (DB sync-heavy en RAIDZ ancho, special vdev subdimensionado), admítelo y planifica rediseño en lugar de idolatrar tunables.

El disco que arruina la latencia rara vez es sutil. Lo sutil somos nosotros: seguimos mirando totales de pool esperando que los promedios digan la verdad.
No lo harán. Los deltas por dispositivo sí.

← Anterior
Maquetación Holy Grail moderna con CSS: encabezado, pie de página y barra lateral sin hacks
Siguiente →
Buzón catch‑all de correo: por qué arruina la entregabilidad (y alternativas más seguras)

Deja un comentario