ZFS zpool iostat -w: Comprender patrones de carga en tiempo real

¿Te fue útil?

No necesitas un panel para saber que tu almacenamiento está descontento. Basta con un timeout de API enfadado, un hilo en Slack preguntando “¿por qué está atascado el despliegue?”
y un directivo que dice “pero ayer funcionaba”. ZFS te da un suero de la verdad: zpool iostat -w.

Bien usado, te dice si estás limitado por CPU, por IOPS, por latencia, por escrituras sincronas, o simplemente “limitado por optimismo”.
Mal usado, te convence de comprar hardware innecesario, tocar perillas que no entiendes y culpar “a la red” por costumbre.

Qué muestra realmente -w (y por qué te debería importar)

zpool iostat es el monitor del pulso. La opción -w añade lo que normalmente desearías tener durante un incidente: latencia.
No latencia teórica. No latencia de la hoja de datos del proveedor. Latencia observada tal como ZFS la ve en operaciones de pool y vdev.

Si gestionas sistemas de producción, deberías tratar zpool iostat -w como la herramienta “¿es el almacenamiento el cuello de botella ahora mismo?”.
Responde:

  • ¿Estamos haciendo cola? La latencia crece antes de que el throughput caiga.
  • ¿Dónde está el dolor? A nivel de pool vs un vdev lento vs una sola pata de mirror.
  • ¿Qué tipo de dolor? Lecturas, escrituras, escrituras sync, trabajo intensivo en metadatos, resilver, trim o “pequeño y aleatorio en todo”.

La latencia es la moneda que gastan las aplicaciones. El throughput es de lo que presumen los equipos de almacenamiento. Cuando llega la factura, las aplicaciones pagan en latencia.

Qué añade -w y qué no añade

Las columnas exactas varían según la implementación y la versión de ZFS (OpenZFS en Linux vs FreeBSD vs illumos). Pero en líneas generales:

  • Añade columnas de latencia (a menudo separadas para lectura y escritura).
  • Puede añadir tiempo de cola o “wait” dependiendo de la plataforma.
  • No separa mágicamente la latencia de intención de ZFS de la latencia del dispositivo a menos que lo solicites (más adelante hablaremos de ello).
  • No te dice por qué la latencia es alta; te indica dónde excavar a continuación.

Una verdad seca: zpool iostat puede hacer que tu sistema parezca sano aun cuando tu aplicación esté en llamas, porque el ARC está guardándote en silencio.
Luego los fallos de caché se disparan y el mismo pool colapsa bajo lecturas reales de disco. Necesitas vigilarlo continuamente, no solo cuando ya estás condenado.

Historia rápida y datos que hacen que la salida tenga sentido

Unos cuantos puntos de contexto convierten “columnas de números” en una historia sobre la que puedes actuar. Aquí hay nueve hechos breves que realmente importan.

  1. ZFS nació en Sun Microsystems (mediados de los 2000) como una pila de almacenamiento de extremo a extremo: sistema de archivos + gestor de volúmenes, con checksums por todas partes.
  2. La idea de “pool” es la innovación central: los sistemas de archivos viven sobre un pool, y el pool decide dónde van los bloques entre vdevs.
  3. Copy-on-write (CoW) es por qué la fragmentación se siente distinta: ZFS no sobrescribe bloques in situ; escribe bloques nuevos y actualiza punteros.
  4. El ZIL no es una caché de escritura: es un registro para escrituras síncronas. Existe incluso sin un dispositivo SLOG dedicado.
  5. SLOG es un dispositivo, ZIL es un concepto: añadir un SLOG mueve el ZIL a un medio más rápido, pero solo para escrituras sync.
  6. OpenZFS unificó múltiples ramas por lo que funciones como eliminación de dispositivos, vdevs especiales y L2ARC persistente se volvieron más comunes entre plataformas.
  7. Ashift es para siempre (en su mayoría): configurarlo mal al crear el pool implica pagar esa penalidad de rendimiento mientras viva el vdev.
  8. “IOPS” es una media verdad sin latencia: puedes empujar IOPS altos con una latencia cola terrible; tu base de datos te seguirá odiando.
  9. Resilver y scrub son dolores intencionales: son lecturas/escrituras en segundo plano que pueden dominar zpool iostat si se lo permites.

Exactamente una cita, porque los ingenieros merecen mejor que posters motivacionales:
La esperanza no es una estrategia. — idea parafraseada comúnmente atribuida a círculos de liderazgo de operaciones.

Un modelo mental de producción: desde la petición de la app hasta el vdev

Cuando una aplicación realiza E/S en ZFS, observas múltiples capas negociando la realidad:

  • La app emite lecturas/escrituras (a menudo pequeñas, a menudo aleatorias y ocasionalmente insultantes).
  • El SO y ZFS agregan, cachean (ARC) y a veces reordenan.
  • ZFS traduce bloques lógicos en escrituras físicas a través de vdevs, obedeciendo reglas de redundancia y asignación.
  • Tus vdevs traducen eso en comandos reales al dispositivo. El componente más lento relevante marca el ritmo.

