Sparing dRAID de ZFS: Cómo los repuestos distribuidos cambian la recuperación

¿Te fue útil?

Las fallas tradicionales en RAIDZ tienen un ritmo conocido: un disco muere, insertas un repuesto y esperas mientras el pool castiga a ese único disco de reemplazo durante horas (o días) como si fuera el culpable.
Mientras tanto, la latencia sube, los dueños de las aplicaciones fruncen el ceño y el equipo de almacenamiento empieza a negociar con la física.

dRAID cambia ese ritmo. Los repuestos distribuidos hacen que la recuperación sea una operación paralela entre muchos discos, no un evento de resistencia en un único disco.
Es importante—cuando se entiende y se opera correctamente. Si no, puedes acabar “recuperado” en los registros mientras el rendimiento se desploma en silencio.

Qué cambia el sparing dRAID (y qué no)

El titular: dRAID sustituye el modelo de “hot spare como disco completo” por espacio de repuesto distribuido dentro del vdev dRAID.
Cuando un disco falla, la reconstrucción escribe en slices de repuesto repartidos entre los discos supervivientes, permitiendo I/O de recuperación en paralelo.
La reconstrucción es menos “un disco es alimentado a la fuerza con paridad” y más “la clase entera hace la evaluación juntos”.

Pero dRAID no reescribe las leyes del almacenamiento mágicamente. Aún tienes que:

  • Sobrellevar el dominio de falla que diseñaste (dRAID1 vs dRAID2 vs dRAID3).
  • Pagar el trabajo de paridad con CPU y I/O de disco.
  • Vivir con el hecho de que un pool en reconstrucción está bajo estrés.

Dos modelos mentales: resilver en RAIDZ vs reconstrucción en dRAID

El resilver en RAIDZ tradicionalmente vuelve a reproducir metadatos y copia bloques que siguen siendo referenciados, pero tiende a hacerlo apuntando mucho al dispositivo de reemplazo.
El reemplazo se convierte en el cuello de botella—especialmente si es un HDD entre HDDs, o peor, un disco más pequeño con comportamiento SMR que no notaste.

dRAID está diseñado para evitar ese punto único de estrangulamiento usando espacio de repuesto distribuido. Eso cambia los modos de fallo de recuperación:

  • Bueno: puedes volver a redundancia más rápido (a menudo de forma drástica) porque las escrituras no se serializan por un único disco.
  • Diferente: las escrituras de recuperación se distribuyen entre muchos discos, así que todo el vdev puede estar “caliente” durante la reconstrucción.
  • Más complejo: puedes “completar” la reconstrucción en slices distribuidos y aún necesitar una reposición física posterior para restaurar la capacidad de repuesto original.

Qué debes importar operacionalmente

En términos operativos, el sparing dRAID cambia la ventana de riesgo:

  • El tiempo en reducción de redundancia puede disminuir, que es el objetivo.
  • El impacto en el rendimiento del pool durante la reconstrucción puede ser más amplio porque más discos participan.
  • El trabajo posterior (reemplazar el disco fallado y evacuar los slices distribuidos de vuelta a él) se convierte en una fase distinta que debes planear.

Repuestos distribuidos explicados como un SRE

La forma más limpia de pensar: en dRAID, cada disco físico contribuye no solo con slices de datos y paridad, sino también (opcionalmente) con slices de repuesto.
Esos slices de repuesto se distribuyen por todo el vdev. Cuando un disco falla, ZFS reconstruye los slices faltantes y los escribe en los slices de repuesto del resto de discos.

Eso significa que el “repuesto” no es un disco solitario e inactivo esperando tragedia. Es capacidad reservada salpicada por todas partes, lista para usarse de inmediato.

Por qué ayuda: paralelismo y evitar el cuello de botella del “disco de reemplazo”

El comportamiento tradicional del hot spare a menudo tiene una propiedad brutal: el dispositivo de reemplazo debe absorber una enorme secuencia de escrituras mayormente secuenciales mientras participa también en lecturas y cálculos de paridad.
El participante más lento se vuelve el metrónomo de la reconstrucción.

Con repuestos distribuidos, las escrituras de reconstrucción pueden emitirse a muchos discos en paralelo.
Eso tiende a:

  • Reducir el tiempo de recuperación para grandes pools de HDD.
  • Hacer que el tiempo de rebuild sea menos sensible a un único dispositivo de repuesto lento.
  • Mejor utilizar JBODs amplios donde ya compraste los spindles—ahora realmente los usas durante la recuperación.

Qué cambia respecto a “reemplazar el disco”

En dRAID, “un disco falló” y “se inserta un disco nuevo” son eventos relacionados pero no idénticos.
Puedes reconstruir en repuestos distribuidos antes de tener un reemplazo físico disponible. Eso es poderoso en sitios remotos, entornos de laboratorio o por realidades de la cadena de suministro.
Pero también es una trampa si tratas “reconstruido” como “terminado”.

El vdev ha consumido sus slices de repuesto. Ahora funcionas con menos (o cero) capacidad de repuesto hasta que reemplaces físicamente el disco fallado y reequilibres los datos fuera de los slices distribuidos.
Esa fase posterior importa. Ignórala y es básicamente como conducir con la rueda de repuesto fingiendo que es un juego completo.

