Pools ZFS: Por qué pensar en ‘particiones’ empeora tu diseño

¿Te fue útil?

Hay un tipo particular de fallo de almacenamiento que no empieza con un estruendo. Empieza con alguien diciendo: “Simplemente vamos a dividir los discos en unas pocas particiones. Será flexible.” Seis meses después estás mirando un pool ZFS que está técnicamente en línea, prácticamente cojeando y emocionalmente agotador.

ZFS no es un gestor de particiones con un sistema de archivos añadido. ZFS es un sistema de almacenamiento que quiere poseer sus dispositivos de punta a punta: topología, redundancia, semántica de escritura, autocuración y rendimiento. Cuando lo diseñas como un montón de particiones, no solo lo haces desordenado: lo haces frágil, más lento y más difícil de recuperar cuando las cosas salen mal (que saldrán, un martes, cinco minutos antes del cierre de cambios).

Qué es el “pensamiento en particiones” (y por qué resulta tan tentador)

El “pensamiento en particiones” es el hábito de tratar los discos como un contenedor genérico que cortas en porciones para servir distintos propósitos: una partición para datos, otra para logs, otra para swap, otra para “futuro”, otra para “rendimiento temporal” y —porque somos adultos que ya hemos sido quemados— una “por si acaso”. Es la visión moldeada por décadas de sistemas de archivos tradicionales y controladoras RAID donde la planificación de capacidad era literalmente sobre tablas de particiones.

En ZFS, ese instinto se manifiesta como:

  • Hacer múltiples particiones en el mismo disco físico y usarlas en diferentes vdevs (o en pools distintos).
  • Crear una “pequeña partición rápida” en cada disco para metadata o cargas especiales.
  • Esculpir “particiones SLOG” en los mismos dispositivos que el pool (o peor, en los mismos spindles).
  • Sobreingeniería de diseños GPT para “estandarizar” entre servidores sin entender qué es lo que ZFS ya estandariza.

Por qué resulta tentador: las particiones dan sensación de control. Se ven ordenadas en una hoja de cálculo. Permiten alegar “flexibilidad futura” sin hacer lo difícil: elegir una topología de vdev correcta desde el principio. Y a veces, especialmente en entornos corporativos, las particiones se usan como herramienta política: “Podemos compartir los discos entre equipos”.

Aquí está el problema: a ZFS no le importan tus buenas intenciones. Le importan las rutas de E/S, los dominios de fallo y la geometría de los vdevs. Las particiones no cambian la física; solo la ocultan tras etiquetas más amables.

Broma #1: Particionar discos para la “flexibilidad” de ZFS es como comprar una nevera más grande y luego pegar con cinta las baldas para poder “escalar después”.

El modelo mental de ZFS: vdevs son la unidad de verdad

Si quieres dejar de diseñar pools malos, interioriza esta frase: La redundancia y el rendimiento en ZFS se definen a nivel de vdev, no a nivel de pool.

Pool: el agregador

Un pool ZFS es una colección de vdevs. El pool reparte los datos en stripe entre vdevs. No “balancea” mágicamente vdevs malos para que actúen bien. Si añades un vdev lento o frágil, has añadido un componente lento o frágil al pool.

Vdev: el dominio de fallo

Un vdev se construye a partir de uno o más dispositivos y tiene un modelo de redundancia: disco único, mirror, raidz1/2/3, special vdev mirror, etc. Si un vdev muere, el pool muere. Por eso la idea de “solo una pequeña partición en un vdev de un solo disco” es silenciosamente catastrófica. Estás añadiendo un punto único de fallo a todo el pool.

Dispositivos: la física

ZFS no puede ignorar qué es un dispositivo. Si dos particiones viven en el mismo SSD, compiten por la misma capa de traducción de flash, la misma amplificación de escritura, la misma recolección de basura, el mismo presupuesto de resistencia, los mismos bugs de firmware y los mismos picos de latencia “sorpresa” cuando el disco decide que es hora de tareas internas.

Datasets: el lugar correcto para “cortar”

Si necesitas separación—quotas, reservaciones, políticas de recordsize, compresión, snapshots—los datasets de ZFS ya proporcionan eso limpiamente. No particiones discos para límites administrativos; usa datasets (o zvols) porque preservan la topología del pool mientras te dan control de políticas.

Hechos e historia que explican la trampa