Pool vs vdev: por qué tus “discos rápidos” pueden seguir siendo lentos

El rendimiento de ZFS se centra en el vdev. Un pool es un conjunto de vdevs. El throughput de tu pool escala con el número de vdevs, no con el número de discos,
en la forma que la gente asume ingenuamente.

Los mirrors te dan más IOPS por vdev que RAIDZ, y múltiples mirrors escalan. Los vdevs RAIDZ son geniales en eficiencia de capacidad y lecturas secuenciales grandes,
pero no se convierten mágicamente en monstruos de IOPS. Si construiste un gran vdev RAIDZ2 con un montón de discos y esperabas I/O aleatorio tipo base de datos,
compraste una furgoneta y la inscribiste en una carrera de drag.

La latencia es una pila: tiempo de servicio + tiempo de espera

La forma más útil de interpretar -w es: “¿el dispositivo es lento?” vs “¿el dispositivo está ocupado?”.
Latencia alta con utilización moderada suele significar que el propio dispositivo es lento (o está fallando, o realizando recolección interna).
Latencia alta con IOPS/throughput altos suele significar cola: la carga excede lo que el vdev puede servir con latencia aceptable.

Cómo leer las columnas sin engañarte

Verás variantes como:

  • capacity: usado, libre, fragmentación y a veces espacio asignado por pool/vdev.
  • operations: operaciones de lectura/escritura por segundo (IOPS).
  • bandwidth: bytes por segundo de lectura/escritura (throughput).
  • latency: latencia de lectura/escritura, a veces desglosada en “wait” y “service”.

La regla: diagnostica con una combinación de IOPS, bandwidth y latency. Cualquiera por sí sola miente.

Las líneas a nivel de pool son promedios; las de vdev son la verdad

Las estadísticas a nivel de pool pueden ocultar un único disco enfermo en un mirror o un único vdev RAIDZ lento arrastrando todo.
Siempre usa -v para ver el desglose por vdev al diagnosticar.

Mira el cambio, no el número

zpool iostat se usa mejor como serie temporal. Ejecútalo con un intervalo de 1 o 2 segundos y observa tendencias.
El “ahora” importa más que los promedios de por vida.

Broma #1: Los gráficos de almacenamiento son como los horóscopos: vagos hasta que suena el pager, y entonces de repente son “obviamente predictivos”.

Guion de diagnóstico rápido

Esta es la secuencia que uso cuando un equipo de apps dice “el almacenamiento está lento” y tienes 90 segundos para decidir si eso es cierto.

Primero: determina si estás viendo disco o caché

  1. Ejecuta zpool iostat -w con intervalos de 1s durante 10–20 segundos.
  2. Si IOPS de lectura y bandwidth son bajos pero la app va lenta, sospecha CPU, bloqueos, red o fallos de caché que aún no llegan al disco.
  3. Si IOPS de lectura se disparan y la latencia sube con ellas, estás en los discos. Ahora es real.

Segundo: aisla la capa que es el cuello de botella

  1. Usa zpool iostat -w -v. Encuentra el vdev con peor latencia o los síntomas de mayor utilización.
  2. Si es un disco en un mirror: probablemente esté fallando, tenga un firmware raro o un problema de pathing.
  3. Si es todo un vdev RAIDZ: estás saturando los IOPS de ese vdev. La solución es arquitectónica (más vdevs, mirrors, o aceptar latencia).

Tercero: decide si es dolor por escrituras sync

  1. Busca picos de latencia de escritura que se correlacionen con IOPS de escritura pequeñas y bajo bandwidth.
  2. Comprueba si la carga fuerza escrituras sync (bases de datos, NFS, hipervisores).
  3. Si es así: examina la salud del SLOG y la latencia del dispositivo; considera si tus ajustes de sync son apropiados para tu tolerancia al riesgo.

Cuarto: busca “trabajos en segundo plano que se hacen pasar por tráfico”

  1. Scrubs, resilvers, trims y snapshots/clones pesados pueden dominar la E/S.
  2. Si zpool status muestra trabajo activo, decide si limitar, programar o dejar que termine.

Quinto: confirma con una segunda señal

  1. Correlaciona con CPU (mpstat), presión de memoria, o E/S por proceso (pidstat).
  2. Usa herramientas a nivel de dispositivo (iostat -x) para ver si un NVMe está fallando mientras ZFS promedia todo.

Tareas prácticas: comandos, significado, decisiones

Pediste tareas reales, no sensaciones. Aquí tienes catorce. Cada una incluye un comando, un fragmento de salida de ejemplo, qué significa y la decisión que impulsa.
Las salidas son representativas; tus columnas pueden diferir según plataforma/versión.