Broma #1: Los repuestos distribuidos son como tener extintores en cada habitación en lugar de uno en el vestíbulo—todavía no sustituyen a no prender fuego a las cosas.

Recorrido de recuperación: de la falla al estado estable

Vamos a recorrer la línea temporal de una falla en un pool dRAID, enfocándonos en qué cambia operacionalmente.
Seré neutral respecto al proveedor pero específico con comandos, porque nadie te llamó para un seminario de filosofía.

Fase 0: pool sano, slices de repuesto reservados

En estado estable, los slices de repuesto dRAID están reservados pero sin usar.
Estás pagando en capacidad bruta por esa preparación, igual que con un repuesto tradicional, pero también pagas en complejidad de layout.
Así que lo monitoreas como si importara.

Fase 1: falla del disco (o marcado como faulted)

El pool detecta una tasa de errores de dispositivo, timeouts o una ruta muerta. ZFS marca el dispositivo como FAULTED u OFFLINE.
En ese momento, el pool está degradado. Tu primera pregunta debería ser: ¿Seguimos dentro de la tolerancia de paridad?

Fase 2: reconstrucción en repuestos distribuidos

El objetivo de diseño de dRAID es reconstruir rápido paralelizando I/O de reconstrucción entre los discos restantes.
Durante esta fase, puedes ver:

  • Aumento de lecturas I/O en muchos miembros (para reconstruir datos/paridad faltante).
  • Aumento de escrituras I/O en muchos miembros (escribiendo en slices de repuesto).
  • Impacto en latencia en todo el pool incluso si el throughput parece correcto, porque las colas se profundizan por todas partes.

Tu trabajo: confirmar que progresa, confirmar que está limitado por el cuello de botella esperado (usualmente discos), y confirmar que nada más está fallando.

Fase 3: estable pero “viviendo en slices de repuesto”

Después de la reconstrucción, la redundancia puede restaurarse en sentido lógico: los slices faltantes ahora están presentes en otro lugar.
Pero has consumido espacio de repuesto. Operativamente, no has vuelto al estado base.

Punto de decisión:

  • Si puedes reemplazar el disco pronto, hazlo y completa la sanación.
  • Si no puedes, sé honesto sobre el riesgo: otra falla puede empujarte fuera de la tolerancia de paridad y puede que no queden slices de repuesto para absorberla con gracia.

Fase 4: reemplazo físico y evacuación

Cuando insertas un disco nuevo y lo adjuntas, ZFS puede redistribuir datos desde los slices de repuesto hacia el nuevo dispositivo, reponiendo efectivamente la capacidad de repuesto distribuida.
Aquí es donde algunos equipos se sorprenden: celebran después de la reconstrucción y luego olvidan terminar la última milla, y seis meses después están “misteriosamente” cortos de espacio de repuesto.

Hechos e historia: por qué existe dRAID

Las funcionalidades de almacenamiento rara vez aparecen porque los ingenieros estaban aburridos. dRAID es reacción a un dolor muy específico: tiempo de rebuild y riesgo de rebuild en grupos RAID muy anchos con HDDs grandes.

  • Hecho 1: A medida que las capacidades de HDD crecieron más rápido que el throughput de reconstrucción por disco, el tiempo en degradado se convirtió en una preocupación principal de confiabilidad para arrays RAID.
  • Hecho 2: Los diseños tradicionales de “hot spare global” pueden estrangular la velocidad de rebuild en el disco spare único, incluso cuando docenas de discos están mayormente inactivos.
  • Hecho 3: Los proveedores de RAID introdujeron “repuestos distribuidos” hace años en arrays hardware para reducir el tiempo de rebuild y evitar concentrar la carga en un solo spare.
  • Hecho 4: ZFS históricamente enfatizó la corrección y checksumming de extremo a extremo; la velocidad de rebuild bajo falla en vdevs muy anchos se volvió una presión operacional creciente.
  • Hecho 5: El término “resilver” es específico de ZFS y refleja que ZFS típicamente reconstruye solo datos vivos referenciados por metadata, no el dispositivo crudo entero (aunque el comportamiento depende de topología y funciones).
  • Hecho 6: Los grupos de paridad anchos pueden sufrir “amplificación de rebuild”: se deben leer más discos para reconstruir datos perdidos, aumentando la carga y la probabilidad de encontrar errores adicionales durante la recuperación.
  • Hecho 7: Las implementaciones modernas de JBOD (muchos discos detrás de HBAs) hicieron que el paralelismo durante la recuperación no solo fuese posible sino necesario—si no, compraste spindles que no usas cuando más los necesitas.
  • Hecho 8: Operativamente, los mayores outages de almacenamiento a menudo no son la primera falla de disco; son la segunda falla durante una ventana prolongada de rebuild.
  • Hecho 9: dRAID también busca reducir efectos de caída abrupta de rendimiento distribuyendo la carga de reconstrucción; esto hace que el impacto sea más amplio pero a menudo más superficial.

Tres microhistorias corporativas desde el campo

Microhistoria 1: El incidente causado por una suposición equivocada