Algo de contexto ayuda porque mucho diseño ZFS malo no es estupidez—son modelos mentales heredados.

  1. ZFS se construyó para acabar con la separación “gestor de volúmenes + sistema de archivos”. En la era Solaris, UFS más un gestor de volúmenes significaban dos capas que querían gestionar bloques. ZFS las unificó.
  2. Las primeras implementaciones de ZFS usaban discos enteros porque las herramientas lo daban por sentado. La partición llegó después como un salvavidas por compatibilidad, no como un objetivo de diseño.
  3. El debate “disco entero” vs “partición” es anterior a ZFS. Los administradores tradicionales particionaban porque MBR/GPT eran la única forma de trocear dispositivos para múltiples sistemas de archivos. ZFS hizo eso menos relevante.
  4. Los discos con sectores de 4K cambiaron todo. Cuando los discos Advanced Format se hicieron comunes, la desalineación y las suposiciones erróneas sobre sectores causaron caídas reales de rendimiento. ZFS respondió con ashift, que debes acertar al crear el vdev.
  5. RAIDZ no es RAID5/6 en una controladora. ZFS tiene ancho de stripe variable y semántica copy-on-write, lo que cambia la historia de rendimiento y fragmentación respecto al RAID clásico.
  6. Copy-on-write significa que “sobrescribir” es una mentira. ZFS asigna nuevos bloques para cambios; no sobrescribe en sitio. El pensamiento centrado en particiones a menudo asume que puedes “proteger” regiones del disco unas de otras. No puedes.
  7. El ZIL y el SLOG se malentienden frecuentemente. El ZIL existe en el pool; un SLOG es solo un dispositivo externo para acelerar ciertas escrituras síncronas. No es una “partición de logs”.
  8. Los special vdevs son poderosos y peligrosos. Pueden almacenar metadata (y opcionalmente bloques pequeños), pero si no son redundantes, pueden tumbar todo el pool.
  9. El comportamiento del firmware de los SSD pesa más en tu historia de latencia de lo que la gente admite. Las particiones no particionan el firmware. Particionan tu confianza.

Cómo el diseño centrado en particiones rompe ZFS en la vida real

1) Creas dominios de fallo compartidos sin querer

El antipatrón clásico: “Dividiremos cada disco en dos particiones y haremos dos mirrors. Así, si perdemos un disco, cada mirror pierde un lado y seguimos bien.” En el papel parece redundancia. En la realidad, cada mirror depende de todos los discos. Pierde un disco y ambos mirrors se degradan. Pierde un segundo disco y puedes perder ambos mirrors dependiendo de qué discos falle.

Empeora cuando atraviesas bahías: pensabas que habías construido “dos pools independientes”, pero realmente construiste un pool con fallos correlacionados (misma tanda de firmware, misma estantería, mismo expander SAS).

2) Creas contendencia de rendimiento que no puedes ajustar

Si dos vdevs comparten el mismo dispositivo físico (porque usaste particiones), has creado contendencia interna que ZFS no puede ver. ZFS programa E/S a vdevs asumiendo que son independientes. Cuando no lo son, obtienes rarezas: los picos de latencia de una carga se filtran a otro vdev, los scrubs se disparan, los resilvers avanzan a paso de tortuga y el sistema parece habitado.

3) Te atas en errores de geometría irreparables

En ZFS, algunas decisiones de diseño son efectivamente permanentes sin reconstruir: ashift, ancho de RAIDZ y decisiones sobre “dónde vive la metadata” como el uso de special vdev. Los planes centrados en particiones suelen hornear suposiciones de “lo cambiaremos después” que se convierten en “lo migraremos más tarde”, que se convierte en “viviremos con ello hasta la renovación de hardware”.

4) Malinterpreta la “eficiencia de espacio” y lo pagas en operaciones

Los administradores a veces particionan discos para reservar espacio para vdevs futuros o crear grupos “de tamaño igual”. ZFS no se beneficia del espacio de disco sin usar sentado inactivo en una tabla de particiones. No estás creando una reserva; estás creando capacidad varada y dolor futuro de reordenación.

5) Haces la recuperación más difícil sin beneficio operativo

Cuando un pool está enfermo, lo último que quieres es ambigüedad: “¿Qué partición era ese vdev otra vez? ¿Era /dev/sdb2 en este host pero /dev/sdc2 en el otro?” ZFS puede usar IDs de dispositivo estables, pero los esquemas con muchas particiones multiplican el número de identificadores y las formas en que los humanos pueden equivocarse bajo estrés durante un reemplazo.

Broma #2: Si alguna vez te encuentras etiquetando particiones “final2_fixed_really”, felicidades—has descubierto deuda técnica en su hábitat natural.

Tres micro-historias del mundo corporativo desde la trinchera

Micro-historia 1: Un incidente causado por una suposición equivocada (“Las particiones son independientes”)

En una empresa mediana, un equipo heredó un servidor de almacenamiento con un pool que parecía “razonablemente redundante”. El admin anterior había dividido cada uno de ocho HDDs en dos particiones y construido dos vdevs RAIDZ1 a partir de las particiones. La lógica era que “dos vdevs significa paralelismo” y “RAIDZ1 está bien porque tenemos dos”.

La primera falla fue aburrida: un disco empezó a devolver errores CRC. El pool se mantuvo en línea, degradado. El on-call cambió la unidad. Comenzó el resilvering—y de inmediato el rendimiento del sistema se fue al garete. La latencia subió, las aplicaciones hicieron timeouts y el equipo de base de datos comenzó a olfatear problemas.

