Diseño ZFS: Espejos vs Paridad — El verdadero coste de “más capacidad”

¿Te fue útil?

La petición suele aparecer en un ticket con un asunto alegre: “Necesitamos más espacio.”
El subtexto siempre es el mismo: alguien vio un pool al 78% y decidió que el equipo de almacenamiento es un obstáculo para el progreso.

Si ejecutas ZFS en producción, “más capacidad” no es un cambio neutro. Es una decisión que reconfigura dominios de fallo,
cambia el comportamiento de reconstrucción, desplaza las colas de latencia y altera cómo será tu peor día. Los espejos y la paridad funcionan.
Pero fallan de forma diferente. Y la factura por “más TB utilizables” a menudo se paga en tiempo, no en dinero.

El verdadero intercambio: latencia, reconstrucciones y tiempo humano

Los espejos y la paridad RAIDZ a menudo se presentan como un simple control deslizante: “los espejos son más rápidos, RAIDZ aprovecha mejor el espacio.”
Eso es cierto en el mismo sentido que “el invierno es frío.” No está mal, simplemente omite todo lo que duele.

El intercambio real es: cuánto riesgo y complejidad operativa compras con cada terabyte adicional de espacio utilizable.
Los espejos te compran rendimiento predecible y manejo de fallos más simple. RAIDZ te compra eficiencia de capacidad pero cobra intereses
en comportamiento de resilver, amplificación de escritura por paridad y en el tiempo para volver a dormir cuando un disco cae en horas punta.

Cuando alguien dice “estamos dejando capacidad sobre la mesa con espejos,” tradúcelo como:
“Queremos reducir gasto inicial aumentando la cantidad de trabajo que podríamos tener que hacer después,
bajo estrés, mientras el negocio está observando.”

Regla práctica: si la carga es intensiva en I/O aleatorio (VMs, bases de datos, contenedores mixtos, runners de CI), los espejos son la opción por defecto.
Si la carga es I/O secuencial grande (backups, media, archivo, retención de logs), RAIDZ2 suele ser la opción por defecto.
RAIDZ1 es para quienes disfrutan escribiendo postmortems sobre “fallo inesperado número dos.”

Hechos e historia que explican el dolor actual

  • ZFS nació en Sun (mediados de los 2000) con checksumming de extremo a extremo como respuesta a la corrupción silenciosa de datos, no como una búsqueda de máxima capacidad utilizable.
  • La reputación de RAID5 sufrió cuando los tamaños de disco crecieron más rápido que las velocidades de reconstrucción; ventanas de rebuild largas aumentaron la probabilidad estadística de un segundo fallo en el peor momento.
  • Las tasas de “error de lectura irrecuperable” en discos commodity fueron un problema importante en la era SATA temprana; las reconstrucciones de paridad leen muchos datos, justo cuando aparecen los URE.
  • El “scrub” de ZFS se volvió estándar porque detecta errores latentes de sector antes de que un resilver te obligue a leerlo todo en peores condiciones.
  • Los discos con sector de 4K (y el abandono de los sectores de 512 bytes) hicieron de ashift una elección de diseño permanente: elegir mal y pagas para siempre en amplificación de escritura.
  • Copy-on-write (CoW) significa que ZFS nunca sobrescribe bloques activos en su lugar; genial para integridad, pero cambia la historia de fragmentación y escrituras pequeñas.
  • RAIDZ fue diseñado para ZFS (no pegado después) para evitar el clásico problema del write-hole que tienen los RAID de paridad tradicionales sin un journal fiable.
  • Las características de OpenZFS divergieron entre plataformas durante años; lo que tu colega jura que funcionó en una distro puede comportarse diferente en otra versión.
  • La adopción de SSD desplazó el dolor de “throughput” a “latencia cola”, y los espejos tienden a comportarse mejor cuando te importan p99.9 más que los benchmarks.

Cómo piensa ZFS: vdevs, comportamiento del pool y por qué los diseños no son “solo RAID”

ZFS no hace “RAID across disks” de la forma en que lo hace un controlador hardware. ZFS hace redundancia a nivel de vdev.
Tu pool es una franja (stripe) a través de vdevs. Un vdev es la unidad de fallo.

Esa sola frase explica la mayoría de las sorpresas en producción:

  • Si pierdes un vdev, pierdes el pool. Un pool es tan fiable como su vdev menos fiable.
  • Añadir un vdev aumenta capacidad y rendimiento, pero también añade otro dominio de fallo.
  • No puedes “convertir” un vdev RAIDZ en un vdev espejo más tarde sin migración. (Sí, hay funciones de expansión en evolución, pero planifica como si todavía tuvieras que migrar.)

Espejos y RAIDZ son distintos tipos de vdev. Los espejos replican bloques. RAIDZ codifica paridad a través de una franja.
ZFS reparte asignaciones entre vdevs de primer nivel, así que si mezclas tipos de vdev, mezclas comportamientos. Eso no es “flexibilidad,”
es “tu gráfica de rendimiento parecerá arte moderno.”

Espejos en producción: lo bueno, lo malo y lo predecible

Qué te compran los espejos

Los espejos son aburridos. Esto es un elogio.