Una compañía SaaS mediana migró una capa de logging de RAIDZ2 a dRAID2 porque querían recuperación más rápida y menos maratones de rebuild nocturnos.
El piloto fue bien. Los dashboards se veían más tranquilos. La gerencia declaró victoria, lo cual siempre es un momento peligroso.

Unos meses después, un disco falló en producción. El de guardia vio que el pool se reconstruyó rápidamente y marcó el incidente como “resuelto”.
No reemplazaron el disco fallado inmediatamente porque compras tenía backlog y el sistema parecía estable.
El pool funcionó semanas con slices distribuidos consumidos.

Entonces un segundo disco en la misma bahía empezó a lanzar timeouts intermitentes. No muerto, lo suficientemente inestable como para causar largos stalls de I/O.
ZFS hizo lo que debía: reintentó, registró errores y siguió. La aplicación hizo lo que siempre hace ante stall: acumuló colas.
La latencia explotó, la canalización de logging se retrasó, y de repente la “capa de logging no crítica” estaba demorando forenses de incidentes en otra falla.

La suposición equivocada fue simple: tratar “reconstruction complete” como “redundancia y capacidad de repuesto totalmente restauradas.”
En términos dRAID, tenían estabilidad pero no margen. La solución fue aburrida: formalizar la fase de reemplazo con un SLO.
Reemplazar el disco fallado dentro de una ventana definida y rastrear “repuestos distribuidos consumidos” como métrica de riesgo de primera clase.

Microhistoria 2: La optimización que se volvió en contra

Una firma de analítica financiera corría una carga intensiva de lecturas aleatorias en un pool de HDDs respaldado por un ARC grande y un L2ARC modesto.
Pasaron a dRAID porque sus vdevs eran anchos y el tiempo de rebuild se estaba volviendo un tema de confiabilidad que nadie quería explicar a los auditores.

Un ingeniero—inteligente, bienintencionado y alérgico a recursos ociosos—decidió “ayudar” el rendimiento de recuperación aumentando agresividad de rebuild durante la reconstrucción.
El pool se reconstruyó rápido, claro. También convirtió la latencia normal de consultas en un incidente diario.
El negocio empezó a fallar en horas pico porque los discos estaban gastando su presupuesto de IOPS en reconstrucción en vez de servir.

El postmortem fue directo: optimizaron para el tiempo de finalización e ignoraron el tiempo de servicio.
En pools anchos, la reconstrucción paralela puede saturar todo el conjunto de discos. Eso no es “velocidad gratis”, es una forma diferente de gastar la misma moneda de I/O.

La solución fue operacional, no heroica: limitar la agresividad de reconstrucción en horas hábiles y permitir mayor velocidad fuera de pico.
También movieron algunos datasets “calientes” a pools basados en SSD donde el comportamiento de rebuild importaba menos y la latencia importaba más.

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

Una empresa de salud mantenía archivos de imágenes en grandes pools dRAID. Los datos eran write-once, read-rarely y absolutamente no debían desaparecer.
Su equipo de almacenamiento era discretamente conservador: probaban procedimientos de reemplazo trimestralmente, mantenían firmware consistente y rotaban al personal de guardia por ejercicios prácticos.
Nadie organizaba fiestas por esto. Así sabes que era el trabajo correcto.

Un fin de semana, un backplane en una bahía empezó a hacer flapping con dos discos—desconexiones breves y luego reconexiones.
ZFS marcó un dispositivo como degradado, inició actividad de reconstrucción y luego se estabilizó cuando la ruta volvió.
El de guardia siguió el playbook: confirmó que no era un solo disco, revisó logs del HBA y puso la bahía en ventana de mantenimiento.

Reemplazaron el backplane, recolocaron cables y solo entonces reemplazaron los discos sospechosos.
Porque tenían un procedimiento practicado, no reemplazaron en pánico media chasis e introdujeron más riesgo.
La reconstrucción se completó sin drama.

El “salvamento” no fue una perilla de tuning ingeniosa. Fue el hábito de chequear la capa de hardware primero, verificar dominios de falla y hacer mantenimiento controlado.
Lo aburrido ganó. Otra vez.

Tareas prácticas: comandos, salidas, decisiones (12+)

Estos son movimientos reales de operador. Cada tarea incluye: el comando, qué significa la salida y la decisión que tomas.
Nombres de host y pools son ejemplos; no copies y pegues en prod a menos que disfrutes escribir informes de incidentes.

Task 1: Confirmar salud del pool y si reconstrucción/resilver está activa

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
  scan: resilver in progress since Thu Dec 26 02:01:11 2025
        1.23T scanned at 1.8G/s, 620G issued at 900M/s, 14.2T total
        620G resilvered, 4.25% done, 04:18:33 to go
config:

        NAME                                      STATE     READ WRITE CKSUM
        tank                                      DEGRADED     0     0     0
          draid2:8d:24c:1s-0                      DEGRADED     0     0     0
            sda                                    ONLINE       0     0     0
            sdb                                    ONLINE       0     0     0
            sdc                                    FAULTED      0     0     0  too many errors
            sdd                                    ONLINE       0     0     0
            ...
errors: No known data errors

