Planificación de capacidad ZFS: diseñar para el crecimiento sin reconstruir

¿Te fue útil?

La interrupción de almacenamiento que recuerdas no fue la de los mensajes de registro aterradores. Fue la silenciosa: el pool alcanzó el 95%,
la latencia se disparó, las aplicaciones hicieron timeout y todos aprendieron que “espacio libre” no es un número: es un rango con bordes afilados.

La planificación de capacidad en ZFS tiene menos que ver con aritmética y más con evitar esquinas de diseño irreversibles. Puedes arreglar muchos
pecados más adelante. No puedes deshacer el diseño de un vdev sin reconstruir el pool. Así que planifica el crecimiento como si realmente fueses a crecer.

Qué significa realmente “planificación de capacidad” en ZFS

En el mundo tradicional del controlador RAID, la planificación de capacidad es mayormente “¿cuántos discos necesitamos?” y “¿cuándo compramos más?” En ZFS, la planificación de capacidad también incluye:

  • Irreversibilidad del diseño: el ancho y la redundancia de los vdevs son el esqueleto. Cambiarlos después suele requerir reconstrucción.
  • Acoplamiento con el rendimiento: espacio, IOPS y latencia están ligados por el espacio libre, la fragmentación y las metaslabs.
  • Márgenes de seguridad operativa: tiempo de resilver, riesgo de URE, ventanas de scrub y retención de snapshots son temas de capacidad.
  • Dominios de falla: “más espacio” puede significar silenciosamente “mayor radio de impacto”.

La planificación de capacidad es por tanto un problema de diseño de sistemas. Es elegir restricciones con las que puedas convivir durante años, no trimestres.
Tu yo futuro te juzgará por dos cosas: si la expansión fue aburrida y si las interrupciones fueron raras.

Hechos y contexto que cambian las decisiones

Algunos puntos concretos —algunos históricos, otros prácticos— que tienden a corregir los modelos mentales de la gente:

  1. ZFS se creó en Sun para evitar la “corrupción silenciosa de datos”, no solo para agrupar discos. Checksums de extremo a extremo y autocuración son fundamentales.
  2. Copy-on-write (CoW) es la razón por la que las “pools llenas” se ponen feas: necesitas espacio libre para escribir nuevos bloques antes de liberar los antiguos.
  3. Los primeros despliegues de ZFS eran alérgicos al RAID por hardware porque ocultar errores de disco rompía el modelo checksum+reparación. Eso sigue siendo cierto: ZFS quiere visibilidad directa del disco.
  4. RAIDZ se diseñó para evitar el write hole que puede afectar a RAID5/6; ZFS mantiene la consistencia mediante transacciones y CoW.
  5. “Ashift” se volvió una historia de guerra cuando llegaron los sectores 4K y la gente se quedó con alineación de 512 bytes. No puedes cambiar ashift después sin reconstruir.
  6. La capacidad de los discos creció más rápido que la velocidad de reconstrucción. El tiempo de resilver es ahora una entrada de planificación, no un detalle post-mortem.
  7. ZFS tiene “slop space” (un margen reservado) precisamente porque los administradores son optimistas y las aplicaciones son despiadadas.
  8. Los snapshots son baratos hasta que dejan de serlo: cuestan espacio solo cuando los bloques divergen, pero las políticas de retención pueden convertir un “ups” en “sin espacio”.
  9. Los vdevs especiales (metadatos/clase) cambiaron la economía del rendimiento al permitir comprar espacio rápido para metadata en lugar de para todo.

Una idea para tener en la pared, parafraseada y atribuida a John Allspaw: La fiabilidad es una característica que construyes en los sistemas, no un estado que declaras después del lanzamiento.
La planificación de capacidad es ingeniería de fiabilidad con una calculadora y la humildad de dejar holgura.

Modela el crecimiento primero: cargas, amplificación de escritura y tiempo

Empieza por el “qué”, no por los discos

Antes de elegir anchos de RAIDZ o conteo de mirrors, decide qué vas a almacenar y cómo se comporta:

  • Perfil de tamaño de bloque: bases de datos e imágenes VM generan escrituras pequeñas y aleatorias; archivos multimedia hacen escrituras grandes y secuenciales.
  • Tasa de churn: con qué frecuencia se reescribe la información importa más que su tamaño. CoW significa que el churn crea fragmentación.
  • Retención y ciclo de vida: snapshots, backups y retenciones legales pueden duplicar el espacio “efectivo” usado.
  • SLOs de rendimiento: objetivos de latencia p95 y presupuestos de tiempo de resilver deben impulsar la redundancia y el conteo de vdevs.

Piensa en “usable ahora” vs “usable después”

Compras ama los TB crudos. Operaciones vive en TB utilizables con latencia aceptable. Querrás dos números en tu plan:

  • Usable día 0: lo que puedes asignar con seguridad en el primer día manteniendo los objetivos de holgura.
  • Usable día N: lo que puedes alcanzar añadiendo vdevs, expandiendo discos o ambos, sin volver a crear el pool.

La amplificación de escritura no es solo para SSD

ZFS amplifica escrituras de formas que importan para la capacidad:

  • Sobrecoste de paridad (RAIDZ): las escrituras pequeñas y aleatorias pueden convertirse en patrones read-modify-write si recordsize y la carga no coinciden.
  • Crecimiento de metadata: muchos archivos pequeños, ACLs, xattrs y snapshots inflan la metadata.
  • Copias y replicación: copies=2, destinos de send/receive y staging de backups duplican el conteo rápidamente.