Luego falló un segundo disco. No sorprendente: misma antigüedad, misma tanda, y el estrés del resilver es una forma clásica de encontrar discos marginales. La sorpresa fue que el pool murió aunque “solo fallaron dos discos”. Las particiones hicieron que esas fallas afectaran ambos vdevs RAIDZ1 de una manera que nadie esperaba por el diagrama. El pool no pudo tolerar la combinación.

El postmortem fue doloroso porque la causa raíz no fue una acción única; fue una suposición de diseño de que las particiones creaban dominios de fallo separados. No lo hacen. Un disco es un disco, y la redundancia de ZFS no entiende tus límites de partición como barreras de seguridad. Los “dos vdevs” no eran independientes; eran dos formas de perder el mismo pool.

Lo que lo arregló no fue heroísmo. Fue re-arquitectar durante la recuperación: reconstruir el pool como mirrors (o RAIDZ2 según objetivos de capacidad), nada de juegos de particiones, y aplicar una política “disco entero únicamente” en la automatización para que el diseño no regresara al mal estado.

Micro-historia 2: Una optimización que se volvió en contra (“Particiones rápidas pequeñas para metadata”)

Un departamento financiero tenía una carga mixta: muchos archivos pequeños, algunas bases de datos y un proceso de backup que se comportaba como una trituradora. Alguien leyó sobre “special vdevs” y se inspiró. Pero en lugar de añadir un par dedicado de SSDs para un special vdev, tallaron una “partición rápida para metadata” de los SSDs existentes que también servían como vdevs de datos.

Al principio se vio bien. Las operaciones intensivas en metadata se aceleraron. Los recorridos de directorio quedaron ágiles. Los números del dashboard mejoraron lo suficiente como para ganar un pequeño reconocimiento interno por “mejoras de rendimiento neutras en coste”, que es el tipo de frase que debería ponerte nervioso.

Luego llegó el cierre de trimestre. La carga cambió: más escrituras síncronas, más churn, más snapshots. Las “particiones de metadata” compitieron con la I/O de datos en los mismos SSDs. La latencia empezó a subir en picos, no consistentemente, pero en ráfagas feas. El equipo persiguió fantasmas: red, NFS, locks de base de datos. Mientras tanto, el planificador de E/S del pool estaba haciendo exactamente lo que se le indicaba—tratar el special vdev como capacidad separada, aunque compartiera los mismos dispositivos físicos debajo.

El retroceso llegó en forma de mantenimiento: durante un scrub, el sistema entró en un mal ritmo—recolección de basura del SSD coincidiendo con lecturas intensas. El scrub tardó dramáticamente más, lo cual extendió la ventana de riesgo. Nada explotó, pero el sistema se volvió predeciblemente impredecible, lo cual es peor en la vida corporativa porque es difícil explicar a la gerencia por qué “no está caído, solo es intermitentemente horrible”.

La solución fue simple y cara: dejar de ser listos. Mover metadata/bloques pequeños a SSDs espejados dedicados y diseñados para ese rol, y mantener separados los vdevs de datos. El beneficio de rendimiento volvió y los picos de latencia se calmaron. El plan “neutro en coste” terminó costando tiempo, atención y credibilidad—tres monedas que los equipos SRE nunca tienen de sobra.

Micro-historia 3: Una práctica aburrida pero correcta que salvó el día (“Discos enteros, IDs estables, reemplazo ensayado”)

Otra organización usaba ZFS para almacenamiento de VM. Nada de particionados extraños. Mirrors para IOPS, un SLOG espejado separado en SSDs con protección contra pérdida de energía, y un par dedicado de SSDs como special vdev (también espejados). El documento de diseño era casi insultantemente aburrido.

Pero su práctica operativa fue la verdadera historia: cada disco se referenciaba por rutas estables (by-id), cada bahía estaba etiquetada y el procedimiento de “reemplazar un disco” se ensayaba trimestralmente como un simulacro. También mantenían un pequeño stock de discos idénticos porque los plazos de aprovisionamiento son también una forma de outage.

Una tarde un disco falló de forma contundente—desapareció del bus. El on-call no tuvo que adivinar qué dispositivo faltaba, no tuvo que mapear particiones y no tuvo que interpretar un montón de symlinks ambiguos. Ejecutaron el procedimiento, reemplazaron por uno equivalente, comenzó el resilver y el sistema siguió sirviendo cargas.

El remate: durante el resilver, otro disco empezó a registrar errores. El equipo lo detectó temprano porque estaban vigilando zpool status y contadores SMART como parte del simulacro. Lo reemplazaron proactivamente antes de que se volviera catastrófico. Sin puente de incidentes. Sin arqueología frenética en Slack. Solo operaciones de almacenamiento aburridas y correctas—exactamente las que nunca reciben un trofeo, pero mantienen a la empresa en funcionamiento.

