ZFS: Las 3 métricas que predicen un fallo del pool antes de que ocurra

¿Te fue útil?

Normalmente no “descubres” un fallo de pool ZFS de golpe. El pool se presenta—lentamente—a través de picos extraños de latencia, un scrub que de pronto dura una eternidad, o un contador inocente que se incrementa exactamente una vez y luego te quita el sueño.

El truco es tratar ZFS como el sistema de producción que es: vigila las pocas señales que realmente predicen el fallo, no los 47 paneles que solo lo confirman después.

Las 3 métricas que realmente predicen un fallo

Los fallos de ZFS en el mundo real rara vez se parecen a los dibujos animados. No siempre obtienes un claro “disco muerto, reemplazar disco”. Con más frecuencia obtienes:

  • Un desastre de E/S a cámara lenta que provoca timeouts en las aplicaciones, seguido de resets y luego la caída de un dispositivo.
  • Detección de corrupción silenciosa (checksums) que empieza pequeña y se convierte en “¿por qué estamos reescribiendo la mitad del pool?”
  • Presión de capacidad que convierte escrituras normales en una pesadilla de asignación, lo que deriva en latencia y luego en pánico.

Así que aquí están las tres métricas en las que me fijo porque tienden a moverse antes de que el pool esté en llamas:

1) Contadores de errores que cambian con el tiempo

No importa el hecho de que tengas un número distinto de cero una sola vez en la historia. Importa la pendiente. Si los contadores READ/WRITE/CKSUM se mueven entre scrubs, entre reinicios o entre dos puntos “conocidos buenos”, el pool te está diciendo que está perdiendo su contrato con la realidad.

2) Latencia + presión de colas en la capa pool/vdev

El throughput es una métrica de vanidad. La latencia es la verdad. El crecimiento de las colas y los tiempos de servicio largos son como detectas una inminente caída de dispositivo, un pool que entra en thrash, o un diseño que “iba bien en staging”.

3) Margen de capacidad y fragmentación

ZFS tolera mucho, pero no un pool que está casi lleno y además fragmentado y al que se le piden escrituras aleatorias. El predictor de fallo aquí no es “80% usado”. Es “estamos al otro lado de la curva y los scrubs/reslivers ahora toman una eternidad”.

Una idea parafraseada de Deming (la gente de fiabilidad lo cita constantemente por una razón): Sin datos, solo eres otra persona con una opinión. Parafraseado, pero el punto está claro: recopila los datos correctos.

Un chiste (1/2): ZFS no “falla al azar”. Solo espera hasta que estés de vacaciones y entonces presenta una queja detallada en forma de latencia.

Métrica 1: Contadores de errores que se mueven (READ/WRITE/CKSUM)

ZFS te da un regalo que la mayoría de las pilas de almacenamiento no tienen: checksumming end-to-end con contabilidad explícita de errores. Pero tienes que leerlo como operador, no como turista.

Qué cuenta como “predictivo” aquí

  • Nuevos errores de checksum (CKSUM) en un solo dispositivo, aumentando lentamente: a menudo cableado, backplane, controlador, firmware o medio marginal.
  • Errores de lectura en aumento: el dispositivo no pudo devolver datos (o no lo hizo dentro de la paciencia del driver). Si esto se mueve, el disco está postulándose para ser reemplazado.
  • Errores de escritura en aumento: puede ser del dispositivo, pero también de rutas HBA/controlador, problemas de alimentación o timeouts bajo carga.
  • Errores ligados a bloques específicos que reaparecen después de un scrub: ahora estás viendo corrupción persistente o una “arreglo” que no arregló.

Cómo ocurren los crashes a partir de “solo algunos errores”

Un crash de pool, en la práctica, suele ser una cascada:

  1. El dispositivo empieza a devolver errores ocasionales o a tardar demasiado.
  2. ZFS reintenta; la cola crece; la latencia se dispara; empiezan los timeouts de la aplicación.
  3. El driver reinicia el dispositivo; ZFS lo marca FAULTED o DEGRADED.
  4. Comienza un resilver; la carga aumenta; otros dispositivos marginales se estresan.
  5. Ahora estás a un parpadeo más de perder redundancia.

Por eso “solo 3 errores de checksum” no es una frase reconfortante. Es una frase que debe disparar investigación y análisis de tendencias, porque los conteos pequeños suelen ser los créditos iniciales.

Qué hacer con contadores no nulos

Decides basado en persistencia, localidad y correlación:

  • Persistencia: ¿Los errores siguen aumentando después de un scrub y después de volver a asentar cables?
  • Localidad: ¿Es un dispositivo o varios? Un solo camino sugiere hardware. Muchos sugieren controlador, backplane, firmware o alimentación.
  • Correlación: ¿Los errores coinciden con picos de carga, temperatura o un host específico?