Planifica con un factor de seguridad. Si no conoces el churn, asume que es alto. Si no conoces la retención, asume que alguien pedirá “mantenerlo más tiempo” dos semanas después de alcanzar el 85% de utilización.

Broma #1: Lo único que crece más rápido que los datos es el número de equipos que aseguran que “apenas escriben nada.” Es adorable.

Opciones de vdev que determinan tu futuro

Mirrors: la opción aburrida que gana más veces de las que pierde

Los mirrors son caros en capacidad y operativamente indulgentes. Ellos:

  • Escalan IOPS añadiendo más vdevs mirror (cada vdev mirror añade más cabezas independientes).
  • Resilverizan más rápido, porque solo se copian bloques asignados y hay menos matemáticas de paridad y menos coordinación entre discos.
  • Manejan mejor situaciones de “un disco está raro”. La varianza de latencia es menor porque las lecturas pueden venir de cualquiera de los lados.

Si tu carga es intensiva en I/O aleatorio (VMs, bases de datos, contenedores mixtos), los mirrors suelen ser la respuesta correcta a menos que
el costo en capacidad sea lo único que la organización quiera oír.

RAIDZ: eficiente en capacidad, pero el ancho es un compromiso a largo plazo

RAIDZ (paridad simple, doble, triple) intercambia IOPS y características de resilver por espacio utilizable. Puede ser fantástico para
cargas orientadas a throughput o mayormente secuenciales. Pero la captura clave de planificación es el ancho del vdev.

Históricamente, no podías expandir un vdev RAIDZ añadiendo discos; expandías añadiendo un vdev completo. OpenZFS moderno tiene soporte para
expansión RAIDZ, pero la disponibilidad y madurez dependen de la plataforma y la versión, y aún debes considerar la complejidad operativa y
el rendimiento durante el reshape. Trátalo como “posible” no como “inevitable.” Si tu plataforma no lo soporta, planifica como si no existiera.

Nivel RAIDZ: no seas tacaño con paridad en discos grandes

Los discos grandes cambiaron las matemáticas. Las ventanas de reconstrucción son más largas, y la probabilidad de una segunda falla durante el resilver no es teórica.
RAIDZ1 todavía se usa, pero debería reservarse para casos donde:

  • Puedes tolerar un riesgo mayor,
  • Los rebuilds son rápidos (discos pequeños, baja utilización),
  • Y tienes excelentes backups y recuperación probada.

Para “almacenamiento empresarial”, RAIDZ2 es la recomendación por defecto. RAIDZ3 es justificable para vdevs muy anchos, discos muy grandes
o entornos donde la correlación de fallos de discos es algo que ya has visto.

Cantidad de vdevs: la capacidad se agrupa, el rendimiento no

ZFS stripea a través de vdevs, no a través de discos individuales como podría hacer un controlador RAID. Un pool con un vdev RAIDZ ancho
sigue siendo un vdev. Tiene la concurrencia de un solo vdev para muchas operaciones. Añade vdevs para añadir paralelismo.

Por eso “un RAIDZ2 de 12 discos” y “dos RAIDZ2 de 6 discos” pueden sentirse radicalmente diferentes bajo carga. La segunda opción tiene dos
vdevs, más concurrencia y a menudo mejor latencia en la cola alta. La primera tiene un único dominio de fallo y un solo sobre de rendimiento.
Tu monitorización te dirá qué construiste.

Ashift y alineación de sectores: el tatuaje que te queda para siempre

Elige ashift=12 (sectores de 4K) como base a menos que tengas una razón muy específica para no hacerlo. Muchos discos “512e”
mienten educadamente. Un ashift incorrecto puede costarte rendimiento y espacio para siempre.

Reglas de espacio de reserva: por qué 80% no es una superstición

ZFS necesita espacio libre para mantenerse rápido y seguro

La antigua recomendación de “no superar el 80%” perdura porque funciona. A medida que los pools se llenan:

  • La asignación se vuelve más difícil; ZFS tiene menos extensiones libres grandes para elegir.
  • La fragmentación aumenta; las escrituras secuenciales dejan de serlo.
  • Copy-on-write requiere más espacio temporal, así que metadata y reescrituras de bloques se encarecen.
  • Resilver y scrub se vuelven más lentos porque hay más datos y menos holgura de I/O.

Trata “80%” como un disparador por defecto para planificar, no para entrar en pánico. “90%” es donde empiezas a cancelar reuniones.

Slop space: el margen que olvidas hasta que te salva

ZFS reserva algo de espacio (el “slop”) para evitar comportamientos catastróficos de pools llenos. No está ahí por tu conveniencia; está
para mantener el pool funcionando cuando los humanos hacen cosas humanas. Los planes de capacidad deben asumir que el slop es intocable.

Estrategia de cuotas y reservas es parte de la planificación

Las cuotas y reservas no son “política de sistema de archivos.” Son guardarraíles que evitan que un dataset devore el pool y convierta
a todas las demás cargas en víctimas.

  • Usa cuotas para limitar el radio de impacto.
  • Usa reservas (y refreservation) solo cuando necesites garantizar espacio para datasets críticos.
  • Prefiere cuotas por proyecto en entornos con muchos subárboles y cambios frecuentes de equipos.