Tareas prácticas: comandos que te mantienen honesto

Estas son las tareas que realmente uso cuando alguien me entrega un sistema ZFS que “fue diseñado cuidadosamente” y ahora hace ruidos tristes. Cada tarea incluye el comando y cómo interpretar lo que ves.

Tarea 1: Inventario de la topología del pool (detecta juegos de particiones)

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

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-SAMSUNG_SSD_...-part1  ONLINE       0     0     0
            ata-SAMSUNG_SSD_...-part1  ONLINE       0     0     0

errors: No known data errors

Interpretación: Si ves -partX por todas partes, pregunta por qué. Puede ser inocuo (particiones de arranque más particiones ZFS enteras), o puede ser que alguien esté cortando dispositivos para múltiples roles. Busca el mismo disco base apareciendo en varios vdevs vía diferentes particiones. Eso es una señal de alerta.

Tarea 2: Mostrar vdevs con nombres de dispositivo persistentes

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'ata-|nvme-' | head
lrwxrwxrwx 1 root root  9 Dec 24 09:10 ata-WDC_WD80... -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 24 09:10 ata-WDC_WD80...-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Dec 24 09:10 ata-WDC_WD80...-part2 -> ../../sdb2

Interpretación: En producción, referencia los miembros del vdev por /dev/disk/by-id/..., no por /dev/sdX. Si confías en /dev/sdX y alguien añade una HBA o cambia el orden de arranque, tu próximo reinicio será una fiesta sorpresa.

Tarea 3: Verificar ashift (alineación) por vdev

cr0x@server:~$ sudo zdb -C tank | grep -E 'vdev_tree|ashift' -n
97:        vdev_tree:
130:                ashift: 12

Interpretación: ashift: 12 significa sectores de 4K. Para la mayoría de HDDs/SSDs modernos, 12 es una base segura. Si ves ashift: 9 en discos modernos, podrías estar pagando una penalización de rendimiento para siempre a menos que reconstruyas ese vdev.

Tarea 4: Comprobar tamaños reales de sector desde el SO

cr0x@server:~$ sudo lsblk -o NAME,MODEL,SIZE,PHY-SEC,LOG-SEC,ROTA,TYPE | grep -E 'sd|nvme'
sda  INTEL SSDSC2  447.1G    4096    512    0 disk
sdb  WDC WD80EAZZ  7.3T      4096    512    1 disk

Interpretación: ZFS escribe en unidades de 2^ashift. Si el sector físico es 4096 y tu vdev se creó con ashift=9, estás desalineado. Eso suele manifestarse como IOPS bajos y mayor latencia bajo cargas síncronas o de bloques pequeños.

Tarea 5: Identificar si usas special vdevs

cr0x@server:~$ sudo zpool status tank | sed -n '/special/,$p'
          special
            mirror-2                ONLINE       0     0     0
              nvme-SAMSUNG_MZ...     ONLINE       0     0     0
              nvme-SAMSUNG_MZ...     ONLINE       0     0     0

Interpretación: Si existe un special vdev y no está espejado, trátalo como un incidente esperando ocurrir. Los special vdevs pueden contener metadata y (opcionalmente) bloques pequeños; perderlos puede significar perder el pool.

Tarea 6: Confirmar a dónde van las escrituras síncronas (presencia y salud del SLOG)

cr0x@server:~$ sudo zpool status tank | sed -n '/logs/,$p'
          logs
            mirror-1                ONLINE       0     0     0
              ata-INTEL_SLOG_A      ONLINE       0     0     0
              ata-INTEL_SLOG_B      ONLINE       0     0     0

Interpretación: Un SLOG ayuda solo para escrituras síncronas (NFS con sync, bases de datos configuradas para durabilidad, etc.). Si tu “SLOG” es una partición en un SSD de datos muy ocupado, probablemente cambiaste latencia predecible por latencia impredecible.

Tarea 7: Ver I/O por vdev y detectar el miembro lento

cr0x@server:~$ sudo zpool iostat -v tank 1 5
                    capacity     operations     bandwidth
pool              alloc   free   read  write   read  write
----------------  -----  -----  -----  -----  -----  -----
tank              2.10T  5.10T    120    380  12.3M  45.1M
  mirror-0        1.05T  2.55T     60    190   6.1M  22.6M
    sdb            -      -       60    190   6.1M  22.6M
    sdc            -      -       60    190   6.1M  22.6M
  mirror-1        1.05T  2.55T     60    190   6.2M  22.5M
    sdd            -      -       60    190   6.2M  22.5M
    sde            -      -       60    190   6.2M  22.5M

Interpretación: Cuando un vdev es mucho más lento, la latencia cola del pool lo sigue. Si has construido vdevs a partir de particiones en el mismo disco físico, la salida de iostat puede parecer “balanceada” mientras el dispositivo físico está sobrecargado—porque ZFS no puede ver el cuello de botella compartido.