Métrica 2: Latencia y presión de colas (el pool “respira con fuerza”)

Cuando los pools ZFS “crashean”, a menudo no están realmente muertos. Simplemente están atrapados en una latencia patológica: técnicamente todo funciona, pero nada termina a tiempo para tus apps. Operacionalmente es indistinguible de estar caído.

Cómo se ven las señales de latencia en ZFS

Quieres vigilar el nivel pool y vdev, no solo IOPS por disco:

  • Await alto / tiempos de servicio largos durante cargas normales.
  • Profundidad de cola en aumento (peticiones acumulándose porque el pool no puede drenarlas).
  • Scrub/resilver tomando mucho más tiempo que las líneas base históricas.
  • Presión de escrituras sync (especialmente con un SLOG mal diseñado o sin SLOG para cargas con muchas sync).

Por qué esto predice caídas de dispositivos

Los timeouts y resets suelen ser primero una historia de latencia. Muchos “fallos de disco” son “el disco se volvió demasiado lento y el OS se rindió”. Esa distinción importa porque la solución cambia:

  • Si un solo disco está lento: reemplázalo.
  • Si todos los discos se vuelven lentos a la vez: revisa HBA, expander, firmware, errores PCIe, saturación, presión ARC o comportamiento por pool lleno.
  • Si solo las escrituras sync están lentas: revisa SLOG, configuraciones sync y la semántica de la carga de trabajo.

Un chiste (2/2): La profundidad de cola es como el correo electrónico: cuanto más larga, menos probable que algo importante reciba respuesta.

Métrica 3: Margen de capacidad + fragmentación (metaslabs y el precipicio)

El rendimiento de ZFS no es lineal con la ocupación. El pool tiene un cambio de fase: la asignación se vuelve más difícil, el espacio libre se fragmenta en piezas más pequeñas y las escrituras son más caras. El pool no necesita estar al 99% para comportarse como si estuviera muriendo.

El margen no es una sensación; es una perilla de control

Si operas pools ZFS en producción, deberías tener una política explícita de margen. Mi línea base opinionada:

  • Cargas mixtas generales: mantener por debajo de ~80% usado.
  • Cargas con muchas escrituras aleatorias, intensivas en metadatos, snapshots por doquier: apuntar por debajo de ~70% usado.
  • Vdevs con Rust y bloques pequeños: sé más estricto; la fragmentación te golpea antes.

Eso no son leyes de la física; son guardarraíles. La señal real es la tendencia: cuando la asignación se ralentiza y la fragmentación sube, estás fuera de la zona cómoda.

Fragmentación y por qué se vuelve “como un fallo”

ZFS asigna desde metaslabs. A medida que el espacio libre se fragmenta, las asignaciones requieren más seek, más trabajo de metadata, más operaciones de I/O y tiempos de commit de TXG más largos. Los síntomas incluyen:

  • Latencia de escritura en ascenso incluso cuando el throughput parece “bien”.
  • Scrubs/reslivers pasando de horas a días.
  • Bloqueos intermitentes donde las apps se detienen durante el sync de TXG.

Los problemas de capacidad también amplifican otros riesgos: resilvers en pools casi llenos tardan más, aumentando el tiempo de exposición en que estás a un disco de la pérdida de datos.

Guía de diagnóstico rápido

Este es el orden que uso cuando una app dice “el almacenamiento está lento” o cuando la monitorización muestra degradación de salud del pool. Está diseñado para encontrar el cuello de botella rápido, no para satisfacer la curiosidad.

Primero: ¿el pool está lógicamente sano o ya está sangrando?

  • Comprueba zpool status por DEGRADED/FAULTED, contadores de errores y cualquier scrub/resilver en curso.
  • Si los contadores de errores se están moviendo: trátalo como un incidente, no como una sesión de tuning.

Segundo: ¿es esto latencia/presión de colas (sistémico) o un actor malo (un solo vdev/dispositivo)?

  • Usa zpool iostat -v para identificar qué vdev está lento, no solo qué dataset está ocupado.
  • Correlaciona con iostat y logs del kernel por resets/timeouts.

Tercero: ¿es la capacidad/fragmentación la culpable oculta?

  • Revisa la asignación del pool e indicadores de fragmentación. Si estás cerca del precipicio, los “bugs” de rendimiento suelen ser física.
  • Valida el crecimiento de snapshots y cargas con bloques pequeños (VMs, bases de datos, colas de correo) que aceleran la fragmentación.

Cuarto: confirma la semántica de la carga (sync, recordsize, special vdevs)

  • ¿NFS con muchas sync? ¿Imágenes de VM con escrituras pequeñas? ¿Un “listo” SLOG? ¿Special vdev? Estos moldean la ruta de I/O y los modos de fallo.
  • No adivines. Extrae las propiedades del dataset y observa los patrones reales de I/O.