Significado: El pool está degradado y hay un resilver en progreso. “errors: No known data errors” es lo que quieres ver.
La línea de scan te da throughput, porcentaje completado y ETA. El número “issued” ayuda a detectar throttling o contención.

Decisión: Si la ETA es razonable y los errores están estables, monitorizas. Si la ETA se dispara o los errores aumentan, salta a la guía rápida de diagnóstico.

Task 2: Identificar si se está consumiendo espacio de repuesto (visión general)

cr0x@server:~$ sudo zpool list -v tank
NAME     SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank    218T   141T    77T        -         -     18%    64%  1.00x  DEGRADED  -
  draid2:8d:24c:1s-0  218T   141T    77T        -         -     18%    64%      -      -

Significado: Esto no imprime directamente “repuesto consumido”, pero confirma que estás en un vdev dRAID y el estado del pool.
La capacidad y la fragmentación importan porque alta fragmentación puede ralentizar la reconstrucción.

Decisión: Si CAP es alto y FRAG es alto, espera una recuperación más lenta y planifica una ventana de riesgo mayor.

Task 3: Confirmar el layout exacto del vdev (parámetros dRAID)

cr0x@server:~$ sudo zpool status tank | sed -n '1,80p'
  pool: tank
 state: DEGRADED
  scan: resilver in progress since Thu Dec 26 02:01:11 2025
config:

        NAME                     STATE     READ WRITE CKSUM
        tank                     DEGRADED     0     0     0
          draid2:8d:24c:1s-0     DEGRADED     0     0     0
            sda                  ONLINE       0     0     0
            sdb                  ONLINE       0     0     0
            sdc                  FAULTED      0     0     0
            sdd                  ONLINE       0     0     0

Significado: La cadena dRAID codifica datos/paridad/children/repuestos. Diferentes plataformas presentan formatos ligeramente distintos, pero lo clave es:
puedes ver nivel de paridad (draid2) y que hay capacidad de repuesto (1s).

Decisión: Verifica que el nivel de paridad coincida con tu apetito de riesgo. Si construiste dRAID1 por “capacidad barata”, acepta que las operaciones serán picantes.

Task 4: Buscar errores de datos silenciosos vs errores de dispositivo

cr0x@server:~$ sudo zpool status -xv tank
pool 'tank' is degraded
status: One or more devices is currently being resilvered.
errors: No known data errors

Significado: “No known data errors” significa que ZFS no ha detectado pérdida de validez por checksum en bloques almacenados.
Los errores de dispositivo no son lo mismo que datos corruptos, pero los errores de dispositivo pueden convertirse en datos corruptos si te quedas sin paridad.

Decisión: Si hay errores de datos conocidos, deja de debatir; escala. Puede que necesites restaurar desde backup los objetos afectados.

Task 5: Encontrar el dispositivo fallido por identificador persistente (no /dev/sdX)

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'sdc|ata|wwn' | head
lrwxrwxrwx 1 root root  9 Dec 26 01:58 ata-WDC_WD140EDGZ-11B2DA0_9KJ3ABCD -> ../../sdc
lrwxrwxrwx 1 root root  9 Dec 26 01:58 wwn-0x5000cca2b3c4d5e6 -> ../../sdc

Significado: /dev/sdc puede cambiar entre reinicios. by-id y wwn son estables y deberían ser lo que usa tu zpool.

Decisión: Si tu pool fue construido con rutas /dev/sdX, programa una corrección. No es “si” te va a morder, es “cuando”.

Task 6: Inspeccionar logs del kernel por resets de enlace y problemas de la bahía

cr0x@server:~$ sudo dmesg -T | egrep -i 'ata|sas|scsi|reset|timeout|I/O error' | tail -n 15
[Thu Dec 26 01:56:09 2025] sd 4:0:12:0: [sdc] tag#198 FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_OK
[Thu Dec 26 01:56:09 2025] ata12: hard resetting link
[Thu Dec 26 01:56:10 2025] ata12: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Thu Dec 26 01:56:12 2025] blk_update_request: I/O error, dev sdc, sector 1827342336 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0

Significado: Timeouts y resets de enlace suelen implicar cableado, backplane, HBA o expander—no solo el disco.

Decisión: Si múltiples discos en la misma ruta muestran resets, pausa el reflejo de “reemplazar el disco” y investiga la ruta de la bahía.

Task 7: Medir presión real de I/O en tiempo real durante la reconstrucción