Tarea 8: Comprobar propiedades a nivel de dataset en lugar de inventar particiones

cr0x@server:~$ sudo zfs get -o name,property,value,source compression,recordsize,atime,sync tank/app
NAME      PROPERTY     VALUE   SOURCE
tank/app  compression  lz4     local
tank/app  recordsize   128K    local
tank/app  atime        off     local
tank/app  sync         standard default

Interpretación: Aquí es donde se hace el tuning de la carga. No necesitas una “partición de logs” para una app con muchos logs; necesitas un recordsize apropiado, quizá atime=off, quizá un dataset separado para patrones de E/S distintos.

Tarea 9: Observar la latencia en vivo (suero de la verdad)

cr0x@server:~$ sudo zpool iostat -r -v tank 1 3
                    capacity     operations     bandwidth    total_wait  disk_wait
pool              alloc   free   read  write   read  write   ---------   ---------
tank              2.10T  5.10T    120    380  12.3M  45.1M     12ms        8ms
  mirror-0        1.05T  2.55T     60    190   6.1M  22.6M     10ms        7ms
  mirror-1        1.05T  2.55T     60    190   6.2M  22.5M     14ms        9ms

Interpretación: Si disk_wait es alto, los dispositivos físicos son lentos o están sobrecargados. Si total_wait es mucho más alto que disk_wait, podrías estar limitado por CPU, presión de memoria o atascado detrás de colas de ZFS (a menudo síntoma de vdevs subdimensionados o cargas síncronas patológicas).

Tarea 10: Confirmar presión de ARC y si la memoria es tu cuello de botella

cr0x@server:~$ sudo arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
09:21:01   520    40      7    10   25    20   50    10   25   28G    32G

Interpretación: Tasas altas de miss con arcsz pequeño relativo a tu carga pueden impulsar I/O de disco y hacer que todo parezca un “problema de almacenamiento” cuando en realidad es cuestión de dimensionamiento de memoria. Particionar no arregla un problema de caché; solo te da nuevos lugares donde equivocarte.

Tarea 11: Estado de scrub y conciencia del impacto

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
scan: scrub in progress since Tue Dec 24 08:10:15 2025
        1.20T scanned at 520M/s, 600G issued at 260M/s, 2.10T total
        0B repaired, 28.57% done, 0 days 02:10:33 to go

Interpretación: Los scrubs son buenos; los scrubs también cargan el sistema. Si los scrubs constantemente aplastan el rendimiento, probablemente tienes un problema de geometría de vdev (RAIDZ demasiado ancho para cargas IOPS) o un cuello de botella por dispositivo compartido (travesuras de particiones), o simplemente no tienes suficientes spindles.

Tarea 12: Reemplazar un disco correctamente (y no a base de adivinanzas con particiones)

cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/ata-WDC_OLD_DRIVE /dev/disk/by-id/ata-WDC_NEW_DRIVE
cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: DEGRADED
scan: resilver in progress since Tue Dec 24 09:02:11 2025
config:
        NAME                                 STATE
        tank                                 DEGRADED
          mirror-0                           DEGRADED
            replacing-0                      DEGRADED
              ata-WDC_OLD_DRIVE              UNAVAIL
              ata-WDC_NEW_DRIVE              ONLINE  (resilvering)
            ata-WDC_PEER_DRIVE               ONLINE

Interpretación: Usa IDs estables. Reemplaza dispositivos enteros cuando sea posible. Cuando tu pool está construido a partir de particiones, las operaciones de reemplazo se vuelven más propensas a errores porque estás manejando múltiples objetivos partX por disco.

Tarea 13: Detectar uso accidental múltiple de un disco físico

cr0x@server:~$ sudo zpool status -P tank | grep -E '/dev/disk/by-id/.*-part' | sed 's/-part[0-9]\+//g' | sort | uniq -c | sort -nr | head
      2 /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S5...
      1 /dev/disk/by-id/ata-WDC_WD80EAZZ_7SG...

Interpretación: Si el mismo dispositivo base aparece múltiples veces (count > 1) tras quitar el sufijo de partición, probablemente tengas un disco alimentando múltiples miembros de vdev. A veces es intencional para arranque; a menudo es un olor de diseño.

Tarea 14: Comprobar flags de características del pool y suposiciones de versión

cr0x@server:~$ sudo zpool get -H -o property,value feature@async_destroy feature@spacemap_histogram tank
feature@async_destroy      enabled
feature@spacemap_histogram active

Interpretación: Esto no es “partición vs disco entero”, pero previene una clase relacionada de fallo: intentar importar un pool en un host que no soporta sus features. La gente de las particiones también tiende a ser la de “podemos importarlo en cualquier lado”. No siempre puedes.

Guía rápida de diagnóstico (caza de cuellos de botella)