Tareas prácticas: comandos, salidas y decisiones

A continuación hay tareas prácticas que puedes ejecutar hoy. Cada una incluye: comando, salida de ejemplo, qué significa y qué decisión tomar. Estos son los movimientos aburridos que mantienen tu pool con vida.

Tarea 1: Leer la salud del pool y la pendiente de errores

cr0x@server:~$ sudo 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, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
  scan: scrub repaired 0B in 03:18:22 with 0 errors on Sun Feb  4 01:10:43 2026
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     2
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0

errors: No known data errors

Qué significa: Un disco tiene 2 errores de checksum. ZFS los corrigió y reporta no tener errores de datos conocidos. Eso no es “está bien”; es “investigar”.

Decisión: Comprueba si el contador CKSUM aumenta con el tiempo. Si se incrementa de nuevo después de un scrub o tras volver a asentar cables, planifica reemplazar el disco e inspeccionar cableado/backplane.

Tarea 2: Limpiar errores solo después de capturar evidencia

cr0x@server:~$ sudo zpool clear tank

Qué significa: Los contadores se reinician. Esto es útil para medir tendencias, pero también destruye tu comparación antes/después si no lo registraste.

Decisión: Limpia solo después de haber capturado la salida de zpool status (ticket/notas) y estar listo para observar si los errores vuelven a aparecer.

Tarea 3: Confirmar si un scrub está en curso y cómo se comporta

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
  scan: scrub in progress since Mon Feb  3 00:12:10 2026
        3.42T scanned at 1.21G/s, 1.88T issued at 684M/s, 8.10T total
        0B repaired, 23.19% done, 0:02:53 to go
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0
errors: No known data errors

Qué significa: El scrub progresa rápidamente. Compara las tasas scan/issue con scrubs previos.

Decisión: Si la velocidad de scrub de repente se reduce a la mitad (o peor) sin un cambio intencional de carga, investiga latencia y fragmentación; es una advertencia temprana.

Tarea 4: Identificar qué vdev está lento bajo carga

cr0x@server:~$ sudo zpool iostat -v tank 2 5
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        6.12T  1.98T    320    610  42.1M  81.7M
  raidz2-0                  6.12T  1.98T    320    610  42.1M  81.7M
    ata-WDC_WD80...-part1      -      -     40     90  5.1M  12.0M
    ata-WDC_WD80...-part1      -      -     41     88  5.0M  11.8M
    ata-WDC_WD80...-part1      -      -     39     92  5.2M  12.3M
    ata-WDC_WD80...-part1      -      -     40    250  5.0M  35.0M
    ata-WDC_WD80...-part1      -      -     40     90  5.1M  12.1M
    ata-WDC_WD80...-part1      -      -    120      0  16.7M   0.0
--------------------------  -----  -----  -----  -----  -----  -----

Qué significa: Un disco está recibiendo escrituras desproporcionadas (250 ops) y otro está tomando la mayoría de lecturas (120 ops). Puede ser normal según el layout de paridad y la carga, pero la persistencia de esa asimetría puede indicar un dispositivo lento que hace esperar al resto.

Decisión: Si un dispositivo muestra constantemente menor ancho de banda con más ops (I/O pequeñas) y los logs del sistema muestran timeouts, considera sospechoso ese dispositivo/ruta.

Tarea 5: Obtener estadísticas de latencia (OpenZFS) para detectar explosiones en tiempo de servicio

cr0x@server:~$ sudo zpool iostat -v -l tank 1 3
                              capacity     operations     bandwidth    latency
pool                        alloc   free   read  write   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----  -----  -----
tank                        6.12T  1.98T    310    590  41.0M  79.0M  2.1ms  18.4ms
  raidz2-0                  6.12T  1.98T    310    590  41.0M  79.0M  2.1ms  18.4ms
    ata-WDC_WD80...-part1      -      -     40     90  5.1M  12.0M  1.8ms  12.2ms
    ata-WDC_WD80...-part1      -      -     40     90  5.0M  12.0M  1.9ms  12.4ms
    ata-WDC_WD80...-part1      -      -     40     90  5.2M  12.1M  2.0ms  12.6ms
    ata-WDC_WD80...-part1      -      -     40    240  5.0M  33.0M  2.1ms  85.0ms
    ata-WDC_WD80...-part1      -      -     40     90  5.1M  12.0M  2.0ms  12.5ms
    ata-WDC_WD80...-part1      -      -    110      0  15.6M   0.0  2.2ms   0.0ms
--------------------------  -----  -----  -----  -----  -----  -----  -----  -----

Qué significa: Un disco muestra 85ms de latencia de escritura mientras los pares están en ~12ms. Ese es tu informe de incidente futuro.

Decisión: Correlaciona con los logs del kernel; planifica reemplazo o remediación de la ruta. No “tunes” alrededor de un disco que está desarrollando personalidad.