Snapshots, clones y retención: el impuesto de capacidad silencioso

Los snapshots no son gratis; son facturación aplazada

Los snapshots preservan bloques antiguos. Cuanto más cambian tus datos, más snapshots fijan espacio. Para imágenes VM y bases de datos con
churn constante, los snapshots pueden convertirse en una segunda copia con el tiempo. La trampa es que el pool parece estar bien… hasta que
borras datos y nada se libera porque los snapshots todavía los referencian.

La retención debe ser explícita y aplicada

“Mantener snapshots diarios por 30 días” suena inocuo hasta que tienes 50 datasets y 10 equipos y uno de ellos decide hacer snapshots cada 5 minutos.
Necesitas:

  • un esquema de nombres,
  • una política de retención por clase de dataset,
  • y poda automatizada que se trate como crítica para producción.

Clones: convenientes, pero enredan la contabilidad

Los clones comparten bloques. Ese es el punto. También significa que “usado” se convierte en una pregunta con múltiples respuestas (usado lógico, referenciado,
escrito, uso por snapshots). Si no entrenas a la gente en esto, alguien borrará el “original” y se confundirá por qué no se liberó espacio, o borrará
el “clone” y se sorprenderá por lo que desaparece.

Vdev especiales, SLOG, L2ARC: capacidad y dominios de fallo

Vdevs especiales: la palanca de rendimiento que también puede inutilizar tu pool

Las clases de asignación especiales pueden almacenar metadata (y opcionalmente bloques pequeños) en dispositivos rápidos. Bien hecho, hacen que los pools HDD
se sientan menos como 2009. Mal hecho, crean un nuevo dominio de fallo que puede dejar caer todo el pool.

Reglas que te mantienen empleado:

  • Haz mirrors de los vdevs especiales. Trátalos como metadata crítica (porque lo son).
  • Dimensiona pensando en el crecimiento. Si se llenan, el rendimiento cae y el comportamiento de asignación cambia.
  • Monitorea el uso especial por separado. Es fácil pasarlo por alto hasta que es demasiado tarde.

SLOG: no es una caché de escritura, y no es para la mayoría

Un dispositivo de registro separado (SLOG) solo ayuda a escrituras síncronas. Si tu carga es mayormente asíncrona, un SLOG es un placebo elegante.
Si tu carga es síncrona y sensible a la latencia (NFS para VMs, bases de datos con fsync), un buen SLOG puede estabilizar la latencia en cola alta.

Relación con la planificación de capacidad: el tamaño del SLOG suele ser pequeño, pero la resistencia del dispositivo, la protección ante pérdida de energía y el mirroring importan.
Un dispositivo SLOG muerto en una configuración equivocada es una forma rápida de aprender cómo son las “escrituras síncronas colgadas.”

L2ARC: caché de lectura que puede robar memoria y decepcionarte

L2ARC no es “añade SSD, obtén velocidad.” Es “añade SSD, luego paga el coste de metadata en RAM.” Planifica RAM antes de planificar L2ARC. Si tu ARC
ya está bajo presión, L2ARC puede empeorar las cosas aumentando la churn de expulsiones.

Broma #2: L2ARC es como una membresía de gimnasio: comprarla se siente productivo, pero los resultados dependen de lo que realmente hagas.

Rutas de expansión sin reconstrucción (y lo que aún obliga a reconstruir)

Método de expansión #1: añadir vdevs (el clásico)

Añadir un nuevo vdev es la ruta de crecimiento más establecida. Preserva la geometría de los vdevs existentes y aumenta el rendimiento añadiendo
más paralelismo. También incrementa el número de dominios de falla: más discos significa más fallos a lo largo del tiempo, así que la política
de redundancia y la monitorización importan.

Implicación de planificación: diseña vdevs iniciales para que los vdevs futuros puedan igualarlos. Mezclar tamaños y perfiles de rendimiento muy diferentes
puede causar asignación desigual y comportamiento impredecible.

Método de expansión #2: reemplazar discos por discos más grandes (crecer in situ)

Reemplazar cada disco en un vdev por uno más grande y dejar que ZFS expanda es común para mirrors y RAIDZ. Funciona, pero:

  • Es lento: resilverizas cada disco, uno a la vez.
  • Es arriesgado si tu vdev ya está estresado o altamente utilizado.
  • Sólo obtienes el nuevo espacio después de reemplazar el último disco (en RAIDZ).

Implicación de planificación: si vas a crecer in situ, asegúrate de que tus ventanas de resilver y la estrategia de repuestos sean realistas. “Simplemente reemplazaremos discos el fin de semana” es cómo terminas reconstruyendo un martes.

Método de expansión #3: expansión RAIDZ (cuando está soportada)

Si tu plataforma soporta la expansión de vdev RAIDZ, trátala como una herramienta, no como una estrategia. Puede ser útil para crecimiento incremental
cuando añadir vdevs completos no es factible. Pero aún debes preguntar:

  • ¿Cuál es el impacto en rendimiento durante el reshape?
  • ¿Cómo interactúa con tu calendario de scrub?
  • ¿Cuál es la historia de rollback si algo sale mal?
  • ¿Coincide tu monitorización y madurez operativa con esa complejidad?