Para lecturas aleatorias, los espejos suelen ser excelentes porque ZFS puede atender lecturas desde cualquiera de los lados, y puede ser inteligente con la profundidad de cola.
Para escrituras aleatorias, escribes dos veces—pero el patrón de I/O sigue siendo simple, y el comportamiento ante fallos sigue siendo directo.

El resilver de un espejo tiende a ser más suave, especialmente cuando reemplazas por un disco más grande o cuando el pool no está lleno.
ZFS puede resilverizar solo bloques asignados (secuencial-ish) en lugar de una reconstrucción completa del disco, dependiendo de la plataforma y las flags de función.
Incluso cuando tiene que trabajar duro, los resilvers de espejo suelen ser más sencillos de razonar.

Dónde muerden los espejos

El coste es la eficiencia de capacidad. Un espejo de dos vías es 50% utilizable (antes de slop, metadatos y padding).
Un espejo de tres vías es 33%. Pagas eso todos los días, tenga o no necesidad de rendimiento.

Los espejos también fomentan un tipo específico de exceso de confianza: “Está en espejo, así que está seguro.”
Es más seguro que un solo disco. No es una copia de seguridad. No protege contra “rm -rf”, ransomware o una aplicación
que alegremente escriba basura con checksums válidos.

Paridad RAIDZ en producción: gana capacidad, deuda operativa y cuándo es la opción correcta

Qué te compra RAIDZ

RAIDZ1/2/3 te dan mejor capacidad utilizable por disco. Ese es el titular, y importa.
Para cargas secuenciales grandes, RAIDZ puede ser perfectamente adecuado y a menudo rentable.

RAIDZ2 es la línea base práctica para pools grandes de HDD. La diferencia de coste entre RAIDZ1 y RAIDZ2 es un disco de paridad por vdev.
La diferencia en “qué tan probable es que pierdas el vdev durante el estrés de rebuild” es mayor que esa diferencia.

Dónde muerde la paridad

RAIDZ tiene un problema estructural con escrituras aleatorias pequeñas: la aritmética de paridad más el comportamiento read-modify-write pueden convertir una pequeña escritura lógica
en múltiples operaciones físicas. ZFS puede mitigar parte de esto con elecciones de recordsize, alineación de carga y suficiente CPU,
pero no puedes negociar con la física.

El comportamiento de reconstrucción es donde los layouts de paridad pasan la factura. Un resilver RAIDZ necesita reconstruir datos desde los discos sobrevivientes,
lo que implica leer mucho. Eso puede alargarse días en HDD grandes, y durante esa ventana tu pool está estresado y tu margen es estrecho.

Chiste #1: RAIDZ1 en discos giratorios grandes es como lanzarse en paracaídas con un paracaídas de repuesto que dejaste en el coche. Técnicamente lo posees.

Cálculos de capacidad que no mienten (y las partes que ocultan)

El cálculo de capacidad es la parte más fácil, por eso se abusa de él. La gente hace aritmética rápida y se declara vencedora.
La trampa es que ZFS tiene overheads y comportamientos que hacen que “utilizable” sea distinto de “seguro para operar.”

Bruto vs utilizable vs sensato

  • Capacidad bruta: suma de los tamaños de los discos.
  • Capacidad utilizable: bruto menos redundancia de paridad/espejo, menos realidades de formateo/ashift, menos metadatos de ZFS.
  • Capacidad operativa sensata: utilizable menos el espacio que te niegas a llenar porque el rendimiento y la fragmentación se vuelven desagradables cuando lo haces.

Si ejecutas pools al 90–95% y luego te sorprenden los picos de latencia, no eres desafortunado. Estás simplemente haciendo lo que los causa.
ZFS necesita espacio para encontrar buenos objetivos de asignación; no está solo—la mayoría de sistemas CoW se comportan de forma similar.

Por qué “un gran vdev RAIDZ” seduce

Un vdev RAIDZ ancho se ve genial en una hoja de cálculo: más discos de datos por disco de paridad.
Luego te das cuenta de que un vdev ancho resilveriza leyendo desde más discos, tarda más y cada disco es un punto de fallo durante esa larga ventana.
El coste operativo no es lineal; es más parecido a interés compuesto.

Realidad del rendimiento: IOPS, throughput y latencia cola

Las decisiones de almacenamiento fallan cuando optimizas la métrica equivocada. La gente compra “más TB” cuando necesitaba “menos latencia.”
O compran “más IOPS” cuando necesitaban “más throughput.” Espejos vs paridad es mayormente una historia sobre latencia e IOPS.

IOPS: los espejos suelen ganar donde duele

Un vdev espejo puede atender lecturas desde cualquiera de los discos, por lo que las IOPS de lectura escalan mejor que la paridad para cargas aleatorias.
Las IOPS de escritura en un espejo son aproximadamente como un solo disco (escribes en ambos), pero el comportamiento se mantiene limpio.

Las IOPS de escritura aleatoria en RAIDZ están limitadas por operaciones de paridad y geometría de stripe. Si tienes muchas escrituras pequeñas y síncronas
(bases de datos, NFS para VMs, iSCSI), la paridad puede convertirse en una fábrica de latencia.

Throughput: la paridad puede ser excelente (cuando la carga encaja)