Cuando el rendimiento se hunde o la latencia se dispara, necesitas una secuencia que te lleve de “los usuarios están enfadados” a “este es el factor limitante” sin deambular por el folclore. Este es el orden orientado a producción que uso.

Primero: ¿El pool está sano y no haciendo trabajo de emergencia?

cr0x@server:~$ sudo zpool status -x
all pools are healthy

Si no está sano: deja de diagnosticar “rendimiento”. Estás diagnosticando “supervivencia”. Un vdev degradado, un resilver o una corrección de errores intensa dominarán todo lo demás.

Segundo: ¿Estás actualmente scrubeando/resilverizando?

cr0x@server:~$ sudo zpool status tank | sed -n '1,25p'

Interpretación: Un resilver es una razón legítima para menor throughput. Si tu pool se vuelve inutilizable durante scrubs rutinarios, eso es un problema de capacidad de diseño: no suficiente margen de IOPS, o una topología que sobre-optimiza capacidad a costa de concurrencia.

Tercero: ¿Qué vdev es el más lento bajo carga?

cr0x@server:~$ sudo zpool iostat -r -v tank 1 10

Interpretación: Busca un vdev con mayores tiempos de espera. En pools con vdevs mixtos, el vdev más lento arrastra la latencia cola. Si ves esperas inconsistentes que se correlacionan entre varios vdevs, sospecha dispositivos físicos compartidos (particionamiento) o problemas en backplanes/HBA compartidos.

Cuarto: ¿Es presión de escrituras síncronas (SLOG / ZIL) o I/O aleatorio general?

cr0x@server:~$ sudo zfs get -r -o name,property,value,source sync tank | head
NAME      PROPERTY  VALUE     SOURCE
tank      sync      standard  default
tank/app  sync      standard  default

Interpretación: Si la carga fuerza sync (NFS, bases de datos) y no tienes un SLOG apropiado, la latencia se disparará. Si tienes un SLOG pero no está protegido contra pérdida de energía o está sobrecargado (o es una partición en dispositivos ocupados), obtienes “rápido a veces, horrible a veces”.

Quinto: ¿La presión de ARC/memoria te empuja al disco?

cr0x@server:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           64Gi        52Gi       1.2Gi       1.0Gi        11Gi        8Gi
Swap:          0B          0B          0B

Interpretación: Poca memoria disponible con alta carga de lecturas de disco puede parecer “almacenamiento lento”. A ZFS le encanta la RAM; privarlo la convierte en trabajo tonto para los discos.

Sexto: ¿El cuello de botella es CPU, compresión o checksums?

cr0x@server:~$ top -b -n1 | head -20

Interpretación: Si la CPU está al máximo durante escrituras intensas con compresión, podrías estar limitado por cómputo. Eso no es necesariamente malo—la compresión puede valer la pena—pero necesitas saber con qué estás pagando.

Séptimo: Validar errores a nivel de dispositivo y problemas de enlace

cr0x@server:~$ sudo dmesg -T | grep -E 'ata[0-9]|nvme|sd[a-z]:|I/O error|link reset' | tail -20

Interpretación: Errores CRC, resets de enlace y timeouts pueden disfrazarse de “ZFS está lento”. A menudo es un cable, expander o firmware del HBA. Las particiones no causan esto, pero los esquemas con muchas particiones hacen más difícil identificar qué disco físico está realmente enfermo.

Errores comunes: síntomas específicos y soluciones

Error 1: Usar particiones del mismo disco en diferentes vdevs

Síntoma: Picos de latencia aleatorios que no coinciden con la distribución iostat a nivel ZFS; scrubs/resilvers causan que “todo” se ralentice; latencia cola impredecible.

Por qué ocurre: ZFS cree que tiene más dispositivos independientes de los que realmente hay.

Solución: Reconstruir con un rol por dispositivo físico. Si necesitas múltiples “clases” (datos, special, slog), usa dispositivos físicos separados para cada clase y espeja los críticos.

Error 2: Añadir un vdev “special” o “log” de un solo disco porque es “solo metadata” o “solo un log”

Síntoma: Fallo del pool tras la pérdida de un dispositivo; incapacidad para importar; “I/O error” repentino cuando ese dispositivo muere.

Por qué ocurre: Los special vdevs y los SLOGs tienen perfiles de riesgo distintos. Un SLOG normalmente puede perderse sin perder el pool (pierdes transacciones síncronas recientes). Un special vdev puede ser crítico para el pool según lo que almacene.

Solución: Espejar los special vdevs. Usar dispositivos adecuados para SLOG (SSDs con PLP). Evitar particiones “ingeniosas” para roles críticos.

Error 3: Pensar que las particiones solucionan la “expansión futura”

Síntoma: Capacidad varada; tamaños extraños de vdev; incapacidad para añadir nuevos vdevs limpiamente; rendimiento desigual tras la expansión.

Por qué ocurre: La expansión en ZFS es sobre añadir vdevs, no sobre extender particiones. Quieres vdevs coherentes con características de rendimiento consistentes.