cr0x@server:~$ iostat -x 2 5
Linux 6.6.0 (server)   12/26/2025  _x86_64_  (64 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.10    0.00    6.92    9.40    0.00   71.58

Device            r/s     w/s   rMB/s   wMB/s  avgrq-sz avgqu-sz   await  r_await  w_await  svctm  %util
sda              85.0    42.0   160.0    52.0     254.0      9.2   78.0     62.0    110.0   4.1   98.0
sdb              81.0    39.0   158.0    49.0     255.0      8.8   74.0     60.0    105.0   4.0   97.0
sdd              83.0    40.0   159.0    50.0     253.0      8.9   76.0     61.0    108.0   4.0   98.0

Significado: Los discos están cerca del 100% de utilización con await alto. Eso es esperado durante una recuperación agresiva, pero perjudica la latencia.

Decisión: Si esto es una capa sensible a latencia, limita la reconstrucción (ver tareas abajo) o mueve la carga.

Task 8: Vigilar I/O por vdev en ZFS y comportamiento de resilver

cr0x@server:~$ sudo zpool iostat -v tank 2 3
                                   capacity     operations     bandwidth
pool                             alloc   free   read  write   read  write
-------------------------------  -----  -----  -----  -----  -----  -----
tank                              141T    77T  3.10K  1.20K  1.45G   620M
  draid2:8d:24c:1s-0              141T    77T  3.10K  1.20K  1.45G   620M
    sda                               -      -    130     55    62M    27M
    sdb                               -      -    128     54    61M    26M
    sdd                               -      -    129     55    61M    27M
-------------------------------  -----  -----  -----  -----  -----  -----

Significado: Puedes ver la reconstrucción distribuyendo I/O entre miembros. Esta es la firma operacional de repuestos distribuidos: muchos dispositivos haciendo trabajo.

Decisión: Si un disco va muy retrasado respecto a otros, sospecha un dispositivo lento, una ruta mala o rarezas SMR. Investiga antes de que se convierta en el nuevo cuello de botella.

Task 9: Confirmar compresión a nivel de dataset y recordsize (implicaciones en recuperación)

cr0x@server:~$ sudo zfs get -o name,property,value -s local,received compression,recordsize tank/data
NAME       PROPERTY     VALUE
tank/data  compression  zstd
tank/data  recordsize   1M

Significado: Recordsize grande y compresión pueden afectar cuánto I/O físico necesita tocar la reconstrucción, y el coste CPU de la interacción paridad/compresión.

Decisión: Si la CPU está saturada durante la recuperación, considera si un nivel de compresión demasiado agresivo está haciendo la reconstrucción bound por CPU.

Task 10: Comprobar solapamiento scrub/resilver (dolor auto-infligido)

cr0x@server:~$ sudo zpool status tank | egrep -i 'scan:|scrub|resilver'
  scan: resilver in progress since Thu Dec 26 02:01:11 2025
        1.23T scanned at 1.8G/s, 620G issued at 900M/s, 14.2T total

Significado: Si un scrub está corriendo durante un resilver/reconstrucción, estás ejecutando dos operaciones caras de integridad a la vez.

Decisión: No las solapes a menos que tengas una razón. Si un scrub se inició automáticamente, pausa (task 11).

Task 11: Pausar un scrub para reducir contención (cuando convenga)

cr0x@server:~$ sudo zpool scrub -p tank

Significado: Esto pausa un scrub en curso en muchas plataformas. El comportamiento depende de la versión de OpenZFS y la integración con el OS.

Decisión: Si estás reconstruyendo tras una falla, prioriza la operación que restaura redundancia primero. Reanuda el scrub después.

Task 12: Poner offline un dispositivo que hace flapping para dejar de empeorar la situación

cr0x@server:~$ sudo zpool offline tank sdc

Significado: OFFLINE le dice a ZFS que deje de intentar con ese dispositivo. Para una ruta que hace flapping, esto puede estabilizar el pool y permitir que la reconstrucción proceda de forma predecible.

Decisión: Si el dispositivo tiene timeouts intermitentes, hacer offline puede prevenir reintentos repetidos y tormentas de latencia. Pero confirma que aún estás dentro de la tolerancia de paridad.

Task 13: Volver a poner online un dispositivo tras arreglar la ruta

cr0x@server:~$ sudo zpool online tank sdc

Significado: ONLINE permite a ZFS usarlo otra vez. Si estaba realmente sano y el problema era cableado, esto puede reducir la carga de recuperación.

Decisión: Haz esto solo después de abordar el problema de la ruta subyacente, de lo contrario reintroducirás flapping y perderás tiempo.

Task 14: Reemplazar un disco fallado usando una ruta by-id estable

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

Significado: Esto le indica a ZFS que adjunte el nuevo dispositivo como reemplazo del antiguo. El pool hará resilver/rebalance según sea necesario.

Decisión: Si no usas by-id/wwn, estás a un reinicio de reemplazar el disco equivocado. Usa identificadores estables. Siempre.

Task 15: Verificar que ZFS no está bloqueado por CPU (costes de paridad y checksum)

cr0x@server:~$ mpstat -P ALL 2 2 | head -n 15
Linux 6.6.0 (server)  12/26/2025  _x86_64_  (64 CPU)

12:14:01 PM  CPU   %usr  %nice   %sys %iowait  %irq  %soft  %steal  %idle
12:14:03 PM  all  28.10   0.00  14.90    6.50  0.00   1.20    0.00  49.30
12:14:03 PM    0  92.00   0.00   6.00    0.00  0.00   0.00    0.00   2.00
12:14:03 PM    1  88.50   0.00  10.00    0.00  0.00   0.00    0.00   1.50

Significado: Si algunos CPUs están saturados mientras los discos no lo están, podrías estar bound por CPU (checksum, paridad, compresión).

Decisión: Si estás CPU-bound durante la recuperación, considera reducir temporalmente cargas competidoras y revisar ajustes de compresión para diseño futuro.

Task 16: Comprobar presión de memoria (thrash de ARC cambia latencia)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           512Gi       396Gi        22Gi       5.2Gi        94Gi       105Gi
Swap:           16Gi       0.5Gi        15Gi

Significado: Si “available” colapsa y swap crece, tu sistema puede estar thrashing, convirtiendo la reconstrucción en un carnaval de latencia.

Decisión: Si hay swapping, detén consumidores de memoria no esenciales y considera límites de ARC (con cuidado) en sistemas donde ZFS compite con aplicaciones.

Task 17: Validar que el disco de reemplazo está sano antes de confiar en él

cr0x@server:~$ sudo smartctl -a /dev/disk/by-id/wwn-0x5000cca2b3c4d5ff | egrep -i 'Model|Serial|Reallocated|Pending|Offline_Uncorrectable|SMART overall'
Device Model:     WDC WD140EDGZ-11B2DA0
Serial Number:    9KJ3WXYZ
SMART overall-health self-assessment test result: PASSED
Reallocated_Sector_Ct     0
Current_Pending_Sector    0
Offline_Uncorrectable     0

Significado: Estás comprobando señales obvias de fallo temprano. Un disco “nuevo” con sectores pendientes no es “nuevo”, es “incidente futuro”.

Decisión: Si los atributos SMART están malos, RMAalo ahora. No dejes que el resilver sea tu test de burn-in.

Task 18: Confirmar que no estás fuera de margen de repuestos silenciosamente (chequeo operacional)

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
status: One or more distributed spares have been consumed.
action: Replace the failed device and allow the pool to heal to restore spare space.
  scan: resilvered 14.2T in 05:01:22 with 0 errors on Thu Dec 26 07:02:33 2025
config:

        NAME                     STATE     READ WRITE CKSUM
        tank                     ONLINE       0     0     0
          draid2:8d:24c:1s-0     ONLINE       0     0     0
            sda                  ONLINE       0     0     0
            sdb                  ONLINE       0     0     0
            sdd                  ONLINE       0     0     0
            ...

Significado: Este es el mensaje específico de dRAID “no olvides la última milla” que debes tratar como un ticket, no como una sugerencia.

Decisión: Programa el reemplazo físico si no ha ocurrido y rastrea este estado hasta que desaparezca. Operar permanentemente con repuestos consumidos es pedir una secuela.

Guía rápida de diagnóstico

Cuando la reconstrucción es lenta o el rendimiento es terrible, necesitas encontrar el cuello de botella real rápido. No “eventualmente.”
Aquí está el orden que suele ganar.

1) Empieza con la verdad: ¿qué piensa ZFS que está pasando?

  • zpool status -v tank: ¿Hay resilver/reconstrucción? ¿Progresa? ¿Hay errores de datos?
  • zpool iostat -v tank 2: ¿Participan todos los discos uniformemente? ¿Algún rezagado obvio?