Para lecturas/escrituras secuenciales grandes, RAIDZ puede ofrecer un throughput excelente, especialmente si tu recordsize coincide con la carga
y no estás forzando semánticas síncronas innecesariamente.

Latencia cola: la gráfica que importa cuando los usuarios se quejan

La latencia media hace que los dashboards parezcan tranquilos. La latencia cola hace que los canales de incidentes se pongan ruidosos.
Los espejos tienden a tener menos sorpresas desagradables bajo cargas mixtas porque hay menos reconstrucción por paridad y menos operaciones de “tocar-muchos-discos” obligatorias.
RAIDZ tiende a mostrar colas más pesadas cuando el pool está ocupado, fragmentado o resilverizando.

Cita (idea parafraseada): “La esperanza no es una estrategia.” — General James Mattis (idea parafraseada, citada comúnmente en contextos de ops)

Resilvering y scrubs: donde la teoría se encuentra con el pager

Los scrubs y resilvers no son tareas de fondo. Son los momentos en que tu diseño de redundancia es puesto a prueba bajo carga.
Si tu diseño asume que los scrubs siempre terminarán rápido, o que los resilvers no colisionarán con el tráfico pico, estás diseñando un laboratorio, no un servicio.

Scrub: dolor proactivo para evitar desastres reactivos

Un scrub lee todos los datos y verifica checksums, reparando desde la redundancia cuando es posible. Encuentra errores latentes antes de que una falla de disco obligue
a una reconstrucción que lo lea todo de todas formas, pero en peores condiciones.

Los scrubs cuestan I/O. La respuesta correcta es programarlos y monitorizarlos, no deshabilitarlos porque “impactan el rendimiento.”
Si tu sistema no tolera un scrub, tampoco tolera un resilver; solo que aún no lo ha admitido.

Resilver: donde la redundancia se vuelve cara

El resilver de espejo suele ser una copia mayormente secuencial de bloques asignados al disco de reemplazo. El resilver de RAIDZ reconstruye stripes.
En ambos casos, el pool está haciendo trabajo extra mientras está degradado. Este es exactamente el momento en que no quieres sorpresas.

El mayor riesgo operativo no es “un disco falló.” Los discos fallan. El riesgo es “un disco falló y la ventana de rebuild es lo bastante larga
como para que algo más falle también.” Los espejos y RAIDZ2 reducen ese riesgo de formas diferentes; RAIDZ1 lo aumenta.

Chiste #2: La manera más rápida de aprender que tu estrategia de resilver es inadecuada es llamarla “lo veremos después.” El después es muy puntual.

Tareas prácticas: comandos, salidas y decisiones

Estas son tareas que puedes ejecutar en un host ZFS. Cada una incluye: un comando, qué significa la salida típica y qué decisión tomar.
El hostname y los nombres de pool son ejemplos; adapta con cuidado.

Tarea 1: Identificar el layout del pool y tipos de vdev

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Feb  4 02:10:31 2026
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d4  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d5  ONLINE       0     0     0
          mirror-1                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d6  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d7  ONLINE       0     0     0

errors: No known data errors

Qué significa: Los vdevs de primer nivel son espejos; el pool sobrevivirá a la falla de un disco por vdev espejo.
Los contadores de lectura/escritura/checksum están limpios.

Decisión: Si este pool soporta VMs o bases de datos, probablemente ya estás en la dirección correcta. Si es un pool de archivo,
puede que estés pagando demasiado en capacidad. Decide según la carga, no la ideología.

Tarea 2: Confirmar ashift (alineación de sector) antes de expandir o reemplazar discos

cr0x@server:~$ zdb -C tank | grep -i ashift -n
34:            ashift: 12

Qué significa: ashift=12 significa sectores de 4K. Bueno para discos modernos.

Decisión: Si ves ashift=9 en discos 4K, planifica una migración. No lo “arregles después”; no puedes cambiar ashift en sitio.

Tarea 3: Comprobar espacio libre del pool e indicadores de fragmentación

cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health
NAME   SIZE  ALLOC   FREE  FRAG  HEALTH
tank  21.8T  16.9T  4.90T   28%  ONLINE

Qué significa: 28% de fragmentación no es catastrófico, pero va tendiendo a “la latencia de escritura aleatoria se pondrá picante.”

Decisión: Si planeas superar ~80% de asignación en un pool ocupado, reserva tiempo para pruebas de rendimiento o expansión.
“Todavía tiene TB libres” no es un plan de rendimiento.

Tarea 4: Encontrar los datasets que realmente consumen espacio

cr0x@server:~$ zfs list -o name,used,avail,refer,compressratio,mountpoint -S used | head
NAME                    USED  AVAIL  REFER  RATIO  MOUNTPOINT
tank/vmstore           8.42T  4.10T  8.42T  1.28x  /tank/vmstore
tank/backups           5.10T  4.10T  5.10T  1.01x  /tank/backups
tank/home              1.80T  4.10T  1.70T  1.70x  /tank/home
tank                   512K   4.10T   192K  1.00x  /tank

Qué significa: vmstore domina el uso; la compresión ayuda un poco.

Decisión: Si el mayor consumidor es almacenamiento de VMs, los espejos suelen ser la opción por defecto adecuada. Si son backups, RAIDZ2 puede estar bien.

Tarea 5: Comprobar recordsize y ajustes sync del dataset (puntos dolorosos comunes de paridad)