Tarea 1: Línea base de latencia del pool en tiempo real

cr0x@server:~$ sudo zpool iostat -w tank 1
              capacity     operations     bandwidth    latency
pool        alloc   free   read  write   read  write   read  write
----------  -----  -----  -----  -----  -----  -----  -----  -----
tank        3.21T  7.58T    210    180  18.2M  22.4M   2ms   4ms
tank        3.21T  7.58T    195    260  16.9M  31.1M   3ms  18ms
tank        3.21T  7.58T    220    240  19.1M  29.7M   2ms  20ms

Significado: Las escrituras subieron en latencia de 4ms a ~20ms mientras el bandwidth aumentaba. Eso es un clásico “estamos empujando la ruta de escritura”.

Decisión: Si esto se alinea con la latencia que ven los usuarios, trata el almacenamiento como sospechoso. Siguiente paso: añade -v para encontrar qué vdev lo causa.

Tarea 2: Encuentra el vdev que te está perjudicando

cr0x@server:~$ sudo zpool iostat -w -v tank 1
                                            operations     bandwidth    latency
pool        vdev                             read  write   read  write   read  write
----------  -------------------------------- ----  -----  -----  -----  -----  -----
tank        -                                  220    240  19.1M  29.7M   2ms  20ms
tank        mirror-0                           110    120   9.5M  14.6M   2ms  10ms
tank          nvme0n1                          108    118   9.4M  14.4M   2ms  12ms
tank          nvme1n1                          112    119   9.6M  14.7M   2ms  65ms
tank        mirror-1                           110    120   9.6M  15.1M   2ms  10ms
tank          nvme2n1                          110    118   9.5M  14.8M   2ms  11ms
tank          nvme3n1                          110    121   9.7M  15.3M   2ms  10ms

Significado: Una pata del mirror (nvme1n1) tiene 65ms de latencia de escritura mientras su pareja está bien. ZFS puede leer desde mirrors, pero las escrituras esperan a ambas patas.

Decisión: Esto es un problema de dispositivo/path. Revisa SMART, firmware, errores de PCIe, multipath y velocidad de enlace. Reemplaza o arregla el path antes de tunear ZFS.

Tarea 3: Separar “ocupado” de “roto” a nivel de dispositivo

cr0x@server:~$ iostat -x 1 3
Linux 6.5.0 (server)  12/25/2025  _x86_64_  (32 CPU)

Device            r/s     w/s   rMB/s   wMB/s  avgrq-sz  avgqu-sz   await  r_await  w_await  svctm  %util
nvme0n1         110.0   120.0     9.5    14.4     197.0      0.4     3.1      2.0      4.2    0.4   18.0
nvme1n1         112.0   119.0     9.6    14.7     198.2      9.8    66.7      2.2     65.8    0.5   95.0

Significado: nvme1n1 está con alta utilización, cola profunda y enorme await de escritura. Eso no es ZFS “hablando mucho”; es un dispositivo enfermo o estrangulado.

Decisión: Deja de culpar al recordsize. Investiga salud del dispositivo y throttling (térmico, GC de firmware). Si comparte lane PCIe, corrige la topología.

Tarea 4: Detectar rápidamente una carga de escrituras sync

cr0x@server:~$ sudo zpool iostat -w tank 1
              operations     bandwidth    latency
pool        read  write   read  write   read  write
----------  ----  -----  -----  -----  -----  -----
tank          80   3200   6.1M  11.8M   1ms  35ms
tank          75   3500   5.9M  12.4M   1ms  42ms

Significado: Muy altas IOPS de escritura pero bajo bandwidth de escritura indica escrituras pequeñas. La latencia es alta. Si la app es una base de datos, host de VMs o servidor NFS, asume presión sync.

Decisión: Revisa SLOG y ajustes de sync. Si no tienes SLOG y necesitas sync seguro, acepta que discos giratorios sufrirán.

Tarea 5: Verificar si datasets fuerzan comportamiento sync

cr0x@server:~$ sudo zfs get -o name,property,value -s local,received sync tank
NAME   PROPERTY  VALUE
tank   sync      standard

Significado: Pool/datasets usan semántica por defecto: respetar solicitudes sync de las apps.

Decisión: Si la latencia te mata y puedes aceptar riesgo para un dataset específico (no para todo el pool), considera sync=disabled solo para ese dataset.
Si no puedes explicar el riesgo a un auditor sin sudar, no lo hagas.

Tarea 6: Comprobar si tienes SLOG y si está sano

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: ONLINE
config:

        NAME          STATE     READ WRITE CKSUM
        tank          ONLINE       0     0     0
          mirror-0    ONLINE       0     0     0
            nvme0n1   ONLINE       0     0     0
            nvme1n1   ONLINE       0     0     0
          mirror-1    ONLINE       0     0     0
            nvme2n1   ONLINE       0     0     0
            nvme3n1   ONLINE       0     0     0
        logs
          mirror-2    ONLINE       0     0     0
            nvme4n1   ONLINE       0     0     0
            nvme5n1   ONLINE       0     0     0