Solución: Planifica la expansión por unidades de vdev. Los mirrors se expanden añadiendo más mirrors. RAIDZ se expande añadiendo otro vdev RAIDZ (o reemplazando discos por otros mayores y esperando autoexpand donde sea soportado).

Error 4: ashift mal alineado debido a “funcionó en el servidor antiguo” al clonar

Síntoma: Escrituras pequeñas aleatorias inexplicablemente lentas; alta amplificación de escritura; desgaste acelerado del SSD.

Solución: Crear vdevs con el ashift correcto desde el inicio. Si está mal, la migración/reconstrucción es la solución honesta. No intentes “particionar para salir” de ello.

Error 5: Tratar RAIDZ como una característica de rendimiento para cargas IOPS

Síntoma: Almacenamiento de VMs lento; latencia alta en bases de datos; throughput bien en benchmarks pero cargas reales sufren.

Solución: Usa mirrors para cargas sensibles a IOPS. RAIDZ para capacidad/throughput y cargas secuenciales. Si debes usar RAIDZ, mantén anchos sensatos y entiende ventanas de reconstrucción.

Error 6: Sobre-particionar para “layouts de arranque estándar” sin documentarlo

Síntoma: Confusión durante reemplazos; partición equivocada reemplazada; miembros del pool intercambiados incorrectamente; outages más largos por error humano.

Solución: Si debes particionar para arranque (común en algunas configuraciones), mantenlo mínimo y uniforme, y automatiza el etiquetado. Haz que los miembros del vdev de ZFS sean estables y obvios vía nombres by-id y números de partición consistentes.

Listas de verificación / plan paso a paso

Paso a paso: diseñar un pool nuevo sin “pensamiento en particiones”

  1. Define primero el dominio de fallo. ¿Un servidor? ¿Una estantería? ¿Múltiples HBAs? Decide qué es un “fallo único” en tu entorno.
  2. Elige tipo de vdev según la carga.
    • VMs/bases de datos/sensibles a latencia: mirrors (más vdevs = más paralelismo).
    • Backups/media/secuencial: RAIDZ2/3 (eficiente en capacidad).
  3. Elige ashift intencionalmente. Por defecto usa 12 a menos que tengas una razón convincente en contra.
  4. Decide si necesitas special vdev. Solo si la metadata/rendimiento de bloques pequeños importa y puedes espejarlo con buenos SSDs.
  5. Decide si necesitas SLOG. Solo si tienes verdadera presión de escrituras síncronas y puedes usar dispositivos con protección contra pérdida de energía.
  6. Usa datasets para separación de políticas. Quotas, reservaciones, recordsize, compresión, snapshots—hazlo allí.
  7. Estandariza nombres de dispositivo. Construye y opera usando /dev/disk/by-id.
  8. Documenta un procedimiento de reemplazo. Luego ensáyalo.

Paso a paso: crear un pool (ejemplo) usando discos enteros y IDs estables

cr0x@server:~$ sudo zpool create -o ashift=12 tank \
  mirror /dev/disk/by-id/ata-WDC_DISK_A /dev/disk/by-id/ata-WDC_DISK_B \
  mirror /dev/disk/by-id/ata-WDC_DISK_C /dev/disk/by-id/ata-WDC_DISK_D

cr0x@server:~$ sudo zfs set compression=lz4 atime=off tank
cr0x@server:~$ sudo zfs create tank/app
cr0x@server:~$ sudo zfs set recordsize=16K tank/app

Interpretación: Los mirrors te dan IOPS por paralelismo; los datasets te dan política. No se requieren gimnasias de particiones.

Paso a paso: añadir un special vdev espejado (ejemplo)

cr0x@server:~$ sudo zpool add tank special mirror \
  /dev/disk/by-id/nvme-SAMSUNG_SPECIAL_A \
  /dev/disk/by-id/nvme-SAMSUNG_SPECIAL_B

cr0x@server:~$ sudo zfs set special_small_blocks=16K tank

Interpretación: Así aceleras metadata/bloques pequeños sin engañarte sobre dominios de fallo. Espejado y con dispositivos dedicados.

Paso a paso: añadir un SLOG espejado (ejemplo)

cr0x@server:~$ sudo zpool add tank log mirror \
  /dev/disk/by-id/ata-INTEL_PLP_SLOG_A \
  /dev/disk/by-id/ata-INTEL_PLP_SLOG_B

Interpretación: Un SLOG espejado reduce riesgo y mejora consistencia para cargas pesadas en sync. No finjas esto con una partición en tus SSDs ya ocupados.

Lista operativa: qué estandarizar para que los humanos no tengan que ser perfectos

  • Usar siempre rutas por-id al crear y reemplazar pools.
  • Etiquetar bahías y mantener un mapeo interno de bahía-a-serial.
  • Programar scrubs y monitorizar su tendencia de duración a lo largo del tiempo.
  • Alertar en SMART pre-fail y en errores de lectura/escritura/checksum de ZFS.
  • Mantener discos de repuesto (o al menos ruta de compra garantizada) para cada clase de dispositivo.
  • Ensayar flujos zpool replace y zpool clear en un entorno seguro.