cr0x@server:~$ zfs get -o name,property,value -r recordsize,sync tank/vmstore | head -n 12
NAME          PROPERTY    VALUE
tank/vmstore  recordsize  128K
tank/vmstore  sync        standard

Qué significa: Recordsize es 128K (más o menos por defecto). Sync es standard (depende del cliente/app).

Decisión: Para bases de datos, considera un recordsize menor (p. ej., 16K) solo cuando entiendas el patrón de I/O.
Para zvols de VM, normalmente ajustas volblocksize en la creación. No cambies estos parámetros al tuntún en un pool de producción.

Tarea 6: Identificar si la compresión está activada (y si ayuda)

cr0x@server:~$ zfs get -o name,property,value,source -r compression tank | head -n 12
NAME           PROPERTY     VALUE     SOURCE
tank           compression  lz4       local
tank/vmstore   compression  lz4       inherited from tank
tank/backups   compression  off       local

Qué significa: El almacén de VMs comprime; los backups no.

Decisión: Si los backups ya están comprimidos (p. ej., archivos cifrados/comprimidos), la compresión no ayudará.
Para datasets de propósito general, lz4 suele ser una ganancia sin coste. Si la CPU está al límite, mide antes de cambiar.

Tarea 7: Ver I/O en tiempo real para saber si estás limitado por IOPS o throughput

cr0x@server:~$ zpool iostat -v tank 2 3
                                            capacity     operations     bandwidth
pool                                      alloc   free   read  write   read  write
----------------------------------------  -----  -----  -----  -----  -----  -----
tank                                      16.9T  4.90T    820   1450   112M   210M
  mirror-0                                8.45T  2.45T    410    720  56.0M   105M
    wwn-0x5000c500a1b2c3d4                    -      -    208    361  28.1M  52.7M
    wwn-0x5000c500a1b2c3d5                    -      -    202    359  27.9M  52.4M
  mirror-1                                8.45T  2.45T    410    730  56.0M   105M
    wwn-0x5000c500a1b2c3d6                    -      -    205    365  28.0M  52.6M
    wwn-0x5000c500a1b2c3d7                    -      -    205    365  28.0M  52.6M
----------------------------------------  -----  -----  -----  -----  -----  -----

Qué significa: Las escrituras son más intensas que las lecturas. El ancho de banda es moderado. Si hay quejas de latencia pese a estos números,
puede ser por escrituras síncronas, encolamiento o un dispositivo lento (o estás alcanzando colas p99).

Decisión: Si estás limitado por IOPS en paridad, los espejos son una solución estructural. Si estás limitado por throughput, añade vdevs o medios más rápidos.

Tarea 8: Comprobar salud del ARC y presión de memoria (el rendimiento de ZFS suele ser “RAM vs disco”)

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  size     c
12:40:01   942   121     12     0    0   121  100     0    0  64.0G  64.0G
12:40:02   910   115     12     0    0   115  100     0    0  64.0G  64.0G
12:40:03   955   118     12     0    0   118  100     0    0  64.0G  64.0G

Qué significa: ~12% de miss en ARC. No es horrible, ni espectacular. Si tu working set no cabe en RAM, el diseño de vdev importa más.

Decisión: Si los misses del ARC son altos y los discos están ocupados, puede que necesites más RAM o almacenamiento más rápido—no solo otro nivel RAID.

Tarea 9: Identificar si estás bloqueado por escrituras síncronas y comportamiento del SLOG

cr0x@server:~$ zpool status tank | sed -n '1,120p'
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Feb  4 02:10:31 2026
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d4  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d5  ONLINE       0     0     0
          mirror-1                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d6  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d7  ONLINE       0     0     0
        logs
          mirror-2                  ONLINE       0     0     0
            nvme0n1p2               ONLINE       0     0     0
            nvme1n1p2               ONLINE       0     0     0

errors: No known data errors

Qué significa: Hay un dispositivo de logs en espejo (SLOG). Eso puede ayudar dramáticamente la latencia de escrituras síncronas para NFS/iSCSI, cuando está bien configurado.

Decisión: Si tienes cargas pesadas síncronas y no hay SLOG, ni los espejos ni RAIDZ te salvarán por sí solos. Añade un SLOG espejado apropiado o cambia las semánticas de sync con conocimiento.

Tarea 10: Verificar estado de resilver/scrub en curso y estimar riesgo operativo

cr0x@server:~$ zpool status tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
  scan: resilver in progress since Tue Feb  4 11:10:51 2026
        3.12T scanned at 1.45G/s, 1.84T issued at 860M/s, 16.9T total
        1.84T resilvered, 10.88% done, 05:12:33 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            wwn-0x5000c500a1b2c3d4  ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              wwn-0x5000c500a1b2c3d5  ONLINE     0     0     0
              wwn-0x5000c500ffff0001  ONLINE     0     0     0  (resilvering)

errors: No known data errors

Qué significa: El pool está degradado durante un resilver. El tiempo restante no es trivial.

Decisión: Congela cambios riesgosos. Si este es un vdev de paridad, trata la ventana como de mayor riesgo; considera limitar la carga o programar mantenimiento.

Tarea 11: Detectar discos que fallan antes de que se vuelvan “repentinos”