Qué suele forzar una reconstrucción de todos modos

Algunas decisiones son difíciles de deshacer:

  • Ashift incorrecto (alineación del tamaño de sector).
  • Mala geometría de vdev para la carga (p. ej., un RAIDZ enorme para cargas I/O aleatorias intensas).
  • Cambiar la política de redundancia (p. ej., pasar de RAIDZ1 a RAIDZ2 sin rutas de conversión soportadas).
  • Estrategia de vdev especial fundamentalmente equivocada (dispositivos de metadata subdimensionados o no espejados).
  • Errores con dedup que requieren rediseño para recuperar rendimiento y sensatez en capacidad.

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

Esta es la parte que puedes copiar en un runbook de ops. Cada tarea incluye: comando, qué significa la salida y la decisión que impulsa.
Los comandos asumen OpenZFS en Linux; adapta los nombres de dispositivos a tu plataforma.

Tarea 1: obtener la capacidad real y la salud del pool

cr0x@server:~$ zpool list -o name,size,alloc,free,capacity,health
NAME   SIZE   ALLOC   FREE  CAPACITY  HEALTH
tank  109T   71.2T  37.8T       65%  ONLINE

Significado: “capacity” es la utilización a nivel de pool. No incluye el crecimiento futuro por snapshots ni las reservas de datasets.

Decisión: Si la capacidad tiende al 80%, empieza a planificar la expansión; si supera el 85%, empieza a ejecutarla.

Tarea 2: ver el layout de vdev (la vista de “arrepentimientos futuros”)

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 12:41:03 with 0 errors on Sun Dec 22 03:10:32 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            ata-WDC_WD140EDGZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDGZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDGZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDGZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDGZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDGZ-...   ONLINE       0     0     0

errors: No known data errors

Significado: Tienes un vdev RAIDZ2. Un vdev significa concurrencia limitada comparada con múltiples vdevs.

Decisión: Si necesitas más IOPS, planea añadir otro vdev en lugar de ampliar este.

Tarea 3: confirmar ashift (alineación) antes de comprar más discos

cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_tree' -n | head
37:        vdev_tree:
58:            ashift: 12
59:            asize:  14000519643136

Significado: ashift: 12 indica alineación a 4K. Buen valor por defecto para discos modernos.

Decisión: Si ashift es 9 en discos 4K, considera planificar una reconstrucción o migración antes que seguir acumulando el error.

Tarea 4: identificar los datasets principales por espacio (incluyendo snapshots)

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -S used | head -n 12
NAME                 USED  AVAIL  REFER  MOUNTPOINT
tank/vm              28.1T  38.0T  6.2T   /tank/vm
tank/backups         17.4T  38.0T  1.1T   /tank/backups
tank/home            8.6T   38.0T  8.2T   /tank/home
tank                 71.2T  38.0T  216K   /tank

Significado: USED incluye uso por snapshots. REFER es la data referenciada en vivo.

Decisión: Si USED es mucho mayor que REFER, los snapshots están fijando espacio; atiende la retención antes de comprar discos.

Tarea 5: cuantificar el consumo por snapshots

cr0x@server:~$ zfs list -t snapshot -o name,used,refer,creation -S used | head -n 8
NAME                              USED  REFER  CREATION
tank/vm@auto-2025-12-25-1200       1.2T  6.1T   Thu Dec 25 12:00 2025
tank/vm@auto-2025-12-24-1200       1.1T  5.9T   Wed Dec 24 12:00 2025
tank/backups@daily-2025-12-25      640G  1.1T   Thu Dec 25 01:00 2025
tank/vm@auto-2025-12-23-1200       980G  5.7T   Tue Dec 23 12:00 2025

Significado: El USED del snapshot es el espacio retenido de forma exclusiva por ese snapshot (estimado por ZFS).

Decisión: Si unos pocos snapshots dominan, poda o ajusta el horario; si todos son grandes, el churn es alto—planifica más holgura.

Tarea 6: comprobar reservas y refreservations (el “espacio faltante” oculto)

cr0x@server:~$ zfs get -r -H -o name,property,value reservation,refreservation tank | egrep -v '\t0$' | head
tank/db	reservation	2T
tank/vm	refreservation	5T

Significado: Las reservas consumen espacio incluso si el dataset está vacío; refreservation se ata al espacio referenciado, normalmente usado con volúmenes.

Decisión: Si el pool está ajustado, cuestiona las reservas: mantenlas solo para cargas que realmente necesitan espacio garantizado.

Tarea 7: inspeccionar la eficacia de la compresión (multiplicador de capacidad o decepción)

cr0x@server:~$ zfs get -o name,property,value -s local,received compression,compressratio tank | head -n 12
NAME        PROPERTY       VALUE
tank/home   compression    zstd
tank/home   compressratio  1.62x
tank/vm     compression    zstd
tank/vm     compressratio  1.08x
tank/db     compression    zstd
tank/db     compressratio  1.01x

Significado: compressratio muestra el ahorro real. Los datos de VM y BD a menudo se comprimen poco.

Decisión: Si tu plan asume ahorros por compresión, verifica la realidad. No presupuestes terabytes imaginarios.

Tarea 8: comprobar la alineación recordsize/volblocksize (rendimiento y comportamiento de espacio)