Significado: Existe un SLOG en espejo. Bien: un SLOG de un único dispositivo es una trampa si te importa la durabilidad.

Decisión: Si las escrituras sync son lentas, mide la latencia del dispositivo SLOG por separado y considera reemplazar por NVMe con protección contra pérdida de energía.

Tarea 7: Medir comportamiento por vdev durante un scrub o resilver

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Thu Dec 25 10:11:03 2025
        1.23T scanned at 1.1G/s, 512G issued at 450M/s, 3.21T total
        0B repaired, 15.9% done, 01:42:18 to go
cr0x@server:~$ sudo zpool iostat -w -v tank 1
                                            operations     bandwidth    latency
pool        vdev                             read  write   read  write   read  write
----------  -------------------------------- ----  -----  -----  -----  -----  -----
tank        -                                 6200    180  1.05G  22.4M  12ms   4ms
tank        mirror-0                          3100     90  525M  11.2M  13ms   4ms
tank        mirror-1                          3100     90  525M  11.2M  12ms   4ms

Significado: Las lecturas están dominadas por scrub. La latencia está elevada pero es explicable. Las escrituras parecen normales.

Decisión: Si esto ocurre en una ventana de producción ocupada, limita el scrub (depende de la plataforma) o reprograma. Si la latencia de lectura está rompiendo SLOs, la programación del scrub es ahora un problema de SRE, no solo de almacenamiento.

Tarea 8: Identificar un único disco lento en un mirror sin adivinar

cr0x@server:~$ sudo zpool iostat -w -v tank 1
                                            operations     bandwidth    latency
pool        vdev                             read  write   read  write   read  write
----------  -------------------------------- ----  -----  -----  -----  -----  -----
tank        mirror-0                           800    900  65M   72M     3ms  14ms
tank          sda                              400    450  32M   36M     2ms   6ms
tank          sdb                              400    450  33M   36M     3ms  80ms

Significado: sdb es el ancla que arrastra el barco. Los mirrors escriben en ambos lados; una pata lenta envenena la latencia de escritura.

Decisión: Obtén datos SMART, revisa cableado/HBA y planifica el reemplazo. No intentes “tunear” alrededor de un disco que está muriendo.

Tarea 9: Confirmar ashift y por qué importa

cr0x@server:~$ sudo zdb -C tank | grep -E "ashift|vdev_tree" -n
45:        ashift: 12

Significado: ashift=12 (sectores de 4K). Esto es generalmente sensato para discos modernos y SSDs. Si ves ashift=9 en medios nativos 4K, estás pagando una penalidad de amplificación de escritura para siempre.

Decisión: Si ashift está mal, no “lo arreglas con un sysctl.” Migra a un nuevo vdev/pool con ashift correcto.

Tarea 10: Detectar dolor por metadatos y considerar un vdev especial

cr0x@server:~$ sudo zpool iostat -w -v tank 1
                                            operations     bandwidth    latency
pool        vdev                             read  write   read  write   read  write
----------  -------------------------------- ----  -----  -----  -----  -----  -----
tank        -                                 5200   2100  48M   39M    18ms  22ms
tank        raidz2-0                           5200   2100  48M   39M    18ms  22ms

Significado: Gran cantidad de IOPS con poco bandwidth es la firma de metadatos o I/O aleatorio pequeño (recorridos de directorios, archivos pequeños, maildirs, capas de contenedores).
RAIDZ no está contento.

Decisión: Considera añadir mirrors, añadir más vdevs o usar un vdev especial para metadatos/bloques pequeños si tu plataforma lo soporta y puedes operarlo con seguridad.

Tarea 11: Verificar recordsize del dataset vs carga (y evitar dolor autoinfligido)

cr0x@server:~$ sudo zfs get -o name,property,value recordsize tank/db
NAME     PROPERTY    VALUE
tank/db  recordsize  128K

Significado: recordsize de 128K está bien para I/O secuencial grande, pero muchas bases de datos prefieren más pequeño (como 16K) según el motor y tamaño de página.

Decisión: Si tu carga es lecturas/escrituras aleatorias pequeñas y ves amplificación de lectura, prueba un recordsize menor para ese dataset.
No cambies recordsize a ciegas en un dataset existente y esperes milagros instantáneos; los bloques existentes permanecen como están.

Tarea 12: Comprobar compresión y saber si estás limitado por CPU

cr0x@server:~$ sudo zfs get -o name,property,value compression,compressratio tank/vm
NAME      PROPERTY       VALUE
tank/vm   compression    zstd
tank/vm   compressratio  1.62x
cr0x@server:~$ mpstat 1 3
Linux 6.5.0 (server)  12/25/2025  _x86_64_  (32 CPU)