cr0x@server:~$ smartctl -a /dev/sda | egrep -i 'reallocated|pending|uncorrect|crc|overall|temperature'
SMART overall-health self-assessment test result: PASSED
Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       8
Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       2
Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       2
UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
Temperature_Celsius     0x0022   034   040   000    Old_age   Always       -       34

Qué significa: Existen sectores pendientes e incorrigibles. “PASSED” no significa “saludable.” Significa “no lo suficiente muerto aún.”

Decisión: Reemplaza el disco. En RAIDZ, hazlo proactivamente para evitar descubrir discos débiles durante un resilver.

Tarea 12: Comprobar si sufres de un disco lento (el asesino silencioso del pool)

cr0x@server:~$ iostat -x 1 3
Linux 6.5.0 (server)  02/04/2026  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.1    0.0     6.4    18.7     0.0    62.8

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
sda              62.0   115.0  8120.0  20120.0   9.2   1.8   31.0
sdb              64.0   117.0  8200.0  19990.0   8.9   1.9   32.0
sdc              12.0    95.0  1100.0  19850.0  44.5   2.1   88.0
sdd              60.0   112.0  8050.0  20010.0   9.1   1.8   30.5

Qué significa: sdc tiene await mucho más alto y alta utilización. Un disco lento puede arrastrar un vdev espejo o un vdev de paridad a mala latencia.

Decisión: Correlaciona sdc con un dispositivo ZFS (by-id/wwn). Revisa SMART, cableado, errores de HBA. Reemplaza o arregla la ruta.

Tarea 13: Ver si tu pool se está auto-limitando por errores

cr0x@server:~$ zpool events -v | tail -n 12
Feb 04 2026 12:11:02.123456789 ereport.fs.zfs.checksum
        pool = tank
        vdev = /dev/disk/by-id/wwn-0x5000c500a1b2c3d6
        errno = 0x0
        ...
Feb 04 2026 12:11:05.987654321 ereport.fs.zfs.io
        pool = tank
        vdev = /dev/disk/by-id/wwn-0x5000c500a1b2c3d6
        errno = 0x5
        ...

Qué significa: Se están reportando errores de checksum y I/O. ZFS puede estar reintentando, reconstruyendo y bloqueando.

Decisión: Trátalo como un problema de ruta de hardware hasta que se demuestre lo contrario: disco, cable, backplane, HBA, firmware. Arregla eso antes de debatir espejos vs paridad.

Tarea 14: Verificar que los scrubs se ejecutan y terminan en una ventana razonable

cr0x@server:~$ zpool status -x
all pools are healthy
cr0x@server:~$ zpool status tank | grep -A2 -i scan
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Feb  4 02:10:31 2026

Qué significa: El scrub se completó en unas horas y no reparó nada. Eso es lo que quieres.

Decisión: Si los scrubs tardan días e impactan la producción, tu pool está demasiado ocupado, demasiado lleno, demasiado ancho o demasiado lento. Los espejos pueden reducir el dolor, pero también lo pueden “más vdevs” y “más margen de I/O.”

Guía de diagnóstico rápido: encuentra el cuello de botella en minutos

Cuando los usuarios dicen “el almacenamiento va lento,” no empieces por rediseñar el pool. Empieza por demostrar qué está lento y por qué.
Aquí está el orden que ahorra tiempo y evita soluciones equivocadas.

Primero: confirma que realmente es el almacenamiento

  • Revisa iowait y CPU steal: iowait alto sugiere almacenamiento; steal alto sugiere vecino ruidoso o presión del hypervisor.
  • Revisa síntomas de la aplicación: ¿están limitados por latencia (timeouts) o por throughput (jobs lentos)?
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 6  2      0  92100  52000 812000    0    0  1200  4800 8200 9000 14  6 60 20  0

Decisión: Si wa está alto y b (procesos bloqueados) es distinto de cero, continúa con las comprobaciones de almacenamiento.

Segundo: identifica si es un dispositivo, un vdev o todo el pool

  • Por disco: iostat -x para detectar outliers en await/%util.
  • Por vdev: zpool iostat -v para detectar desequilibrio y sobrecarga.

Tercero: comprueba señales de salud de ZFS que lo cambian todo

  • Degradado o resilverizando: el rendimiento será peor. Decide si puedes descargar carga.
  • Errores/eventos: errores de checksum/I/O sugieren problemas de hardware que ningún nivel RAID arregla.
  • Espacio libre/fragmentación: alta ocupación + fragmentación = fiesta de latencia cola.

Cuarto: valida la ruta de escrituras síncronas y comportamiento del intent log

  • NFS/iSCSI/DB escrituras síncronas: verifica si fuerzan sync y si existe un SLOG sano y configurado.

Quinto: solo entonces habla de cambios de layout

Si no puedes nombrar el cuello de botella, no propongas espejos vs RAIDZ como la solución. Eso es culto de carga.
Los cambios de layout son costosos, disruptivos y difíciles de revertir. Gánatelos con evidencia.

Tres mini-historias corporativas desde las trincheras del almacenamiento

Mini-historia 1: Incidente causado por una suposición errónea