Tarea 6: Comprobar uso del pool y implicaciones de ashift

cr0x@server:~$ sudo zpool list -o name,size,alloc,free,cap,health,ashift tank
NAME  SIZE  ALLOC   FREE  CAP  HEALTH  ASHIFT
tank  8.10T  6.12T  1.98T   75%  ONLINE  12

Qué significa: 75% usado, ashift=12 (sectores 4K). Buena referencia para discos/SSDs modernos.

Decisión: Si ashift es incorrecto (p. ej., 9 en unidades 4K), no puedes arreglarlo in situ; planifica una reconstrucción/migración. Un ashift errado es un impuesto de rendimiento a largo plazo que puede convertirse en un problema de estabilidad bajo carga.

Tarea 7: Inspeccionar propiedades del dataset que cambian la ruta de I/O

cr0x@server:~$ sudo zfs get -o name,property,value -s local recordsize,compression,atime,sync,logbias xattr tank/vmstore
NAME          PROPERTY     VALUE
tank/vmstore  recordsize   16K
tank/vmstore  compression  lz4
tank/vmstore  atime        off
tank/vmstore  sync         standard
tank/vmstore  logbias      latency
tank/vmstore  xattr        sa

Qué significa: Este dataset está ajustado para bloques pequeños estilo VM (recordsize 16K), compresión lz4, atime off, logbias latency. Bien, pero implica sensibilidad a escrituras sync e intensidad de metadata.

Decisión: Verifica que realmente tienes un SLOG sensato si la latencia de escrituras sync importa. No pongas recordsize pequeño “por las bases de datos”; mide tu tamaño de I/O primero.

Tarea 8: Identificar presión de snapshots (predictor de capacidad)

cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer -s used | head
NAME                                USED  REFER
tank/vmstore@auto-2026-02-04-0000    48G   3.1T
tank/vmstore@auto-2026-02-03-0000    44G   3.1T
tank/vmstore@auto-2026-02-02-0000    39G   3.1T
tank/vmstore@auto-2026-02-01-0000    33G   3.1T

Qué significa: Los snapshots están consumiendo espacio real (USED), incluso si REFER se mantiene similar. Esto puede comer margen silenciosamente y provocar fragmentación.

Decisión: Implementa retención y verifica que realmente se eliminan los snapshots. Si USED por snapshot crece más rápido de lo esperado, tu churn es alto y los resilvers dolerán más.

Tarea 9: Medir presión ARC (predictor de latencia disfrazado)

cr0x@server:~$ sudo arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:10:01   612   118     16    44    6    60    8    14    2   46.2G  64.0G
12:10:02   590   121     17    50    7    55    8    16    3   46.2G  64.0G
12:10:03   640   130     17    52    7    61    8    17    3   46.3G  64.0G

Qué significa: El tamaño de ARC es estable; tasa de misses ~16–17%. Si la tasa de misses se dispara y empiezas a golpear discos, la latencia sigue.

Decisión: Si ARC está constreñido (límites de contenedor, ballooning de VM, zfs_arc_max mal configurado), arregla la presión de memoria primero. No culpes a los discos por lo que la RAM no cacheó.

Tarea 10: Detectar patrones de error/reset en los logs del kernel

cr0x@server:~$ sudo dmesg -T | egrep -i 'reset|timeout|error|ata|nvme' | tail -n 12
[Mon Feb  3 13:42:11 2026] ata7.00: exception Emask 0x10 SAct 0x0 SErr 0x4050002 action 0x6 frozen
[Mon Feb  3 13:42:11 2026] ata7.00: irq_stat 0x08000000, interface fatal error
[Mon Feb  3 13:42:12 2026] ata7: hard resetting link
[Mon Feb  3 13:42:17 2026] ata7: link is slow to respond, please be patient (ready=0)
[Mon Feb  3 13:42:22 2026] ata7: COMRESET failed (errno=-16)
[Mon Feb  3 13:42:22 2026] ata7.00: disabled

Qué significa: Resets de enlace y fallos COMRESET apuntan a problemas de cableado/backplane/ruta HBA, no necesariamente “mal ZFS”. Este es un precursor clásico de dispositivos que caen del pool.

Decisión: Reemplaza cables, mueve puertos, verifica alimentación y backplane. Si los errores siguen al puerto, el disco es inocente y el chasis está mintiendo.

Tarea 11: Verificar SMART/NVMe del dispositivo sospechoso

cr0x@server:~$ sudo smartctl -a /dev/sdg | egrep -i 'Reallocated_Sector_Ct|Current_Pending_Sector|Offline_Uncorrectable|CRC_Error_Count|SMART overall'
SMART overall-health self-assessment test result: PASSED
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       2
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       2
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       14

Qué significa: “PASSED” es marketing. Sectores pendientes + offline_uncorrectable son serios. CRC errors sugieren problemas de cableado/ruta.