Preguntas frecuentes

1) ¿Usar particiones con ZFS es siempre malo?

No. Es común usar una pequeña partición EFI/boot y luego una partición ZFS para el miembro del pool. Lo que es malo es usar particiones para fingir que un dispositivo físico es múltiples dispositivos independientes, o mezclar roles en el mismo disco de formas que creen contendencia oculta y fallos correlacionados.

2) ¿Por qué importa tanto que “un vdev malo mata el pool”?

Porque cambia tu forma de pensar sobre el riesgo. En el mundo LVM, puedes perder un PV y quizá perder solo un volumen. En ZFS, si añades un vdev de disco único (incluso uno minúsculo), has añadido un punto único de fallo a todo el pool.

3) ¿Puedo dividir discos en particiones para crear más vdevs y obtener rendimiento?

Puedes, pero no deberías. No estás creando más IOPS; estás creando más colas que eventualmente afectan al mismo dispositivo físico. ZFS programará trabajo como si los vdevs fueran independientes, lo que hace el rendimiento menos predecible y puede empeorar la latencia bajo carga.

4) ¿Cuál es la forma correcta de aislar cargas si no son particiones?

Usa datasets (o zvols) con quotas, reservaciones y propiedades por dataset. Si necesitas aislamiento físico real, usa pools separados en dispositivos físicos separados—no particiones en los mismos spindles/SSDs.

5) ¿Necesito un SLOG para NFS?

Sólo si tu carga NFS hace escrituras síncronas (común en almacenamiento de VM, algunas configuraciones de bases de datos y ciertas opciones de exportación NFS). Si tu carga es mayormente async, un SLOG no ayudará mucho. Si lo necesitas, usa dispositivos con protección contra pérdida de energía y preferiblemente espejados.

6) ¿Valen la pena los special vdevs?

Pueden transformar el rendimiento en cargas intensivas en metadata y archivos pequeños, pero deben diseñarse como dispositivos de primera clase, redundantes y monitorizados. Trátalos como críticos para el pool a menos que hayas limitado explícitamente lo que almacenan—y aun así, entiende las implicaciones de fallo.

7) Mirrors vs RAIDZ: ¿cuál es el “por defecto en producción”?

Para cargas generales sensibles a latencia (VMs, bases de datos), los mirrors son la opción más segura por defecto porque escalan IOPS con cada vdev y reconstruyen más rápido. RAIDZ es genial para eficiencia de capacidad y throughput secuencial, pero no es magia para I/O aleatorio.

8) Si mi pool ya está construido con particiones, ¿qué debo hacer?

Primero, no entres en pánico. Haz inventario para ver si las particiones comparten discos físicos entre vdevs. Si lo hacen, planifica una migración: construye un pool nuevo con topología sensata y replica usando ZFS send/receive o migración a nivel de aplicación. Si las particiones son solo “arranque + miembro ZFS”, documéntalo y sigue adelante.

9) ¿ZFS “re-balancea” datos cuando añado nuevos vdevs?

No en la forma que la gente espera. Las nuevas escrituras tenderán a ir al nuevo espacio, pero los bloques existentes permanecen donde están a menos que se reescriban (o uses estrategias específicas de re-balanceo). Esta es otra razón por la que los planes de partición “lo arreglaremos después” suelen envejecer mal.

10) ¿Cuál es la señal más rápida de que mi equipo piensa en particiones en lugar de ZFS?

Si el documento de diseño habla más sobre “tallar discos” que sobre número de vdevs, ancho de vdev, dominios de fallo y comportamiento de reconstrucción, estás en territorio de particiones.

Conclusión

ZFS recompensa a quienes diseñan pensando en topología, dominios de fallo y la realidad de la carga. Castiga a quienes diseñan con tablas de particiones y optimismo. El “pensamiento en particiones” seduce porque parece flexibilidad, pero en producción suele ser solo acoplamiento oculto: cuellos de botella compartidos, fallos correlacionados y procedimientos de recuperación que requieren humanos perfectos bajo estrés.

Si quieres un pool ZFS que se comporte como un sistema profesional—predecible, diagnosticable y sobrevivible—diseña alrededor de los vdevs, usa datasets para separación, mantén roles en dispositivos físicos dedicados y estandariza lo básico operativo. El enfoque aburrido gana, no porque sea aburrido, sino porque deja menos espacio para que la física te sorprenda.

← Anterior
Dimensionamiento DDT de ZFS: predecir la RAM necesaria antes de activar la deduplicación
Siguiente →
Anillo Rojo de la Muerte: el desastre térmico del Xbox 360 que costó miles de millones

Deja un comentario