Una compañía SaaS mediana ejecutaba un pool ZFS que soportaba un clúster de virtualización. El almacenamiento se construyó como un único vdev RAIDZ1 ancho.
La razón era familiar: “Perdemos demasiada capacidad con espejos, y ZFS es más inteligente que RAID de todos modos.”

El primer disco falló un martes por la mañana. No fue gran cosa. Tenían hot spares en estantería y un on-call que ya había hecho esto antes.
El resilver comenzó y el rendimiento bajó—de forma notable, pero tolerable. El equipo supuso que terminaría durante la noche.

La noche se convirtió en “la tarde del día siguiente.” El pool estaba ocupado, el historial de scrubs era irregular y el pool superaba el 85% de ocupación.
Las escrituras aleatorias ya eran un poco feas; ahora la reconstrucción de paridad amplificó la fealdad. La latencia de las VMs subió. Llegaron timeouts en aplicaciones.

Tarde en el segundo día, un segundo disco dio errores de lectura durante el resilver. El vdev no pudo reconstruir unos bloques.
ZFS hizo lo que pudo, pero las imágenes críticas de VM se vieron afectadas. El incidente no fue causado por ZFS siendo poco fiable.
Fue causado por la suposición de que RAIDZ1 se comporta como una póliza de seguro casual, incluso durante ventanas largas de rebuild.

La acción correctiva no fue “usar espejos en todas partes.” Fue más adulta:
RAIDZ2 para vdevs HDD, scrubs regulares con alertas sobre duración, y una política de llenado de pool que trate el 80% como “empieza a planificar,” no como “está bien.”

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

Una empresa de servicios financieros tenía un pool espejo ZFS que soportaba una base de datos sensible a la latencia.
Todo era estable, si algo caro en capacidad bruta. Durante un ciclo de presupuesto, alguien propuso cambiar a RAIDZ2 para “ahorrar discos.”

La migración se planificó con cuidado y se ejecutó bien. El nuevo pool tenía suficientes spindles, redundancia RAIDZ2, y se veía genial en una gráfica de capacidad.
Las pruebas iniciales mostraron throughput aceptable. El equipo declaró la optimización un éxito y siguió adelante.

Luego la carga cambió: más microservicios, más transacciones pequeñas, más escrituras síncronas y un job batch nuevo que hacía muchas actualizaciones pequeñas.
La latencia cola subió. No de forma consistente—solo lo suficiente para provocar consultas lentas y fallos intermitentes para los usuarios.

El equipo persiguió fantasmas: red, parámetros de BD, código de aplicación, actualizaciones del kernel. Eventualmente hicieron lo que debieron hacer al inicio:
medir patrones de I/O. La carga era intensiva en IOPS con pequeñas escrituras síncronas. RAIDZ2 no era “malo,” era inadecuado.

Terminaron añadiendo un SLOG espejado y ajustando algunos settings de datasets, lo que ayudó.
Pero la gran solución fue reintroducir espejos para la capa de base de datos y mantener RAIDZ2 para backups y almacenamiento menos espigado.
La optimización sí ahorró discos. También compró una rotación extra de on-call llena de falta de sueño.

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

Una empresa de medios almacenaba activos de producción y archivos a largo plazo en pools RAIDZ2 ZFS. Nada glamoroso.
El equipo tenía un hábito que parecía excesivamente cauteloso: scrubs mensuales, alertas sobre duración de scrub y conteo de errores,
y una regla de reemplazar cualquier disco con sectores pendientes en una semana.

En un trimestre, un lote de discos empezó a mostrar pequeños pero crecientes conteos de errores de lectura. Nada falló de golpe.
Los pools se mantuvieron ONLINE. La mayoría habría encogido de hombros—al fin y al cabo, los dashboards estaban verdes.

Porque los scrubs eran consistentes y se trackeaban, notaron un patrón: los tiempos de scrub aumentaban y algunos discos eran consistentemente más lentos.
Reemplazaron esos discos durante una ventana de mantenimiento planificada, uno a la vez, manteniendo la carga de resilver manejable.

Dos semanas después, otra empresa en el mismo edificio (mismas condiciones de energía, hardware de generación similar) tuvo un evento de fallos multi-disco
durante una reconstrucción no planificada y perdió un vdev. La empresa de medios no “tuvo suerte.” Tenía higiene operativa.

La práctica no era sexy. No apareció en un informe trimestral. Sí mantuvo el archivo intacto y a los directivos tranquilos,
que es el mayor cumplido que la producción puede ofrecer.

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

Error 1: “Necesitamos más espacio, cambia espejos a RAIDZ”

Síntomas: Pool al 75–85% de ocupación; rendimiento ya esporádicamente irregular; presión de capacidad por crecimiento.

Causa raíz: Tratar el layout como una herramienta de capacidad en lugar de una herramienta de carga de trabajo; ignorar que rediseñar implica migración y riesgo.

Solución: Añade vdevs (del mismo tipo) o añade otro pool para datos fríos. Si debes migrar, hazlo clasificando la carga:
espejos para capas I/O aleatorio, RAIDZ2 para capas secuenciales.

Error 2: RAIDZ1 en HDD grandes para almacenamiento primario

Síntomas: Ventanas de rebuild medidas en días; picos de ansiedad durante resilver; errores irrecuperables ocasionales durante rebuild.