Decisión: Si los CRC errors aumentan, arregla cableado/backplane primero. Si los sectores pendientes persisten/aumentan, programa reemplazo—especialmente si la redundancia está reducida.

Tarea 12: Comprobar el calendario de scrub y asegurarse de que no fallen silenciosamente

cr0x@server:~$ systemctl status zfs-scrub@tank.timer
● zfs-scrub@tank.timer - ZFS scrub timer for tank
     Loaded: loaded (/lib/systemd/system/zfs-scrub@.timer; enabled; preset: enabled)
     Active: active (waiting) since Sun Feb  2 00:00:01 2026
    Trigger: Mon Feb  17 00:00:00 2026

Qué significa: Los scrubs están programados y habilitados.

Decisión: Si los scrubs no se están ejecutando regularmente, pierdes la detección temprana. Habilita y monitoriza la finalización de scrubs y los contadores de errores.

Tarea 13: Detectar datasets casi llenos y sorpresas de cuotas

cr0x@server:~$ sudo zfs list -o name,used,avail,refer,mountpoint -S used | head
NAME           USED  AVAIL  REFER  MOUNTPOINT
tank/vmstore   5.4T   520G  3.1T   /tank/vmstore
tank/backups   580G  2.2T   580G   /tank/backups
tank/home      120G  2.7T   120G   /tank/home

Qué significa: vmstore consume la mayor parte del espacio; solo 520G “available” a nivel de dataset puede ser justo dependiendo del churn y comportamiento de snapshots.

Decisión: Si este dataset tiene churn elevado (VMs), aumenta el margen eliminando snapshots, moviendo datos o ampliando el pool antes de que el rendimiento colapse.

Tarea 14: Comprobar special vdev y entender el radio de impacto

cr0x@server:~$ sudo 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
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
            ata-WDC_WD80...-part1   ONLINE       0     0     0
        special
          mirror-1                  ONLINE       0     0     0
            nvme-INTEL_SSDPE...     ONLINE       0     0     0
            nvme-INTEL_SSDPE...     ONLINE       0     0     0

Qué significa: Existe un special vdev (metadata/bloques pequeños dependiendo de ajustes). Sus semánticas de fallo pueden ser graves si metadata crítica vive allí.

Decisión: Trata los special vdevs como ciudadanos de primera clase: mórralos en mirror, monitorízalos, mantén firmware estable y no escatimes en resistencia.

Tarea 15: Confirmar comportamiento sync cuando la latencia sube “solo para algunas escrituras”

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

Qué significa: Las escrituras sync se cumplen. Si tu carga es sync-heavy y no tienes un SLOG capaz (o tienes uno malo), lo notarás.

Decisión: No pongas sync=disabled como “arreglo de rendimiento” a menos que hayas aceptado explícitamente la semántica de pérdida de datos. Si necesitas baja latencia para sync, diseña el SLOG correctamente.

Tres micro-historias del mundo corporativo

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

Operaban una flota de hosts de virtualización con pools ZFS locales. Era una configuración cómoda: SSDs espejo para boot, raidz para almacenamiento bulk de VMs y scrubs semanales. La suposición del equipo era simple: los errores de checksum significan “el disco está malo”. Eso decían las gráficas, y las gráficas nunca estaban equivocadas.

Un host empezó a acumular un pequeño número de errores CKSUM en dos unidades, no en una. El on-call reemplazó la primera unidad. Los errores siguieron. Luego reemplazaron la segunda. Aún seguían subiendo. A nadie le gustó la idea, pero el equipo empezó a planear un mantenimiento mayor: “quizá tenemos un lote malo”.

Mientras tanto, el patrón del incidente se volvió más feo. Bajo carga máxima de escrituras, un disco desaparecía brevemente, ZFS degradaba el vdev y las VMs se congelaban lo suficiente para que los OS invitados hicieran panic. Luego el dispositivo volvía, a veces. Los contadores subían como una escalera—solo durante ventanas de alto tráfico específicas.

La causa raíz fue una ruta de backplane: un conector marginal que se comportaba hasta que la temperatura sostenida y la vibración lo afectaron en la combinación exacta. La suposición “el disco está malo” retrasó la solución correcta por una semana y quemó varias ventanas de mantenimiento. Una vez que movieron los discos a bahías distintas (y reemplazaron el backplane), los contadores de checksum dejaron de moverse. Mismos discos. Mismos datos. Realidad distinta.

Lección: Un error de checksum no es un diagnóstico de disco; es una alarma de integridad de datos. Cuando los errores se extienden entre dispositivos, sospecha primero de componentes compartidos: cableado, backplane, HBA, expander, alimentación.

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