12:11:01 AM  all   %usr  %nice   %sys %iowait  %irq  %soft  %steal  %idle
12:11:02 AM  all   72.0    0.0   11.0     2.0   0.0    0.0     0.0   15.0

Significado: La compresión está activa y es efectiva. La CPU está bastante ocupada. Si zpool iostat muestra baja actividad de disco pero la latencia a nivel de aplicación es alta, la CPU podría ser el limitante.

Decisión: Si la saturación de CPU se correlaciona con la latencia de I/O, considera cambiar el nivel de compresión (sin quitarla necesariamente), añadir CPU o aislar vecinos ruidosos.
No desactives la compresión como primera reacción; a menudo reduce la E/S de disco.

Tarea 13: Detectar impacto de TRIM/autotrim y decidir cuándo ejecutarlo

cr0x@server:~$ sudo zpool get autotrim tank
NAME  PROPERTY  VALUE     SOURCE
tank  autotrim  on        local
cr0x@server:~$ sudo zpool iostat -w tank 1
              operations     bandwidth    latency
pool        read  write   read  write   read  write
----------  ----  -----  -----  -----  -----  -----
tank         180    220  12.4M  19.1M   2ms   6ms
tank         175    240  12.2M  19.8M   3ms  18ms

Significado: Si ves picos periódicos de latencia de escritura sin cambios coincidentes en la carga, el mantenimiento en segundo plano (incluido TRIM en algunos dispositivos) puede ser el culpable.

Decisión: Si autotrim provoca jitter visible en sistemas sensibles a latencia, prueba desactivar autotrim y programar trims manuales en ventanas de baja carga. Mide, no adivines.

Tarea 14: Correlacionar “quién hace la E/S” con síntomas del pool

cr0x@server:~$ pidstat -d 1 5
Linux 6.5.0 (server)  12/25/2025  _x86_64_  (32 CPU)

12:12:01 AM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
12:12:02 AM     0      2211      120.0   82000.0      0.0       1  postgres
12:12:02 AM     0      3440      200.0   14000.0      0.0       0  qemu-system-x86

Significado: Postgres está martillando escrituras. Si zpool iostat -w muestra alta latencia de escritura, ahora puedes mantener una conversación productiva con el propietario de la base de datos.

Decisión: Decide si estás frente a un aumento legítimo de carga (escalar almacenamiento), una app mal configurada (bucle fsync) o una tarea operativa (vacuum, reindex) que debe programarse.

Reconocer patrones de carga en entornos reales

El objetivo de zpool iostat -w es reconocer patrones lo suficientemente rápido para actuar. Aquí están los comunes que aparecen en sistemas reales.

Patrón: escrituras pequeñas aleatorias, altas IOPS, bajo bandwidth, alta latencia

Se ve así: miles de ops de escritura, pocos MB/s, latencia de escritura decenas de milisegundos o peor.

Normalmente es: presión de WAL/fsync de bases de datos, journaling de VM, escrituras sync de NFS, cargas con muchos logs.

Qué hacer:

  • Confirma si las escrituras son síncronas (dataset sync y comportamiento de la app).
  • Asegura que SLOG esté presente, sea rápido y tenga protección frente a pérdida de energía si te interesa la durabilidad.
  • No pongas un SSD de consumo barato como SLOG y lo llames solución. Así compras pérdida de datos con factura.

Patrón: alto bandwidth de lectura, IOPS moderados, latencia de lectura en aumento

Se ve así: cientos de MB/s a GB/s en lecturas, latencia subiendo de pocos ms a decenas de ms.

Normalmente es: lecturas en streaming durante backups, escaneos analíticos, scrubs o tormenta de misses de caché.

Qué hacer:

  • Comprueba el estado de scrub/resilver.
  • Comprueba la tasa de aciertos del ARC indirectamente viendo si las lecturas llegan al disco (acompaña con estadísticas de ARC si están disponibles).
  • Si es tráfico real de usuarios, quizá necesites más vdevs o medios más rápidos. La latencia no negocia.

Patrón: un vdev muestra alta latencia; el promedio del pool parece “bien”

Se ve así: la línea de pool en zpool iostat -w parece aceptable; con -v aparece un mirror o disco con 10–100x latencia.

Normalmente es: disco fallando, cable malo, reinicios de HBA, estrangulamiento térmico o bug de firmware.

Qué hacer: trátalo como hardware hasta que se pruebe lo contrario. Reemplaza. No pases una semana escribiendo una propuesta de tunning alrededor de un disco que está muriendo en silencio.

Patrón: picos de latencia con throughput estable

Se ve así: mismos MB/s e IOPS, pero la latencia periódicamente se dispara.

Normalmente es: GC del dispositivo, TRIM, flushes de caché de escritura o contención en recursos compartidos (PCIe, HBA, host de virtualización).