Causa raíz: Un vdev de paridad simple no tolera un segundo fallo/URE durante una reconstrucción larga; un vdev ancho magnifica el estrés de rebuild.

Solución: Usa RAIDZ2 (o espejos) para vdevs HDD grandes. Mantén anchos de vdev razonables. Haz scrubs regularmente para reducir sorpresas por errores latentes.

Error 3: Ejecutar pools demasiado llenos porque “ZFS lo aguanta”

Síntomas: Picos de latencia, operaciones de metadatos lentas, rendimiento de escritura impredecible, tiempos de scrub aumentan.

Causa raíz: El asignador CoW tiene menos buenas opciones; aumenta la fragmentación; sube la contención de metaslabs.

Solución: Mantén margen (a menudo 20% para pools ocupados). Añade capacidad antes del pánico. Considera vdevs especiales para metadatos solo cuando puedas espejarlos y monitorizarlos.

Error 4: Malinterpretar escrituras síncronas y culpar al nivel RAID

Síntomas: Datastore NFS “se cuelga aleatoriamente”; latencia de fsync de la base de datos alta; throughput parece bien pero los usuarios se quejan.

Causa raíz: Escrituras síncronas forzando comportamiento de ZIL; no hay SLOG, o el SLOG es malo/insafe; la paridad amplifica escrituras síncronas pequeñas.

Solución: Añade un SLOG espejado adecuado (SSD/NVMe con protección ante pérdida de energía), verifica semánticas de sync y mide de nuevo. No pongas sync=disabled a menos que aceptes pérdida de datos en un crash.

Error 5: Mezclar tipos de vdev en un mismo pool sin entender la asignación

Síntomas: Algunas cargas son rápidas, otras inexplicablemente lentas; el rendimiento cambia con el llenado del pool.

Causa raíz: ZFS asigna entre vdevs de primer nivel; los vdevs más lentos se convierten en anclas de latencia cola; aparece desequilibrio.

Solución: Mantén pools homogéneos por capa. Si necesitas diferente comportamiento, usa pools separados o vdevs especiales diseñados con intención clara.

Error 6: Tratar SMART “PASSED” como certificado de salud

Síntomas: Errores de checksum intermitentes, comportamiento lento del disco, timeouts raros; “pero SMART dice PASSED.”

Causa raíz: El estado overall de SMART es grueso; pending/uncorrectable son advertencias tempranas; problemas de cable/HBA no siempre cambian SMART.

Solución: Genera alertas sobre atributos significativos (pending, uncorrectable, tendencias de reallocated, errores CRC). Usa zpool events y logs del SO para detectar problemas de ruta.

Listas de comprobación / planes paso a paso

Plan A: Elegir espejos vs RAIDZ (lista de decisión para producción)

  1. Clasifica la carga: IOPS aleatorio pesado (VMs/BD) vs secuencial (backup/archivo) vs mixta.
  2. Define el presupuesto de fallos: rendimiento degradado aceptable, duración de rebuild aceptable y ventana de riesgo aceptable.
  3. Fija un objetivo de llenado operativo: elige un % máximo lleno donde el rendimiento sea predecible.
  4. Decide el nivel de redundancia: espejos (2 vías o 3 vías) vs RAIDZ2/3; evita RAIDZ1 para pools primarios con HDD grandes.
  5. Elige el ancho del vdev: mantenlo razonable; no construyas el vdev más ancho que permita tu chasis solo porque puedes.
  6. Planifica el crecimiento: añade vdevs del mismo tipo; evita mezclar tipos; asegúrate de que bahías y HBAs soporten expansión futura.
  7. Planifica operaciones de rebuild: hot spares, ventanas de mantenimiento, monitorización y procedimiento documentado de reemplazo.
  8. Valida con mediciones: benchmark de I/O representativo (incluyendo escrituras síncronas) antes de comprometerte.

Plan B: Procedimiento de reemplazo de disco (seguro, repetible)

  1. Confirma el dispositivo fallido por ID estable (WWN/by-id), no por /dev/sdX.
  2. Revisa zpool status y asegúrate de entender qué vdev está afectado.
  3. Si es posible, pon el disco offline limpiamente antes de retirarlo.
  4. Reemplaza el disco físicamente.
  5. Usa zpool replace con la ruta by-id.
  6. Monitorea el progreso del resilver y la latencia del sistema.
  7. Tras la finalización, ejecuta un scrub en la próxima ventana segura si tu política lo permite.
cr0x@server:~$ zpool offline tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d5
cr0x@server:~$ zpool replace tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d5 /dev/disk/by-id/wwn-0x5000c500ffff0001
cr0x@server:~$ zpool status tank | grep -A4 -i resilver
  scan: resilver in progress since Tue Feb  4 11:10:51 2026
        1.84T resilvered, 10.88% done, 05:12:33 to go

Decisión: Si el pool es de paridad y crítico para el negocio, considera reducir temporalmente la carga o reprogramar jobs batch durante el resilver.
Para espejos, vigila el disco hermano: ahora está haciendo todas las lecturas.