Si ZFS muestra errores en aumento, deja de optimizar y empieza a estabilizar. Una falla rápida sigue siendo una falla.

2) Decide si estás limitado por disco, ruta o CPU

  • iostat -x 2: Si %util está cerca de 100% con await alto en todas partes, estás disk-bound (esperado, pero puede que necesites throttling).
  • dmesg -T: Si ves resets/timeouts, estás path-bound. Arregla cableado/backplane/HBA antes de tocar perillas de ZFS.
  • mpstat: Si CPUs están pegados mientras discos no, estás CPU-bound (paridad/checksum/compresión).

3) Busca contención auto-infligida

  • Scrub solapándose con resilver.
  • Backups golpeando el pool durante la recuperación.
  • Concurrencia de aplicación sin límites (p. ej., restores paralelos o reindexados).

Si tu organización no puede reducir carga durante la recuperación, diseña para esa realidad: más paridad, dominios de falla más pequeños o otro tier para tráfico sensible a latencia.

4) Valida la hipótesis del “disco lento único”

dRAID paraleliza el trabajo, pero aún puede estar rehén de un disco que hace stalls intermitentes.
En vdevs anchos, un disco con stalls periódicos de 30 segundos puede crear tail latency en todo el pool.

  • Chequea smartctl por errores de media.
  • Revisa logs por resets de enlace.
  • Compara throughput por disco en zpool iostat -v.

5) Solo entonces considera tuning

El tuning es lo último porque es la forma más fácil de sentirse productivo mientras haces el sistema menos predecible.
Si ajustas, hazlo con plan de rollback y una métrica clara de éxito (ETA, SLO de latencia, o ambos).

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

Error 1: “Resilver completado, así que ahora estamos seguros”

Síntoma: El pool está ONLINE, pero el estado menciona repuestos distribuidos consumidos; semanas después, otra falla de disco es una crisis.

Causa raíz: Tratar la reconstrucción en repuestos distribuidos como estado final en lugar de un salvavidas temporal.

Arreglo: Reemplaza el disco fallado prontamente y verifica que el aviso de “repuestos distribuidos consumidos” desaparezca. Regístralo como ítem de riesgo.

Error 2: Reconstrucción lenta atribuida a ZFS, pero es la bahía

Síntoma: Throughput de recuperación fluctúa salvajemente; dmesg muestra resets; múltiples discos muestran timeouts.