Un equipo de plataforma de datos quería más rendimiento NFS para un cluster analítico muy cargado. El backend era ZFS sobre un conjunto decente de HDDs con suficiente RAM. La latencia parecía aceptable hasta los jobs nocturnos por lotes, cuando las escrituras sync se acumulaban y todos se quejaban.

Alguien propuso una solución rápida: añadir un NVMe “rápido” de consumo como SLOG. En papel era perfecto—barato, benchmarks fantásticos, instalación fácil. También cambiaron un par de propiedades de dataset en la misma ventana de cambios para “alinear para escrituras pequeñas”. El benchmark mejoró. Hubo felicitaciones. Así es como siempre empieza.

Dos meses después, el pool no se cayó exactamente. Hizo algo más sutil y más caro: empezó a bloquearse durante segundos, luego decenas de segundos. Los clientes NFS colgaban. Los logs del kernel mostraban errores ocasionales en el NVMe. El dispositivo SLOG no estaba muerto, solo intermitentemente lento y ocasionalmente reiniciándose. Cada reset forzaba reintentos dolorosos y, como el SLOG estaba en la ruta crítica de las escrituras sync, todo el servicio parecía caído.

El desencadenante final fue un evento de alimentación en el rack. El NVMe de consumo carecía de la protección ante pérdida de energía que realmente quieres en un dispositivo de log. Tras el reinicio, el equipo pasó una larga noche validando integridad de datos y semánticas de replay. Tuvieron suerte, pero la suerte no es una arquitectura.

Lección: SLOG no es “una caché”. Es un dispositivo de log de escritura previa con requisitos de fiabilidad y latencia. Si añades un SLOG, que sea de grado enterprise, réplicalo si la carga lo exige y monitorízalo como si fuera producción—porque lo es.

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

Una compañía SaaS mediana operaba ZFS en nodos de almacenamiento dedicados que soportaban object storage y backups internos. Nada sofisticado. Tenían una política que sonaba casi cómicamente estricta: scrubs mensuales, registro obligatorio de duración de scrub y una regla simple—cualquier dispositivo con errores recurrentes tras remediación se reemplaza antes del siguiente ciclo de mantenimiento.

No fue popular al principio. Los scrubs generan carga. Reemplazar discos cuesta dinero. Y anotar tiempos de scrub parecía burocracia. Pero insistieron porque en las post-mortems de incidentes eran implacables con “no sabíamos” como excusa inaceptable.

Un mes, el tiempo de scrub en un pool clave se duplicó sin crecimiento en datos totales. Nadie había tocado el layout. Los contadores de errores seguían en cero. Pero el equipo trató “el scrub tardó el doble” como señal de fallo y empezó a investigar. Encontraron un conjunto de discos que aún estaban online pero con tiempos de recuperación de lectura mucho mayores. El OS todavía no hacía timeout; ZFS no se había quejado. Esa fue la ventana.

Reemplazaron dos discos de forma controlada y en baja carga—antes de que el pool se degradara, antes de que un resilver compitiera con tráfico de producción, antes de estar a una sorpresa de un mal día. Una semana después, uno de los discos retirados falló una prueba diagnóstica del proveedor.

Lección: Las líneas base son un seguro barato. La duración de scrub y resilver son indicadores tempranos de problemas incluso cuando la “salud” parece verde.

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

1) “Unos pocos errores de checksum, pero el scrub dice 0 reparados”

Síntoma: CKSUM se incrementa; scrub informa 0 reparados; las apps parecen bien.

Causa raíz: Corrupción transiente en la ruta (cable/backplane/HBA) o medio marginal que aún no forzó una reparación; los contadores pueden reflejar datos corregidos vía redundancia sin requerir reparación por scrub.

Solución: Captura zpool status -v, limpia contadores, vuelve a asentar/reemplaza cables, revisa logs por resets, ejecuta otro scrub. Si los contadores vuelven, reemplaza el dispositivo o arregla hardware compartido.

2) “Pool está ONLINE pero todo hace timeout”

Síntoma: No hay errores ZFS obvios, pero las aplicaciones cuelgan; iowait se dispara.

Causa raíz: Colapso de latencia por un dispositivo lento, fragmentación por pool casi lleno, cuello de botella de escrituras sync o un resilver/scrub compitiendo con la carga.

Solución: Usa zpool iostat -v -l para encontrar el vdev lento. Revisa capacidad, actividad de scrub/resilver y la ruta sync (SLOG). Limita scrubs si es necesario y arregla el componente lento real.

3) “Resilver ahora tarda una eternidad”

Síntoma: Reemplazar un disco solía tardar horas; ahora tarda días.

Causa raíz: El pool está más lleno, más fragmentado y/o la carga es mayor; también posibles lentitudes a nivel de dispositivo que aumentan el tiempo de servicio.

Solución: Aumenta margen (elimina snapshots, migra datos fríos), programa resilvers en baja carga, considera vdevs más anchos con cautela y verifica que ningún dispositivo esté retrasado vía estadísticas de latencia.