Qué hacer: correlaciona con métricas a nivel de dispositivo y logs del sistema. Si es throttling térmico de NVMe, la “solución” puede ser flujo de aire, no software.

Broma #2: Si tus “picos de latencia son aleatorios”, felicidades: has creado una distribución de probabilidad en producción.

Tres micro-historias corporativas (porque la realidad es cruel)

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

Una compañía SaaS mediana migró un clúster Postgres ocupado desde un SAN antiguo a NVMe locales con mirrors ZFS. El equipo celebró:
los benchmarks se veían bien, la latencia media era baja y los gráficos de almacenamiento ya no parecían escenas de crimen.

Dos semanas después, un incidente: paradas periódicas de 2–5 segundos en endpoints con mucha escritura. No constantes. No previsibles.
El equipo de apps culpó a bloqueos. Los DBAs a autovacuum. Los SREs a “tal vez el kernel”.
Todos tenían su villano favorito y ninguno era el disco.

Alguien finalmente ejecutó zpool iostat -w -v 1 durante una parada. Los promedios del pool estaban bien, pero un NVMe mostraba latencia de escritura de cientos de milisegundos.
No fallaba por completo. Se estrangulaba de forma intermitente.

La suposición equivocada: “NVMe siempre es rápido, y si es lento debe ser ZFS”. La realidad: dispositivos NVMe de consumo pueden alcanzar límites térmicos y bajar rendimiento dramáticamente
bajo patrones sostenidos de escritura tipo sync. La caja tenía CPU excelente y flujo de aire terrible.

La solución fue gloriosamente aburrida: mejorar la refrigeración, actualizar firmware y cambiar ese modelo por piezas enterprise en el siguiente mantenimiento.
Tunear ZFS no habría ayudado. Observar la latencia por dispositivo con -w -v sí ayudó.

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

Un equipo de plataforma corporativo gestionaba un clúster multi-tenant de virtualización respaldado por un gran pool RAIDZ2. Había presión: los desarrolladores querían CI más rápido,
y el almacenamiento era “lo que todos se quejan”.

Alguien propuso una ganancia rápida: poner sync=disabled en el dataset de máquinas virtuales. El argumento fue seductor: “Tenemos UPS. El hipervisor puede recuperar.
Y son solo cargas de dev.” Lo cambiaron a última hora de la tarde y vieron cómo la latencia de escritura en zpool iostat bajaba. Abrazos de celebración.

Luego llegó la réplica. Un host se cayó de una forma que el UPS no evitó (fue un fallo de placa, no un corte de energía).
Un puñado de VMs sufrió corrupción de sistema de archivos. No todas. Justo las suficientes para arruinar un fin de semana y poner picante al postmortem.

El error operativo no fue “sync=disabled siempre está mal”. El error fue tratar las semánticas de durabilidad como una perilla de rendimiento sin modelar el radio de blast.
Optimizaron para el caso medio y pagaron por el riesgo en la cola.

La solución a largo plazo: volver a sync=standard, añadir un SLOG en espejo con protección PLP y segmentar “dev real” de “pseudo prod”
para que la decisión de durabilidad casara con la realidad del negocio. La lección: zpool iostat -w puede mostrar que las escrituras sync duelen,
pero no te da permiso para desactivarlas.

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

Una compañía relacionada con finanzas usaba ZFS para servicios de archivos y artefactos de build. Nada sofisticado. El tipo de almacenamiento que no recibe atención hasta que falla.
El ingeniero de almacenamiento tenía un hábito: un “ejercicio de cinco minutos” semanal durante horas laborables.
Ejecutar zpool iostat -w -v 1 por un minuto, mirar latencias, revisar zpool status y seguir con su día.

Un martes, el ejercicio mostró una pata de mirror con latencia de escritura en ascenso constante. Sin errores aún. Sin alertas. El sistema estaba “bien”.
Pero la tendencia de latencia estaba mal, como un cambio de sonido en una caja de cambios antes de que explote.

Sacaron datos SMART y encontraron errores de medio crecientes. El disco no estaba muerto; empezaba a mentir.
Programaron reemplazo para la próxima ventana de mantenimiento, resilverizaron y nunca tuvieron un outage.

Semanas después, otro disco del mismo modelo en otra flota falló en seco y causó un incidente visible. Mismo proveedor, mismo lote, mismo modo de fallo.
Su equipo escapó únicamente porque alguien miró -w y confió en la deriva lenta.

La práctica aburrida no fue heroica. Fue reconocer que los discos rara vez pasan de “perfecto” a “muerto” sin una fase de “raro”.
zpool iostat -w es excelente para detectar lo raro.

Errores comunes: síntoma → causa raíz → solución

Estos son los modos de fallo que sigo viendo en organizaciones reales. El truco es mapear el síntoma en zpool iostat -w a la causa probable,
y luego hacer un cambio específico que se pueda validar.