Causa raíz: Cable SAS malo, expander, backplane o firmware HBA marginal. La recuperación estresa la ruta y la expone.

Arreglo: Arregla el transporte primero. Cambia cables, revisa salud del expander, confirma consistencia de firmware y solo entonces reejecuta la reconstrucción.

Error 3: Recuperación demasiado agresiva en carga pico

Síntoma: Rebuild termina rápido pero la latencia de la aplicación es terrible; ocurren timeouts de cara al usuario.

Causa raíz: Tratar el tiempo de rebuild como único objetivo. La reconstrucción paralela puede consumir todo el set de spindles.

Arreglo: Limita la recuperación durante horas de negocio y acelera fuera de pico. Si tu plataforma lo soporta, ajusta prioridad de scan/resilver con cautela.

Error 4: Usar /dev/sdX en pools productivos

Síntoma: Después de reinicio o mantenimiento, los dispositivos aparecen intercambiados; se reemplaza el disco equivocado.

Causa raíz: Nombres de dispositivo no persistentes.

Arreglo: Usa /dev/disk/by-id o rutas WWN para miembros de vdev y reemplazos. Documenta el mapeo a bahías.

Error 5: Elegir ancho dRAID por capacidad bruta, no por comportamiento de recuperación

Síntoma: La reconstrucción golpea todo el pool; el impacto en rendimiento es inaceptable; la ventana de riesgo sigue asustando.

Causa raíz: Grupos dRAID demasiado anchos para la carga y hardware. Más ancho no siempre es mejor.

Arreglo: Reduce el ancho del dominio de falla (más vdevs, menos discos por grupo dRAID), o mueve cargas sensibles a latencia a tiers SSD/NVMe.

Error 6: Olvidar que “un disco inestable” puede imitar “rebuild lento”

Síntoma: ETA sigue aumentando; tasa de scan cae; un dispositivo muestra errores intermitentes pero permanece ONLINE.

Causa raíz: Disco marginal que no ha fallado completamente; ZFS reintenta, lo que mata el throughput.

Arreglo: Reemplaza proactivamente el disco marginal. No esperes a que falle limpiamente por caridad.

Error 7: Dejar que scrubs se solapen con recuperación

Síntoma: Aparecen scrub y resilver; el ancho de banda se divide; todo va más lento.

Causa raíz: La programación automática de scrub no considera ventanas de recuperación por fallas.

Arreglo: Pausa el scrub durante la recuperación y reanúdalo. Ajusta la automatización para detectar y posponer cuando haya un resilver en curso.

Broma #2: Lo único más rápido que un rebuild dRAID es el email de finanzas preguntando por qué necesitas “tantos discos”.

Listas de verificación / plan paso a paso

Checklist A: Cuando un disco falla en un pool dRAID

  1. Confirmar tolerancia de paridad y estado del pool.
    Ejecuta zpool status -v. Si estás fuera de tolerancia de paridad, para: estás en territorio de pérdida de datos.
  2. Buscar errores de datos.
    Usa zpool status -xv. Si hay errores de datos conocidos, abre un incidente y empieza planificación de restauración.
  3. Validar que no es un problema de ruta.
    Revisa dmesg -T por resets/timeouts. Si varios discos en la misma ruta lo muestran, investiga enclosure/HBA primero.
  4. Estabilizar dispositivos que hacen flapping.
    Si un dispositivo tiene timeouts intermitentes, considera zpool offline para detener el thrash, siempre que la paridad lo permita.
  5. Monitorear progreso e impacto.
    Usa zpool iostat -v 2 y iostat -x 2. Decide si throttlear o mover cargas.
  6. Reemplazar hardware deliberadamente.
    Reemplaza el disco fallado usando by-id/WWN. Evita reemplazar múltiples discos a la vez a menos que disfrutes la probabilidad.
  7. Confirmar estado de restauración de repuestos.
    Tras la reconstrucción, asegura que la advertencia de “repuestos distribuidos consumidos” se limpie tras el reemplazo y la sanación.

Checklist B: Decisiones en diseño que hacen aburrida la recuperación dRAID

  1. Elige paridad según tu realidad de fallas. dRAID2 es la base pragmática para grandes pools de HDD. dRAID1 es para quienes disfrutan casos límite.
  2. No hagas dominios de falla demasiado amplios. Grupos muy anchos se reconstruyen rápido pero aún pueden crear contención en todo el pool. Equilibra velocidad de recuperación contra latencia de servicio.
  3. Estandariza hardware. Modelos de disco mixtos y revisiones de firmware son donde discos “idénticos” se vuelven muy no idénticos bajo carga.
  4. Mapea bahía → WWN. Mantén un mapeo para reemplazar el disco físico correcto sin danza interpretativa.
  5. Automatiza detección. Alertar en DEGRADED, en repuestos distribuidos consumidos y en la tasa de crecimiento de ETA de reconstrucción (buen predictor de “algo anda mal”).
  6. Practica los reemplazos. La primera vez que ejecutes zpool replace no debería ser durante un outage.