4) “Arreglamos el rendimiento poniendo sync=disabled” (y luego…)

Síntoma: El rendimiento mejora dramáticamente; luego hay pérdida de datos tras un crash/evento de energía.

Causa raíz: Cambio semántico: las escrituras síncronas ya no son durables al commit.

Solución: Vuelve a sync=standard. Si necesitas rendimiento sync, diseña el SLOG y el comportamiento de la carga. Si realmente aceptas el riesgo, documéntalo como un contrato con el negocio.

5) “El rendimiento de lectura aleatoria es terrible en pool SSD”

Síntoma: Latencia inesperadamente alta; IOPS bajos.

Causa raíz: ashift incorrecto, particiones desalineadas o problema de firmware/controlador de SSD; a veces también mismatch de recordsize causando amplificación de lectura.

Solución: Confirma ashift y alineación. Si está mal, planifica una reconstrucción. Valida salud y firmware del SSD; ajusta recordsize del dataset al workload.

6) “Special vdev aceleró todo, luego el pool se volvió frágil”

Síntoma: Aceleración de metadata/bloques pequeños útil—hasta que los errores del special vdev empezaron y todo se puso feo.

Causa raíz: El special vdev contiene asignaciones críticas; si está mal protegido o usa dispositivos débiles, su fallo amenaza la disponibilidad del pool y a veces los datos.

Solución: Mirror el special vdev, usa dispositivos de alta resistencia, monitoriza SMART/NVMe y ten repuestos listos. Trátalo como parte del pool, no como un plugin.

Listas de verificación / plan paso a paso

Checklist diaria/continua (qué graficar y alertar)

  • Pendiente de errores: alerta cuando cualquier vdev READ/WRITE/CKSUM aumente desde la última baseline.
  • Duración de scrub: alerta cuando la duración aumente más allá de un umbral vs las últimas 3 ejecuciones.
  • Duración de resilver: rastrea tiempo-para-completar; tendencia ascendente es aumento de exposición al riesgo.
  • Percentiles de latencia: latencia de escritura a nivel pool y vdev (p95/p99), no solo throughput promedio.
  • Margen de capacidad: cap del pool + tendencia “días para llenar”; incluye crecimiento de snapshots.

Cuando ves errores nuevos (respuesta paso a paso)

  1. Captura evidencia: zpool status -v, zpool events -v (si está disponible), líneas relevantes de logs del kernel.
  2. Identifica el alcance: un dispositivo vs varios dispositivos vs toda la ruta del controlador.
  3. Si varios dispositivos están afectados: investiga primero componentes compartidos (HBA, expander, backplane, alimentación).
  4. Ejecuta/verifica un scrub si es apropiado y seguro bajo la carga actual.
  5. Limpia contadores después de tener una baseline, luego observa si recurren.
  6. Reemplaza hardware de forma proactiva si los contadores recurren o la latencia se degrada, incluso si el pool sigue ONLINE.

Cuando la latencia sube (respuesta paso a paso)

  1. Comprueba si scrub/resilver está en curso y compite con producción.
  2. Ejecuta zpool iostat -v -l e identifica el vdev/dispositivo más lento por latencia.
  3. Revisa logs del OS por resets/timeouts en esa ruta.
  4. Revisa el fullness del pool y el churn de snapshots; si estás cerca del precipicio, crea margen inmediatamente.
  5. Valida la carga sync y la salud del SLOG si la latencia de escrituras sync domina.
  6. Sólo después de descartar hardware y capacidad, ajusta propiedades como recordsize y compresión.

Plan de mantenimiento trimestral (aburrido, correcto, efectivo)

  • Revisa tiempos de scrub y tendencias de errores para cada pool; actualiza las líneas base después de cambios mayores.
  • Revisa retención de snapshots y verifica que las eliminaciones realmente ocurren.
  • Prueba el flujo de reemplazo de disco en un sistema no crítico: etiquetado, zpool replace, monitorización de resilver y scrub post-check.
  • Audita versiones de firmware para HBAs y SSDs; aplica actualizaciones aprobadas por el proveedor en una ventana controlada.
  • Planificación de capacidad: proyecta crecimiento y programa expansiones antes de cruzar tu política de headroom.