1) Latencia de escritura del pool alta, pero solo una pata del mirror está lenta

  • Síntoma: Latencia de escritura del pool se dispara; -v muestra un dispositivo con latencia de escritura mucho mayor.
  • Causa raíz: Throttling del dispositivo, GC de firmware, problema térmico, enlace malo o disco fallando.
  • Solución: Verifica con iostat -x y logs; reemplaza el dispositivo o arregla el path. No pierdas tiempo tunando recordsize o ARC.

2) Altas IOPS de escritura, bajo bandwidth de escritura, latencia de escritura fea

  • Síntoma: Miles de escrituras/s, solo unos MB/s, latencia de escritura de decenas de ms a segundos.
  • Causa raíz: Escrituras sync sin un SLOG rápido, o SLOG lento.
  • Solución: Añadir/reemplazar SLOG espejo con PLP; confirmar comportamiento sync de la app; aislar datasets y fijar semánticas de sync intencionalmente.

3) Las lecturas parecen bien hasta que los misses del ARC se disparan, luego todo se derrite

  • Síntoma: Normalmente pocas lecturas de disco; durante incidentes, IOPS/bandwidth de lectura saltan y la latencia de lectura sube.
  • Causa raíz: Working set supera el ARC, o cambio de patrón de acceso (scan, job de report, backup, nueva feature).
  • Solución: Añadir RAM (a menudo el mejor ROI), reconsiderar estrategia de caché o aislar cargas de scan. Valida observando cambios de lectura en zpool iostat -w.

4) Vdev RAIDZ se satura en I/O aleatorio pequeño de metadatos

  • Síntoma: Altas IOPS, bajo MB/s, alta latencia; el vdev es RAIDZ.
  • Causa raíz: Overhead de paridad en RAIDZ y IOPS limitados por vdev para escrituras pequeñas aleatorias.
  • Solución: Añadir más vdevs (no más discos al mismo vdev) o cambiar a mirrors para cargas I/O aleatorio sensibles a latencia. Considerar vdev especial para metadatos si procede.

5) “Mejoramos discos pero sigue lento”

  • Síntoma: SSDs nuevos, latencia similar bajo carga.
  • Causa raíz: Estás limitado por CPU (compresión/checksumming), o por diseño de vdev, o por PCIe/HBA.
  • Solución: Confirma con métricas CPU y stats por vdev; escala número de vdevs, arregla topología o mueve datasets calientes a un pool separado.

6) Picos de latencia durante scrubs/resilver y los usuarios se quejan

  • Síntoma: Latencia de lectura aumenta bruscamente cuando corren mantenimientos.
  • Causa raíz: Scrub/resilver compiten con la carga de producción.
  • Solución: Programar mantenimiento en horas valle, limitar si es posible o provisionar suficiente margen de rendimiento para que las comprobaciones de integridad no sean generadoras de outage.

Listas de verificación / plan paso a paso

Lista: responder a “el almacenamiento está lento” en menos de cinco minutos

  1. Ejecuta sudo zpool iostat -w -v tank 1 y observa 10–20 líneas.
  2. Identifica si predominan lecturas o escrituras, y si la latencia sube con la carga.
  3. Si un dispositivo destaca, pivota a iostat -x y logs del sistema para ese dispositivo.
  4. Revisa sudo zpool status tank por scrub/resilver.
  5. Revisa ajustes de sync del dataset implicado.
  6. Correlaciona con E/S por proceso (pidstat -d) para no depurar fantasmas.
  7. Haz un cambio a la vez; confirma el impacto con la misma vista de zpool iostat -w.

Lista: construir una línea base antes de tocar nada

  1. Captura zpool iostat -w -v 2 30 durante un periodo conocido como bueno.
  2. Captura lo mismo durante tráfico pico.
  3. Guarda salidas con marcas temporales en tu cuaderno de incidentes o ticket.
  4. Registra layout del pool: tipos de vdev, modelos de disco, ashift.
  5. Registra propiedades de datasets: recordsize, compression, sync, atime.
  6. Decide qué significa “malo” (umbrales de latencia alineados con tus SLO de aplicación).

Plan paso a paso: convertir observaciones en un proyecto de mejora

  1. Clasifica la carga: aleatoria vs secuencial, lectura vs escritura, sync vs async, metadatos vs bloques grandes.
  2. Mapea al layout ZFS: determina si el diseño de vdevs coincide con la carga.
  3. Corrige primero la corrección: reemplaza dispositivos malos, corrige cableado/HBA, asegura redundancia para SLOG/vdevs especiales.
  4. Reduce I/O evitable: habilita compresión sensata, ajusta recordsize por dataset, considera atime=off donde proceda.
  5. Escala correctamente: añade vdevs para escalar IOPS; no sigas agrandando un único vdev RAIDZ esperando milagros.
  6. Valida con -w: quieres menor latencia con la misma carga, no solo números de throughput más bonitos.
  7. Operativiza: añade chequeos rutinarios y alertas en anomalías de latencia por vdev, no solo en capacidad.