cr0x@server:~$ zfs get -o name,property,value recordsize tank/home tank/backups
NAME         PROPERTY    VALUE
tank/home    recordsize  128K
tank/backups recordsize  1M

Significado: Un recordsize grande mejora el throughput para cargas secuenciales grandes; puede perjudicar escrituras pequeñas y aleatorias.

Decisión: Ajusta recordsize por clase de dataset. No ejecutes imágenes VM con recordsize de 1M salvo que disfrutes de gráficos de latencia.

Tarea 9: comprobar ajustes de sync (y si estás enmascarando un problema)

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

Significado: standard respeta la semántica de sync de las aplicaciones. disabled es una apuesta por pérdida de datos.

Decisión: Si alguien puso sync=disabled para “arreglar rendimiento”, reviértelo y diseña un SLOG adecuado o aísla la carga.

Tarea 10: medir fragmentación y presión de asignación

cr0x@server:~$ zpool list -o name,capacity,fragmentation,free,allocated
NAME  CAPACITY  FRAG  FREE   ALLOCATED
tank      65%    29%  37.8T      71.2T

Significado: La fragmentación no siempre es mala, pero alta FRAG + alta capacidad suele correlacionar con picos de latencia.

Decisión: Si FRAG sube y estás por encima del ~80% de capacidad, prioriza añadir espacio (nuevo vdev) sobre micro-optimización.

Tarea 11: vigilar latencia de I/O por vdev (encuentra el limitador real)

cr0x@server:~$ zpool iostat -v tank 5 3
                                            capacity     operations     bandwidth
pool                                        alloc   free   read  write   read  write
------------------------------------------  -----  -----  -----  -----  -----  -----
tank                                         71.2T  37.8T    820  1.40K  92.1M  141M
  raidz2-0                                   71.2T  37.8T    820  1.40K  92.1M  141M
    ata-WDC_WD140EDGZ-...                        -      -    140    240  15.3M  25.0M
    ata-WDC_WD140EDGZ-...                        -      -    135    230  15.0M  24.6M
    ata-WDC_WD140EDGZ-...                        -      -    138    235  15.2M  24.8M
------------------------------------------  -----  -----  -----  -----  -----  -----

Significado: Un vdev soporta toda la carga. Si el ancho de banda está bien pero la latencia es mala, probablemente estás limitado por IOPS.

Decisión: Añade vdevs para concurrencia; no esperes que la configuración invente nuevos platos giratorios.

Tarea 12: confirmar el comportamiento de scrub y la tendencia de errores

cr0x@server:~$ zpool status tank | sed -n '1,12p'
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 12:41:03 with 0 errors on Sun Dec 22 03:10:32 2025
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          raidz2-0  ONLINE       0     0     0

Significado: Los scrubs son tu sistema de alerta temprana. Tiempos largos de scrub pueden indicar crecimiento de tamaño, contención o discos débiles.

Decisión: Si el tiempo de scrub aumenta, planifica ventanas de mantenimiento más grandes o más vdevs; también revisa la salud de discos.

Tarea 13: comprobar indicadores SMART por disco (predecir la próxima falla, no la pasada)

cr0x@server:~$ sudo smartctl -a /dev/sdb | egrep 'SMART overall-health|Reallocated_Sector_Ct|Current_Pending_Sector|Offline_Uncorrectable'
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      -       1

Significado: Sectores pendientes e incorrigibles son una señal de “este disco está negociando con la realidad”.

Decisión: Reemplaza proactivamente discos con contadores pendientes/incorrigibles en crecimiento, especialmente antes de un ciclo de expansión/resilver planificado.

Tarea 14: validar uso de vdev especial (si existe)

cr0x@server:~$ zpool list -v tank
NAME         SIZE   ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH
tank         109T   71.2T  37.8T        -         -    29%    65%  1.00x  ONLINE
  raidz2-0   109T   71.2T  37.8T        -         -    29%    65%
special         -      -      -        -         -      -      -

Significado: Si tienes una clase special, debes monitorizarla como un pool dentro del pool (asignación, errores, desgaste).

Decisión: Si los dispositivos especiales se acercan a alta utilización, expándelos (con cuidado) antes de que la presión de metadata afecte al rendimiento.

Tarea 15: ver qué está escribiendo ahora mismo (vincula capacidad con ofensores)

cr0x@server:~$ sudo arcstat 5 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:00:05  2.1K   320     13   120    5    40    2   160    7  98.4G  110G
12:00:10  2.3K   410     15   180    6    50    2   180    7  98.1G  110G
12:00:15  2.2K   360     14   140    6    45    2   175    7  98.2G  110G

Significado: Altas tasas de miss implican más lecturas desde disco; si va unido a un pool casi lleno, la latencia se dispara.

Decisión: Si ARC está subdimensionado para el working set, planifica ampliaciones de RAM antes de culpar a los discos. Los planes de capacidad deben incluir RAM para cache.

Guion rápido de diagnóstico

Cuando alguien dice “el almacenamiento está lento” no tienes tiempo para debates filosóficos sobre CoW. Necesitas una secuencia de triaje
que encuentre el cuello de botella rápidamente y apunte a la siguiente acción.

Primero: ¿te quedaste sin espacio (o efectivamente sin espacio)?

  • Ejecuta zpool list y mira CAPACITY y FREE.
  • Ejecuta zfs list y busca datasets cuyo USED incluya uso masivo por snapshots.
  • Comprueba reservas/refreservations que “ocultan” espacio libre.