Datos interesantes y contexto histórico (porque el almacenamiento tiene su lore)

  • ZFS se originó en Sun Microsystems a mediados de los 2000 como un sistema de ficheros + gestor de volúmenes integrado, creado explícitamente para reducir el dolor de “RAID + mismatch del filesystem”.
  • El checksumming end-to-end fue un objetivo de diseño central: detectar corrupción silenciosa en vez de confiar en capas inferiores.
  • Copy-on-write (CoW) es la razón por la que ZFS puede hacer snapshots consistentes de forma económica, pero también por la que la fragmentación y el comportamiento casi lleno pueden morder bajo cargas de escritura aleatoria.
  • Los scrubs existen porque los discos mienten: pueden devolver datos malos sin reportar errores. Los scrubs de ZFS validan checksums en todo el pool.
  • RAIDZ no es RAID5 en un driver: está integrado con el allocator y el modelo de transacciones, lo que es poderoso pero hace al rendimiento sensible a recordsize y forma de la carga.
  • ashift se convirtió en una lección operacional de larga duración: escoger la alineación de sector equivocada no suele romper datos, solo castiga el rendimiento para siempre.
  • “SLOG” se malinterpreta constantemente: solo se usa para escrituras síncronas; no acelera escrituras async normales, y un SLOG malo puede dañarte.
  • OpenZFS evolucionó en varias plataformas (Illumos, FreeBSD, Linux) y convergió como código compartido, por eso algunos comandos/características varían ligeramente por OS y versión.
  • Los special vdevs son armas operacionales relativamente modernas: potentes para metadata/bloques pequeños, pero crean nuevos dominios de fallo que requieren disciplina operativa madura.

FAQ

1) ¿Cuál es la métrica más predictiva de “dolor inminente”?

Nuevos contadores de error combinados con latencia de escritura en aumento. Los errores predicen riesgo de integridad; la latencia predice riesgo de disponibilidad. Cuando ambos se mueven, estás en zona de peligro.

2) Si zpool status dice “No known data errors”, ¿puedo relajarme?

No. Significa que ZFS cree que corrigió o evitó daño visible para el usuario. No significa que la causa subyacente haya desaparecido. Mira tendencias y logs.

3) ¿Los errores de checksum siempre implican un disco malo?

No. Pueden ser cableado, backplane, HBA, expander, firmware o alimentación. Si varios discos muestran incrementos en CKSUM, sospecha primero de infraestructura compartida.

4) ¿Por qué un pool “parece caído” cuando solo está lento?

Porque tus aplicaciones tienen timeouts. Un sistema de almacenamiento que responde tras 60 segundos está funcionalmente abajo para sistemas que esperan 200ms.

5) ¿Qué ocupación del pool es “demasiado llena”?

Depende de la carga, pero muchos pools de producción empiezan a comportarse mal más allá de ~80% usado, antes si la carga es heavy en escrituras aleatorias. Usa tiempos de scrub/resilver para encontrar tu precipicio.

6) ¿Debo ejecutar scrubs semanalmente o mensualmente?

Mensual es una línea base común; scrubs más frecuentes pueden justificarse para datos de alto valor o hardware inestable. Lo clave es la consistencia y rastrear tiempo de finalización y errores.

7) ¿Añadir un SLOG es siempre buena idea?

No. Solo ayuda para escrituras síncronas. Un SLOG débil o inestable puede empeorar cargas sync y convertirse en amplificador de fallo. Elige con cuidado.

8) ¿Sobre qué debo alertar por errores ZFS?

Alerta por cualquier aumento en READ/WRITE/CKSUM por dispositivo, estados DEGRADED/FAULTED, inicio/fin y duración de scrub/resilver, y latencia sostenida alta a nivel vdev.

9) Si los resilvers son lentos, ¿puedo “acelerarlos” de forma segura?

Puedes influir reduciendo la carga competidora y asegurando margen. El tuning agresivo puede dejar sin recursos a las aplicaciones o incrementar riesgo. El “acelerón” más seguro es tener menos problemas: margen y discos sanos.

10) ¿Cuándo reemplazo un disco si SMART dice PASSED?

Cuando la evidencia operacional muestra tendencia a peor: aumento de sectores pendientes, uncorrectables, errores ZFS recurrentes o latencia fuera de rango respecto a los pares. “PASSED” no es garantía.

Conclusión: pasos prácticos siguientes

Si quieres predecir un fallo de pool ZFS, deja de mirar lo que te hace sentir informado y empieza a mirar lo que cambia tus decisiones:

  1. Haz trending de contadores de errores (READ/WRITE/CKSUM) por dispositivo y alerta por incrementos, no solo por valores no nulos.
  2. Mide latencia y presión de colas a nivel vdev, y trata la latencia fuera de rango como un incidente de hardware/ruta hasta demostrar lo contrario.
  3. Haz cumplir el headroom y rastrea duración de scrub/resilver como advertencia temprana de que el pool cruza su precipicio de rendimiento.

Luego haz lo poco glamuroso: escribe las líneas base, mantén los scrubs regulares y reemplaza componentes antes de que el pool te obligue. ZFS es extremadamente honesto. Simplemente no es educado con el tiempo.

← Anterior
BIND9: La configuración que parece correcta pero provoca NXDOMAIN intermitente
Siguiente →
Puntos de restauración ausentes: la configuración que Windows sigue desactivando

Deja un comentario