Checklist C: Verificación post-recuperación

  1. Ejecuta zpool status -v y confirma que el scan muestra “with 0 errors.”
  2. Asegura que no quede la advertencia de “repuestos distribuidos consumidos” tras el reemplazo físico y la sanación.
  3. Chequea SMART en el disco nuevo y al menos en un disco “vecino”; las fallas suelen agruparse.
  4. Revisa los logs de dmesg desde el incidente por errores de ruta; arregla problemas de transporte antes de que la próxima falla los pruebe otra vez.
  5. Reanuda el scrub si fue pausado, pero hazlo en una ventana tranquila.

Preguntas frecuentes (FAQ)

1) ¿El dRAID elimina la necesidad de discos hot spare?

Reduce la dependencia de un repuesto dedicado único para recuperación inmediata, porque el espacio de repuesto está distribuido.
Aún necesitas un plan de reemplazo físico. Los repuestos distribuidos son un colchón, no un sustituto permanente del hardware de reemplazo.

2) ¿La recuperación dRAID siempre es más rápida que RAIDZ?

A menudo es más rápida en tiempo transcurrido para grandes pools de HDD porque las escrituras de reconstrucción se paralelizan. No siempre es “menos impactante”.
Puedes cambiar de “un disco a tope” a “todos los discos ocupados”, lo cual puede ser peor para cargas sensibles a latencia.

3) ¿Qué significa realmente “repuestos distribuidos consumidos”?

Significa que la reconstrucción usó slices de repuesto reservados dentro del vdev dRAID para reconstituir datos/paridad faltante.
Recuperaste redundancia pero gastaste capacidad de repuesto. Reemplaza el disco fallado para restaurar el margen de repuesto.

4) ¿Puedo mantener un pool indefinidamente con repuestos distribuidos consumidos?

Puedes, de la misma manera que puedes mantener un servidor indefinidamente con un array RAID degradado: hasta que no puedas.
La postura operativa correcta es tratarlo como un riesgo acotado en el tiempo y programar el reemplazo.

5) Si un disco hace flapping, ¿debería ponerlo offline inmediatamente?

Si estás dentro de la tolerancia de paridad y el flapping causa timeouts repetidos, offlining puede reducir el caos y acelerar la recuperación.
Si offlining excedería la tolerancia de paridad, estabiliza la capa de transporte primero y evita forzar un estado peor.

6) ¿Por qué la reconstrucción perjudica el rendimiento aunque sea “distribuida”?

Porque estás haciendo lecturas extra (para reconstruir) y escrituras extra (para almacenar slices reconstruidos), además de cálculos de paridad.
La distribución incrementa el paralelismo; no elimina el trabajo. Solo lo reparte.

7) ¿Debería limitar la recuperación para proteger la latencia de aplicaciones?

Sí, si la capa tiene SLOs de latencia. Restaura redundancia, pero no llevando producción abajo por tail latency.
Limita en horas pico y acelera fuera de pico. La meta es servicio seguro, no solo una ETA bonita.

8) ¿Qué es lo primero que verificar cuando la recuperación es más lenta de lo esperado?

Revisa errores de transporte en logs del kernel y busca un disco único lento en zpool iostat -v.
En la práctica, “ZFS está lento” suele ser “una ruta SAS está enferma” o “un disco está haciendo stalls”.

9) ¿dRAID cambia cómo debo dimensionar la paridad (dRAID1/2/3)?

Cambia la dinámica de recuperación, no las matemáticas básicas de tolerancia a fallos.
Pools grandes con discos grandes se benefician de más paridad porque la probabilidad de un segundo fallo durante la ventana de recuperación no es trivial.

10) ¿Cómo explico el sparing dRAID a la dirección?

“Gastamos algo de capacidad por adelantado para reducir el tiempo que estamos vulnerables tras una falla.”
Si quieren una línea: es un seguro que paga en horas menos de riesgo degradado.

Conclusión: próximos pasos que pagan la renta

Los repuestos distribuidos de dRAID no son un truco de marketing; son una respuesta práctica a realidades modernas de disco.
Pueden reducir la ventana peligrosa después de una falla paralelizando la reconstrucción.
También cambian lo que significa “terminado”: la reconstrucción puede completarse sin un disco de reemplazo, pero sigues operando con margen de repuesto gastado hasta que reemplaces hardware y dejes que el vdev sane.

Tres pasos siguientes que hacen aburrida la recuperación dRAID—en el mejor sentido:

  1. Operativiza la recuperación en dos fases. Trata “repuestos distribuidos consumidos” como un ticket con SLA, no como una nota al pie.
  2. Construye el hábito de diagnóstico rápido. Vista ZFS, luego discos/ruta, luego CPU/memoria, luego tuning. En ese orden.
  3. Practica los reemplazos. El mejor momento para aprender tu mapeo by-id no es a las 3 a.m. con un pool degradado.

Una idea para pegar en un sticky, parafraseada de Gene Kim (autor sobre DevOps/operaciones): paraphrased idea: Mejorar el trabajo diario para que los incidentes sean más raros y las recuperaciones algo rutinario.

← Anterior
El cloud gaming no matará a las GPU (No: he aquí por qué)
Siguiente →
Cuotas ZFS para multiinquilinos: evitar que un usuario deje el pool sin espacio

Deja un comentario