Si la utilización del pool es alta (especialmente >85%), trátalo como la causa probable de picos de latencia hasta que se demuestre lo contrario.
La solución suele ser “añadir espacio” o “borrar snapshots”, no tunear el kernel.

Segundo: ¿es IOPS/latencia, ancho de banda o CPU?

  • zpool iostat -v 5 para ver si la carga se concentra en un vdev y si los discos están saturados.
  • Nivel sistema: iostat -x 5 y vmstat 5 para ver profundidades de cola, await y saturación/steal de CPU.
  • Si RAIDZ y escrituras pequeñas intensas: comprueba uso de CPU y carga de interrupciones; el trabajo de paridad no es gratis.

Tercero: ¿estás en modo mantenimiento o de fallo?

  • zpool status para resilver/scrub en progreso, errores o dispositivos lentos.
  • Checks SMART en discos con sectores pendientes.
  • Revisa cambios recientes de configuración: compresión, sync, recordsize, propiedades de vdev especial.

Cuarto: ¿el ARC está bajo presión o el working set no coincide?

  • arcstat para tendencias de tasa de miss y tamaño de ARC.
  • Busca cambios súbitos en el patrón de carga (p. ej., un job de analítica que lea todo de golpe).

Esta secuencia evita el fallo clásico: pasar horas afinando cuando el pool está simplemente demasiado lleno, o perseguir “problemas de disco”
cuando es un cuello de botella de ARC/RAM.

Tres mini-historias corporativas desde el terreno

Mini-historia 1: el incidente causado por una suposición equivocada

Una compañía SaaS mediana tenía un cluster NFS respaldado por ZFS para imágenes VM. El equipo de almacenamiento dimensionó la capacidad basado en “uso actual más 30%”.
Estaban orgullosos de la hoja de cálculo. Tenía formato condicional y todo.

La suposición equivocada: la retención de snapshots era “estable”. En realidad, el equipo de virtualización había aumentado la frecuencia de snapshots
para rollback más rápido durante una migración. Los snapshots pasaron de horarios a cada 10 minutos para un subconjunto de datasets. Nadie avisó
a almacenamiento; “no cambiaron el tamaño de los datos”. Técnicamente cierto. Operativamente irrelevante.

Semanas después, la utilización del pool cruzó la zona de peligro. Las escrituras se fragmentaron cada vez más. La latencia p95 subió, luego p99 se volvió un precipicio.
Los clientes NFS empezaron a hacer timeout bajo una carga que parecía “normal”. Las aplicaciones culparon a la red, la red a los hipervisores, y almacenamiento fue llamado al final, como exige la tradición.

La solución post-incidente no fue heroica. Auditaron los horarios de snapshots, aplicaron retención por clase de dataset y aplicaron cuotas para que “un experimento”
no pudiera comerse el pool. La planificación de capacidad se actualizó para incluir el crecimiento por snapshots como un término de primera clase, no una nota al pie.

La lección: en ZFS, “tamaño de datos” es un concepto engañoso. Debes modelar churn y retención, o estarás planificando para un mundo que no existe.

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

Una organización financiera corría una mezcla de bases de datos y compartidos de archivos. Eran sensibles a la latencia I/O al cierre de mes. Alguien notó que
la latencia de escrituras síncronas era el punto crítico y decidió “arreglarlo” rápido: sync=disabled en los datasets calientes.

Funcionó —espectacularmente. Las gráficas de latencia se aplanaron. El equipo declaró victoria y siguió adelante. Unas semanas después, un evento de energía dejó caer un rack lo suficiente como para reiniciar a la fuerza un nodo de almacenamiento.
El hardware volvió. El pool se importó. La aplicación arrancó. Entonces comenzaron los bugs de integridad: inconsistencias en bases de datos, transacciones recientes faltantes y el peor tipo de incidente —pérdida de datos que no se anuncia inmediatamente.

La recuperación fue dolorosa y política. Restauraron desde backups, reprodujeron lo que pudieron y pasaron días demostrando lo perdido. La “optimización” original no fue maliciosa; fue el resultado
de tratar las semánticas de almacenamiento como un interruptor de rendimiento.

La solución aburrida y correcta fue: revertir a sync=standard, añadir dispositivos SLOG espejados con protección contra pérdida de energía para los datasets que realmente lo necesitaban,
y separar cargas para que las bases de datos no compitieran con compartidos durante picos. La planificación de capacidad también cambió: la resistencia y dominios de fallo del SLOG pasaron a ser parte del diseño, no un añadido de emergencia.

La lección: algunas optimizaciones son incidentes diferidos con mejores gráficas.

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

Una compañía de medios tenía petabytes de archivo nearline y una capa hot más pequeña para proyectos activos. Su ingeniero de almacenamiento tenía un hábito que
parecía soso en reuniones: “simulacros de capacidad” trimestrales. Sin pánico, sin drama. Solo probar procedimientos de expansión, validar backups y revisar líneas de tendencia.

Mantenían una regla simple: la expansión empieza al 75% de utilización proyectada (basada en una tasa de crecimiento móvil), no cuando el pool alcanza el 80% en realidad. También tenían
una política estricta de snapshots: agresiva en datasets activos, conservadora en archivos, y siempre con poda automatizada. Nadie podía conservar snapshots infinitos porque “es más seguro”.