Plan C: Si debes perseguir capacidad, hazlo sin arruinar la fiabilidad

  1. Mueve datasets fríos (backups, archivos) a un pool separado RAIDZ2 diseñado para esa función.
  2. Mantén datasets calientes (VMs/BD) en espejos.
  3. Usa cuotas/reservas para evitar que los backups consuman el pool de VMs.
  4. Habilita compresión donde es probable que ayude (a menudo lz4), pero no esperes milagros en datos ya comprimidos.
  5. Configura alertas al 70/80/85% de llenado del pool con acciones explícitas en cada etapa.
cr0x@server:~$ zfs set quota=6T tank/backups
cr0x@server:~$ zfs get -o name,property,value quota tank/backups
NAME          PROPERTY  VALUE
tank/backups  quota     6T

Decisión: Si los backups se están comiendo el pool, constrénelos. Si los equipos de producto quieren más espacio, hazles elegir: más discos o menos retención.

Preguntas frecuentes

1) ¿Los espejos siempre son más rápidos que RAIDZ?

Para cargas de lectura aleatoria intensiva, usualmente sí. Para throughput secuencial grande, RAIDZ puede ser competitivo o mejor por dólar.
“Siempre” es la palabra que arruina el diseño de almacenamiento.

2) ¿RAIDZ2 es “suficientemente seguro” para pools grandes de HDD?

RAIDZ2 es la línea base común porque tolera dos fallos por vdev. “Suficientemente seguro” depende del tiempo de rebuild, calidad de discos,
higiene de scrubs y cuán cerca al lleno operas. Pero RAIDZ2 es mucho menos estresante que RAIDZ1 durante ventanas de reconstrucción.

3) ¿Por qué se desaconseja RAIDZ1 en discos grandes?

Porque las ventanas de reconstrucción son largas y las reconstrucciones por paridad leen muchos datos. Ahí es cuando aparecen errores latentes o un segundo fallo.
RAIDZ1 no te da margen para eso.

4) ¿Puedo añadir un solo disco después a un vdev RAIDZ?

Históricamente, no—añades vdevs completos, no discos sueltos. OpenZFS más reciente tiene capacidades de expansión RAIDZ en algunos entornos,
pero deberías planificar como si aún expandieras añadiendo vdevs o migrando, porque la disponibilidad de la función y la madurez operativa varían.

5) ¿Debería usar un vdev RAIDZ2 muy ancho o varios más estrechos?

Múltiples vdevs suelen dar mejor paralelismo y rendimiento más predecible. Un vdev muy ancho puede parecer eficiente,
pero aumenta el estrés de rebuild y puede crear latencia cola larga bajo I/O mixto.

6) ¿Los espejos desperdician demasiada capacidad?

Solo desperdician capacidad si no necesitas lo que compran: latencia predecible y comportamiento degradado más simple.
Si tu carga es intensiva en I/O aleatorio, los espejos a menudo son más baratos que el tiempo de ingeniería que gastarás tratando de domar la paridad.

7) ¿Es obligatorio un SLOG?

No. Solo es necesario si tienes escrituras síncronas significativas y te importa la latencia.
Si añades uno, espejalo y usa un dispositivo con protección ante pérdida de energía, o estarás convirtiendo una característica de rendimiento en un riesgo de fiabilidad.

8) ¿Cuánto lleno es demasiado para un pool ZFS?

Depende de la carga, pero los pools ocupados suelen volverse desagradables por encima de ~80–85%. Si ejecutas servicios sensibles a la latencia,
trata el 80% como umbral de planificación, no como meta final.

9) ¿Valen la pena los espejos de 3 vías?

A veces: requisitos de muy alta disponibilidad, logística de reemplazo muy lenta, o cuando el riesgo de resilver debe minimizarse.
Pero son caros en capacidad. RAIDZ3 también puede ser una opción para ciertas capas archivísticas grandes.

10) Si estoy limitado por rendimiento, ¿debería cambiar el nivel RAID o añadir vdevs?

Añade vdevs cuando necesites más paralelismo y throughput/IOPS. Cambia el layout cuando el vdev actual esté estructuralmente desajustado
(p. ej., paridad para escrituras pequeñas síncronas). Si puedes solucionarlo añadiendo vdevs del mismo tipo, eso suele ser menos disruptivo.

Conclusión: pasos prácticos siguientes

Espejos vs paridad no es un debate moral. Es una apuesta de producción: qué tipo de mal día estás dispuesto a tener,
y cuánto tiempo estás dispuesto a que dure.

Pasos siguientes que realmente te moverán hacia adelante:

  1. Mide tu carga: usa zpool iostat -v, métricas de latencia y comportamiento de la aplicación. Decide según el patrón de I/O.
  2. Establece políticas: programa de scrubs, umbrales de reemplazo de discos y límites de llenado del pool con alertas y responsables.
  3. Elige el aburrido por defecto: espejos para capas VM/BD; RAIDZ2 para backups/archivo. Desvíate solo con evidencia.
  4. Diseña para reconstrucciones: asume que un disco fallará durante una semana ocupada. Si eso te hace sudar, tu layout está mal.
  5. Mantén pools homogéneos por capa: evita mezclar tipos de vdev a menos que puedas explicar exactamente cómo se comportará al 85% lleno durante un resilver.
← Anterior
Por qué el ventilador de tu portátil suena mucho después de una actualización (normalmente es un controlador)
Siguiente →
Perfiles de PowerShell: Haz que cada sesión sea inmediatamente útil

Deja un comentario