Preguntas frecuentes

1) ¿Qué mide realmente zpool iostat -w respecto a la latencia?

Informa la latencia observada para E/S de ZFS a nivel de pool/vdev, tal como ZFS la contabiliza. No es un sustituto perfecto de métricas firmware del dispositivo,
pero es muy bueno mostrando dónde se está gastando el tiempo y si hay cola.

2) ¿Por qué la latencia del pool parece bien, pero mi base de datos sigue lenta?

Porque los discos podrían no ser el cuello de botella. Podrías estar limitado por CPU (compresión, checksumming), bloqueos o comportamiento a nivel de aplicación con fsync.
Además, ARC puede enmascarar lecturas de disco hasta que los misses explotan. Correlaciona con CPU y E/S por proceso.

3) ¿Debería siempre ejecutar con -v?

Para diagnóstico, sí. Los promedios del pool ocultan dispositivos lentos y carga desigual entre vdevs. Para muestreo rápido en un sistema ocupado, empieza sin -v y luego pivota.

4) ¿Añadir más discos a un vdev RAIDZ aumenta IOPS?

No en la forma que la mayoría espera. Puede incrementar throughput secuencial, pero I/O aleatorio pequeño está limitado por overhead de paridad y comportamiento del vdev.
Si necesitas más IOPS, añade vdevs o usa mirrors para datos calientes.

5) ¿Cuándo vale la pena un SLOG?

Cuando tienes carga significativa de escrituras síncronas y te importan las semánticas de durabilidad (sync=standard).
Sin presión sync, un SLOG normalmente no hace nada medible. Con presión sync, puede ser la diferencia entre “funciona” y “por qué todo está haciendo timeout”.

6) ¿Puedo usar un SSD de consumo como SLOG?

Puedes, pero probablemente no deberías si te importa la corrección. Un buen SLOG necesita baja latencia bajo escrituras sync sostenidas y protección frente a pérdida de energía.
SSDs baratos pueden mentir sobre flushes y caer por rendimiento exactamente con la carga para la que los compraste.

7) ¿Por qué veo latencia alta durante scrub, aun cuando el tráfico de usuarios es bajo?

Los scrubs leen mucha data y pueden empujar las colas del vdev. Incluso con baja carga de app, el scrub es E/S real.
La solución es programarlo, limitarlo si es posible o provisionar margen suficiente.

8) ¿Es aceptable sync=disabled alguna vez?

Solo si tienes una decisión de riesgo clara y puedes tolerar perder los últimos segundos de escrituras en un crash o pérdida de energía, potencialmente con corrupción a nivel de aplicación.
Si el dataset contiene algo que llamarías “importante” en un postmortem, no lo hagas. Usa un SLOG adecuado en su lugar.

9) ¿Por qué aumenta la latencia de escritura aun cuando el bandwidth es constante?

Porque la cola y el comportamiento interno del dispositivo importan. Throughput constante puede acumular backlog si el tiempo de servicio del dispositivo aumenta por GC,
throttling térmico, flushes de caché de escritura o contención.

10) ¿Cuánto tiempo debo muestrear con zpool iostat -w?

Para triage de incidentes, 10–30 segundos a intervalos de 1 segundo suele ser suficiente para detectar el cuello de botella. Para planificación de capacidad o trabajo de rendimiento,
captura múltiples ventanas: idle, pico y “día malo”.

Conclusión: siguientes pasos que realmente cambian las cosas

zpool iostat -w no es una herramienta de reporting. Es un motor de decisiones. Te dice si tienes un problema de dispositivo, diseño, escrituras sync
o un “mantenimiento en segundo plano que se come mi almuerzo”—mientras el sistema está vivo y comportándose mal.

Próximos pasos prácticos:

  1. Durante un periodo calmado, captura una línea base: sudo zpool iostat -w -v tank 2 30.
  2. Anota cómo es la latencia “normal” por vdev y por ventana de carga.
  3. Cuando llegue la próxima queja, ejecuta el guion de diagnóstico rápido y resiste la tentación de tunear primero.
  4. Si descubres un patrón repetido (presión de escrituras sync, un dispositivo lento, dolor de metadatos en RAIDZ), conviértelo en un proyecto de ingeniería con resultados medibles.

Tu yo futuro no necesita más gráficos. Tu yo futuro necesita menos sorpresas. -w es cómo empiezas a cobrar intereses sobre el caos.

← Anterior
Ubuntu 24.04: logrotate no rota — el error de configuración que sigue afectando a la gente
Siguiente →
Ubuntu 24.04: fallos de TLS en curl — lista rápida de comprobación SNI/CA/tiempo

Deja un comentario