Durante un proyecto mayor, un equipo interno empezó a generar archivos intermedios de alto churn en la capa hot. La tasa de crecimiento se duplicó. La monitorización marcó la tendencia en días.
Debido a que la organización ya había probado el procedimiento, añadir un nuevo vdev fue operativamente sin contratiempos. Expandieron temprano, reajustaron expectativas con stakeholders y evitaron la espiral habitual de “lo arreglamos después del deadline.”

El incidente que no sucedió es difícil de celebrar. Pero la práctica aburrida —disparadores basados en tendencias, expansión ensayada y aplicación de políticas— mantuvo el sistema estable cuando el comportamiento humano cambió.

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

1) Síntoma: picos de latencia cuando el pool alcanza ~85–95%

Causa raíz: presión de asignación + fragmentación + sobrecoste CoW en un pool casi lleno.

Solución: añadir capacidad (preferiblemente nuevos vdevs), podar snapshots y detener escrituras no críticas. No “tunées” tu salida de la física.

2) Síntoma: “borré datos pero el espacio no volvió”

Causa raíz: snapshots (o clones) siguen referenciando bloques.

Solución: identifica uso por snapshots (zfs list -t snapshot), poda la retención, evita clones de larga duración en datasets de alto churn.

3) Síntoma: el pool muestra espacio libre, pero los datasets reportan poco disponible

Causa raíz: cuotas/reservas, refreservations, o efectos del slop.

Solución: audita zfs get reservation,refreservation,quota; quita o redimensiona. Educa a los equipos que el espacio libre del pool ≠ espacio libre del dataset.

4) Síntoma: “añadimos discos más rápidos, sigue lento”

Causa raíz: diseño de un solo vdev limita la concurrencia; o la carga está limitada por IOPS y añadiste throughput secuencial.

Solución: añade vdevs (más concurrencia), considera mirrors para I/O aleatorio y separa cargas por dataset y clase de vdev.

5) Síntoma: scrubs/resilvers ahora tardan una eternidad

Causa raíz: más datos asignados, discos más lentos, contención o pool casi lleno que provoca patrones de asignación ineficientes.

Solución: expande capacidad antes; programa scrubs con menor carga; investiga discos débiles; evita empujar pools a zonas de alta utilización.

6) Síntoma: el vdev especial se llena y el rendimiento cae en picado

Causa raíz: dispositivos especiales subdimensionados para el crecimiento de metadata/bloques pequeños; bloques pequeños redirigidos inesperadamente.

Solución: dimensiona los vdevs especiales con margen; espejéalos; monitoriza asignación; ajusta special_small_blocks con precaución.

7) Síntoma: el rendimiento de escrituras aleatorias es pésimo en RAIDZ

Causa raíz: sobrecoste de paridad + patrones read-modify-write + insuficiente paralelismo de vdev.

Solución: usa mirrors para datasets con muchas escrituras aleatorias, añade más vdevs RAIDZ en lugar de ampliar uno, ajusta recordsize por dataset.

8) Síntoma: no puedes expandir el pool “como planeaste”

Causa raíz: el diseño asumió una característica o procedimiento no soportado en tu plataforma/versión; o restricciones de bahías/backplane.

Solución: valida métodos de expansión en la plataforma exacta temprano; documenta rutas de crecimiento soportadas; mantén un plan de migración.

Listas de verificación / plan paso a paso

Lista de planificación de capacidad (pool nuevo)

  1. Clasifica datasets: VM, BD, home, backups, archivo—cada uno tiene sus propias expectativas.
  2. Define SLOs: objetivos de latencia, ventanas de reconstrucción aceptables y tolerancia a downtime.
  3. Elige redundancia: mirrors para I/O mixto/aleatorio; RAIDZ2/3 para capacidad + throughput cuando corresponda.
  4. Escoge ancho de vdev: evita “un vdev gigante” salvo que la carga sea realmente secuencial y tolerante.
  5. Configura ashift correctamente desde el día cero.
  6. Planifica holgura: trata 80% como límite de planificación; deja espacio de emergencia además de eso.
  7. Diseña política de snapshots: nombres, frecuencia, retención y poda automatizada.
  8. Decide sobre vdevs especiales solo si los espejas y los monitorizas; dimensiona para el crecimiento.
  9. Planifica la ruta de expansión: añadir vdevs, reemplazar discos o ambos—valídalo contra las restricciones de la plataforma.
  10. Operativiza: monitorización, calendario de scrub, checks SMART y procedimientos de expansión ensayados.

Plan de ejecución de crecimiento (pool existente acercándose a límites)

  1. Mide la realidad: utilización del pool, fragmentación, principales datasets, uso por snapshots, reservas.
  2. Detén la hemorragia: poda snapshots, limita datasets descontrolados con cuotas, mueve cargas temporales fuera del pool.
  3. Elige método de expansión:
    • Añade vdevs cuando necesites rendimiento y un paso de crecimiento limpio.
    • Reemplaza discos cuando el chasis esté fijo y puedas permitir ventanas largas de resilver.
    • Usa expansión RAIDZ solo si tu plataforma la soporta y la has probado.
  4. Ensaya: realiza una prueba en laboratorio o staging; confirma nombres de dispositivos y manejo de fallos.
  5. Ejecuta con observabilidad: vigila zpool status, zpool iostat, I/O del sistema y latencia de aplicación.
  6. Validación post-expansión: verifica nuevo espacio, confirma calendario de scrub, confirma alertas y vuelve a comprobar disparadores de holgura.

Lista de políticas que previene reconstrucciones sorpresa

  • Estandariza la geometría de vdev para cada nivel de almacenamiento.
  • Aplica retención de snapshots y poda automática.
  • Requiere revisión de impacto de capacidad para nuevos proyectos que generen churn (artefactos CI, scratch analítica, proliferación de plantillas VM).
  • Mantén procedimientos de expansión documentados con notas específicas por versión.
  • Realiza “simulacros de capacidad” periódicos: simula expansión, verifica backups y prueba restauración.

Preguntas frecuentes

1) ¿Qué objetivo de utilización debo planear en ZFS?

Planea operar por debajo de ~80% para pools de propósito general. Para cargas de alto churn (VMs/BDs), apunta más bajo si te importan las colas altas.
Trata 85% como “ejecutar la expansión”, no como “empezar a pensar”.

2) ¿Son los mirrors siempre mejores que RAIDZ?

No. Los mirrors suelen ser mejores para I/O aleatorio y latencia predecible. RAIDZ suele ser mejor para eficiencia de capacidad y throughput secuencial.
El error es elegir RAIDZ para ahorrar espacio y luego esperar IOPS de mirror bajo cargas VM.

3) ¿Puedo cambiar el nivel RAIDZ después (RAIDZ1 a RAIDZ2)?

En muchos entornos, no sin reconstruir o migrar complejamente. Trata el nivel de redundancia como una decisión de día 0. Si dudas,
elige más paridad, no menos.

4) ¿Por qué borrar archivos no libera espacio?

Los snapshots (o clones) mantienen bloques antiguos referenciados. Borrar el archivo vivo solo elimina una referencia. El espacio vuelve cuando todas
las referencias desaparecen—a menudo significando poda de snapshots.

5) ¿Cómo planifico la capacidad para snapshots?

Estima basado en churn: datos cambiados por día × ventana de retención. Para datasets de alto churn, los snapshots pueden acercarse a otra copia completa con el tiempo.
Mídelo con zfs list -t snapshot y realiza tendencias.

6) ¿Debería habilitar dedup para ahorrar espacio?

Usualmente no, a menos que tengas una carga probada amigable con dedup y suficiente RAM (o diseño especializado) para soportarlo de forma segura.
Los errores con dedup pueden convertir planes de capacidad en incidentes de rendimiento.

7) ¿Cuándo tienen sentido los vdevs especiales?

Cuando tienes pools HDD sufriendo por cargas intensivas en metadata (muchos archivos pequeños, directorios, snapshots) y puedes espejar dispositivos rápidos y monitorizarlos correctamente.
Son potentes—y exigentes.

8) ¿Añadir un SLOG es lo mismo que añadir una caché?

No. SLOG mejora la latencia de escrituras síncronas. Si tu carga no hace escrituras sync, no verás mucho beneficio. No compres un SLOG para arreglar lentitud general.

9) ¿Cuál es la forma más segura de ampliar capacidad sin downtime?

Añadir un nuevo vdev es comúnmente la ruta menos disruptiva si tienes bahías libres y un diseño consistente. Reemplazar discos in-place también se puede hacer online,
pero extiende el riesgo durante un periodo más largo.

10) ¿Cuántos discos por vdev RAIDZ debería usar?

Depende de la carga y la tolerancia a reconstrucción. Los vdevs muy anchos aumentan la complejidad de rebuild y pueden perjudicar el comportamiento I/O aleatorio.
Muchos equipos de producción prefieren múltiples vdevs de tamaño moderado sobre uno muy ancho para mejor concurrencia y flexibilidad operativa.

Conclusión: próximos pasos que puedes ejecutar esta semana

La planificación de capacidad ZFS es el arte de elegir el futuro que deseas: expansiones aburridas, latencia predecible y fallos recuperables.
El diseño equivocado no suele explotar de inmediato. Simplemente acumula intereses hasta que el pool está lleno y la gráfica se pone vertical.

  1. Ejecuta los comandos de auditoría arriba y anota: utilización del pool, fragmentación, principales datasets, uso por snapshots, reservas y tiempos de scrub.
  2. Configura un disparador de holgura atado a la tendencia (no a sensaciones): empieza la expansión al 75% proyectado, ejecuta antes del 85% real.
  3. Estandariza políticas de datasets: recordsize, compresión, cuotas y retención de snapshots por clase.
  4. Decide tu ruta de crecimiento y ensáyala: añadir vdevs, reemplazo de discos o (si está soportado) expansión RAIDZ—con una historia de rollback.
  5. Haz una mejora estructural: más concurrencia de vdev para cargas IOPS, o vdevs especiales espejados para pools con alta carga de metadata.

Haz eso, y pasarás menos tiempo negociando emergencias de almacenamiento y más tiempo ejecutando sistemas que se comportan como si hubieran sido diseñados a propósito.

← Anterior
Docker AppArmor y seccomp: el endurecimiento mínimo que importa
Siguiente →
Eficiencia de GPU: por qué «mejor» no siempre significa «más grande»

Deja un comentario