vdevs de ZFS: la regla que rompes una vez y lamentarás para siempre

¿Te fue útil?

Hay una regla en ZFS que suena a superstición hasta que has visto un pool arrastrarse durante un largo resilver mientras suena tu teléfono de guardia: los vdevs son la unidad de redundancia, rendimiento y arrepentimiento. Puedes cambiar discos. Puedes ajustar datasets. Puedes añadir vdevs. Pero una vez que eliges un diseño de vdev, efectivamente has elegido la personalidad del pool para el resto de su vida.

Esto no es una advertencia teórica dada en una pizarra. Es una verdad de producción aprendida a la fuerza en centros de datos donde el almacenamiento “solo tiene que funcionar” y en nubes donde “solo tiene que ser barato”. ZFS hará exactamente lo que le dijiste que hiciera—brillantemente, implacablemente y sin ninguna simpatía por tus suposiciones equivocadas.

La regla que rompes una vez

La regla es simple: Nunca construyas un pool en el que no puedas articular—en voz alta—cómo lo vas a expandir, reemplazar y sobrevivir a un resilver largo sin poner en riesgo el negocio.

En la práctica, esa regla se reduce a decisiones sobre vdevs:

  • La redundancia vive dentro de un vdev. Un pool es “tan redundante como su vdev menos redundante”, y fallará si cualquier vdev de nivel superior falla.
  • El rendimiento se agrega a través de vdevs. Más vdevs generalmente significa más IOPS y más paralelismo; los vdevs RAIDZ anchos no se comportan como “más discos = más velocidad” de la forma que la gente espera.
  • La expansión es aditiva por vdev. Puedes añadir vdevs a un pool. Históricamente no podías eliminarlos (y aunque existen funciones más nuevas en situaciones específicas, aún deberías planificar como si la eliminación no formara parte de tu ciclo de vida).
  • La reparación (resilver) es por vdev y por dispositivo. Los vdevs más anchos implican más discos participando, más tiempo bajo estrés y a menudo más exposición a una segunda falla antes de que estés seguro de nuevo.

Aquí está la frase que uso cuando alguien propone un diseño “creativo” de vdev para ahorrar en una reunión de presupuesto: ZFS es un sistema de archivos con opiniones, y su opinión más fuerte es que la topología determina el destino.

Broma #1 (corta y relevante): La forma más rápida de aprender diseño de vdevs en ZFS es construir el incorrecto—porque ZFS se asegurará de que lo recuerdes.

Vdevs como modelo mental: la topología vence a la sintonía

Si has administrado controladoras RAID, estás acostumbrado a pensar en términos de “el grupo RAID” y “el LUN”. ZFS colapsa esas ideas. Un pool se construye a partir de vdevs; los datasets viven en el pool; ZFS reparte las escrituras entre vdevs para balancear espacio y rendimiento.

Qué es realmente un vdev

Un vdev es un dispositivo virtual que provee almacenamiento a un pool. Ese vdev puede ser:

  • un disco único (sin redundancia; no hagas esto en producción a menos que aceptes explícitamente perderlo),
  • un mirror (dos o más discos, copias de los datos),
  • un grupo RAIDZ (paridad simple, doble, triple: raidz1/2/3),
  • un vdev especial (metadata y/o bloques pequeños en medios más rápidos),
  • un registro (SLOG) para acelerar escrituras síncronas,
  • un cache (L2ARC).

Sólo algunos de esos contribuyen a la capacidad principal de almacenamiento (vdevs de datos y vdevs especiales, según la configuración). Y sólo algunos son requeridos para que el pool siga funcionando.

Por qué el vdev es el dominio de fallo

Si construyes un pool con cuatro mirrors, puedes perder un disco en cada mirror y seguir funcionando. Si construyes un pool con dos vdevs raidz2, puedes perder dos discos en el mismo vdev (no en cualquier parte del pool) y seguir funcionando. Ese detalle de “dónde aterrizan las fallas” es lo que arruina matemáticas de hoja de cálculo que, por lo demás, parecen decentes.

Operativamente, no puedes elegir dónde fallan los discos. Puedes elegir el radio de impacto cuando lo hacen.

Por qué el vdev es la unidad de rendimiento

ZFS distribuye las escrituras entre vdevs, no entre discos individuales. Un pool con más vdevs tiende a entregar más IOPS porque ZFS puede emitir más IO independientes en paralelo. Por eso “un RAIDZ2 enorme con 12 discos” a menudo decepciona comparado con “seis pares en mirror”, aunque ambos usen 12 discos.

Un vdev RAIDZ puede ofrecer buen rendimiento secuencial, pero el IO aleatorio y la latencia se comportan de forma diferente. Un mirror puede satisfacer lecturas desde cualquiera de los discos y manejar escrituras aleatorias pequeñas sin la sobrecarga de paridad. RAIDZ tiene que hacer cálculo de paridad y patrones de read-modify-write para actualizaciones pequeñas. ZFS mitiga parte de esto con copy-on-write y grupos de transacciones, pero no puedes afinarte fuera de las leyes de la física.

La trampa de “puedes añadir vdevs”

Sí, puedes expandir un pool añadiendo vdevs. Eso suena a libertad. La trampa es que no puedes (prácticamente) “re-balancear” los datos de la manera que la gente imagina a partir de sistemas distribuidos. ZFS asignará nuevas escrituras a los vdevs nuevos, pero los datos existentes permanecen donde están a menos que se reescriban. Tu dataset caliente del año pasado permanece en el vdev del año pasado a menos que lo migres proactivamente.

Además, una vez que añades un vdev, el pool depende de ese vdev para siempre. Si añades un vdev de disco único “temporal” para sobrevivir la semana, acabas de crear un punto único de fallo permanente. Esa semana se convierte en un año. Siempre se convierte en un año.

Hechos interesantes y contexto histórico

La ingeniería de almacenamiento está llena de folclore. Aquí hay datos concretos de contexto que hacen que las reglas de vdevs de ZFS parezcan menos arbitrarias:

  1. ZFS se diseñó en Sun con la integridad de extremo a extremo como objetivo central, no como un añadido. Los checksums en cada bloque no son una característica; son la forma de ver el mundo.
  2. RAIDZ existe porque RAID-5/6 tradicional tiene el problema del “write hole” (pérdida de energía durante actualizaciones de stripe puede dejar la paridad inconsistente). El modelo transactional copy-on-write de ZFS evita esa clase de corrupción.
  3. El “disco de 1 TB” que hizo RAID-5 aterrador se convirtió en “discos de 18 TB” que lo hicieron existencial. A medida que crecieron los discos, las ventanas de reconstrucción/resilver crecieron, y la probabilidad de encontrar un error durante la reconstrucción dejó de ser un detalle despreciable.
  4. Los scrubs de ZFS no son higiene opcional; son cómo conviertes la corrupción silenciosa en corrupción detectada y corregida. Sin scrubs, apuestas tus backups y tu suerte contra la degradación de bits.
  5. Los discos con sectores 4K hicieron de la alineación (ashift) una decisión permanente. Pools mal alineados pueden sufrir una pérdida silenciosa de rendimiento que dura toda la vida del pool.
  6. La gente solía “arreglar” la latencia con la caché de una controladora RAID y luego descubrieron que habían construido una máquina de corrupción cuando las unidades de batería envejecieron. ZFS llevó el caching al SO y dejó el comportamiento ante pérdida de energía explícito.
  7. OpenZFS se convirtió en un ecosistema multi-SO, por eso ves diferencias en valores por defecto, herramientas y flags entre plataformas. Las reglas de vdevs permanecen obstinadamente consistentes.
  8. dRAID existe en gran parte para abordar el tiempo de reconstrucción y el riesgo a escala distribuyendo capacidad de repuesto y acelerando el comportamiento de reemplazo/resilver, especialmente en grandes grupos estilo RAIDZ.
  9. Los vdevs especiales son más nuevos pero operativamente peligrosos cuando se malentienden: si pones metadata en un vdev especial y lo pierdes, el pool puede perderse efectivamente aunque los discos de datos estén bien.

Mirrors, RAIDZ, dRAID y vdevs especiales: compensaciones reales

Mirrors: aburridos, rápidos y caros (en buen sentido)

Los mirrors son la recomendación por defecto para cargas mixtas porque se comportan bien bajo aleatoriedad, fallan de forma predecible y resilverizan relativamente rápido (especialmente con soporte de resilver secuencial y si el pool no está completamente lleno). Los mirrors también te dan más vdevs por el mismo número de discos, lo que significa más paralelismo.

Pero los mirrors te cuestan capacidad bruta: mirrors de dos vías reducen el espacio usable aproximadamente a la mitad. Los mirrors de tres vías son la opción “nunca quiero volver a hablar de esto” para sistemas críticos, al costo de dos tercios de la capacidad bruta.

RAIDZ: eficiencia de capacidad con advertencias de rendimiento

RAIDZ es atractivo cuando necesitas capacidad y tu carga es más secuencial o orientada a bloques grandes. RAIDZ2 suele ser la base para pools nearline o “esto es caro de reconstruir”. RAIDZ1 aún se usa en algunos lugares, pero cada vez es más una decisión de riesgo que una decisión de ingeniería.

Las dos grandes trampas operativas con RAIDZ son:

  • Latencia en escrituras aleatorias pequeñas, especialmente bajo carga, porque las actualizaciones de paridad no son gratis.
  • Resilvers largos a medida que los discos crecen, y la incómoda realidad de que el resilver estresa los discos restantes mientras ya estás degradado.

El ancho del RAIDZ importa. Vdevs RAIDZ muy anchos pueden lucir bien en una tabla de capacidad y luego castigarte con ventanas de reconstrucción y latencias de cola impredecibles en el peor momento.

dRAID: la respuesta para chasis grandes

dRAID (RAID distribuido) está diseñado para pools grandes donde los tiempos de reconstrucción clásicos de RAIDZ se vuelven inaceptables. Al distribuir la paridad y el espacio de repuesto a través de muchos discos, puede reducir el tiempo para restaurar la redundancia después de una falla y disminuir la ineficiencia de “el spare se queda inactivo hasta el desastre”.

No es una varita mágica. Aún necesitas entender los dominios de fallo, el nivel de paridad y el flujo operativo para reemplazos. Pero si estás construyendo estanterías JBOD grandes y te importa el tiempo de resilver, dRAID merece una consideración seria.

Vdevs especiales: multiplicador de rendimiento con filos afilados

Los vdevs especiales pueden almacenar metadata (y opcionalmente bloques pequeños) en almacenamiento más rápido como SSDs. Bien diseñados, pueden transformar el rendimiento de metadata del sistema de archivos, los recorridos de directorios y cargas de trabajo de archivos pequeños. Mal diseñados, pueden crear un dominio de fallo más pequeño que tumbe todo el pool.

Regla general: si un vdev especial contiene metadata, trátalo como un vdev de datos de primera clase con redundancia. Míralo en espejo. Monitóralo. Reemplázalo proactivamente.

SLOG y la mala interpretación de las escrituras síncronas

SLOG no es una caché de escritura. Es un dispositivo de registro separado usado sólo para escrituras síncronas. Si tu carga es mayormente asíncrona (común en muchas aplicaciones), un SLOG puede no hacer nada. Si tu carga es síncrona (bases de datos, NFS con sync, ciertos patrones de almacenamiento de VM), un buen SLOG puede reducir la latencia dramáticamente—si es seguro ante pérdida de energía y rápido a bajas colas.

Broma #2 (corta y relevante): Comprar un SLOG para una carga asíncrona es como instalar un alerón de coche de carreras en una furgoneta de reparto—cambia la apariencia, no el tiempo por vuelta.

Tres mini-historias del mundo corporativo

1) Incidente causado por una suposición equivocada: “Siempre podremos eliminar eso después”

La empresa estaba en plena migración. Se retiraba un SAN legado y se construyó un nuevo appliance ZFS (whitebox, diseño competente) para tomar el relevo. El equipo de almacenamiento dimensionó el pool de forma conservadora: vdevs en mirror, buen monitoreo, restauraciones probadas. Luego el cronograma del proyecto se retrasó.

Un equipo de producto apareció con un nuevo dataset que no cabía. La solución más fácil a corto plazo pareció inofensiva: añadir un disco grande único como vdev “temporal” hasta que termine la compra. El pool lo aceptó. El dataset aterrizó. La crisis pasó. Todos volvieron a sus trabajos reales.

Seis meses después, el “disco temporal” seguía allí. No estaba en el plan de reemplazo original. No estaba en la hoja de cálculo que llevaba las fechas de garantía. Tampoco estaba en espejo. Una mañana, empezó a lanzar errores de lectura. ZFS hizo lo que ZFS hace: marcó el vdev como fallado, y todo el pool cayó porque un pool no puede sobrevivir la pérdida de ningún vdev de nivel superior.

El postmortem fue sombrío no porque la falla fuera exótica, sino porque fue aburrida. La suposición equivocada no fue “los discos fallan”. Fue “podemos deshacer fácilmente los cambios de topología”. Terminaron haciendo una migración de emergencia fuera del pool, bajo presión de tiempo, hacia la capacidad de repuesto que pudieron encontrar. El impacto en el negocio no vino del disco muerto; vino de la decisión de topología que convirtió un disco único en una dependencia a nivel de pool.

La solución fue directa pero dolorosa: reconstruir el pool correctamente y migrar los datos de vuelta. La lección quedó: no existe eso de vdev de nivel superior temporal.

2) Optimización que salió mal: “Un RAIDZ ancho es más simple”

Otra organización tenía un nuevo clúster de analítica. Ejecutaban grandes escaneos secuenciales por la noche, pero el día era interactivo: dashboards, consultas ad-hoc y mucho IO aleatorio pequeño. Alguien propuso un único vdev RAIDZ2 ancho para maximizar espacio usable y simplificar la gestión. Menos vdevs, menos piezas móviles, un conjunto de discos de paridad. El plan parecía limpio.

En la primera prueba de carga, el throughput secuencial fue excelente. Todos celebraron. Luego llegó producción. Las consultas diurnas empezaron a mostrar picos de latencia de cola larga. No lentitud constante—peor. Cada pocos minutos, algo se detenía lo suficiente como para que los timeouts de la aplicación saltaran. Las gráficas de almacenamiento parecían “bien en promedio”, que es como los problemas de almacenamiento se ocultan en los dashboards corporativos.

La causa raíz no fue misteriosa. Fue la desalineación entre la carga de trabajo y el comportamiento del vdev. El RAIDZ2 ancho tenía buen ancho de banda pero luchaba con IO pequeño y mixto bajo concurrencia. El pool tenía un vdev de datos, por lo que ZFS tenía lugares limitados para programar trabajo en paralelo. Súmale un pool moderadamente lleno, algo de fragmentación con el tiempo, y la latencia interactiva se volvió fea.

Intentaron lo habitual: ajustes de recordsize, cambios de compresión, más RAM, incluso un L2ARC. Las mejoras fueron marginales porque el limitador central era estructural. Finalmente reconstruyeron como múltiples vdevs mirror y el problema desapareció. La “optimización” salió mal porque optimizó la métrica equivocada—TB utilizables—a costa de la métrica que los usuarios realmente percibían: latencia p99.

La moraleja silenciosa: la simplicidad es genial, pero un pool de vdev único rara vez es simple en producción.

3) Práctica aburrida pero correcta que salvó el día: “Scrubs, repuestos y disciplina de reemplazo”

Esta historia no aparece en los diagrams de arquitectura porque no es sexy. Una empresa mediana ejecutaba ZFS para almacenamiento de VM con vdevs mirror, utilización conservadora de capacidad y un cronograma: scrubs mensuales, alertas por errores de checksum y una política de reemplazar cualquier disco que mostrara errores repetidos aunque no hubiera fallado por completo.

Un trimestre, un lote de discos empezó a mostrar problemas intermitentes de lectura. No suficientes para disparar una falla inmediata, pero sí lo bastante para acumular errores de checksum. Los scrubs lo detectaron temprano. El equipo no discutió con los discos. Los reemplazaron ordenadamente, un miembro del mirror a la vez, durante horas de trabajo, mientras el pool estaba sano.

Más tarde ese año, un evento de energía golpeó otro rack. Los sistemas se recuperaron, pero el mismo pool que había visto discos inestables habría estado en un estado peligroso si esos discos marginales aún hubieran estado presentes. En su lugar, el pool volvió limpio. Sin vdevs degradados. Sin resilvers de emergencia en medios ya enfermos. La respuesta al incidente fue casi aburrida: verificar estado, verificar calendario de scrubs, seguir adelante.

La práctica que los salvó no fue un parámetro de afinamiento ingenioso. Fue disciplina operativa: scrubs, monitoreo y reemplazo proactivo. En almacenamiento, lo aburrido es una característica.

Tareas prácticas: comandos + interpretación

Estas son las tareas que realmente ejecuto en producción cuando estoy validando diseño de vdevs, diagnosticando problemas o limpiando después de que algo salió mal. Los comandos asumen OpenZFS en un sistema tipo Linux; ajusta los nombres de dispositivos y pools según corresponda.

Tarea 1: Inspeccionar la topología del pool (el suero de la verdad)

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_1       ONLINE       0     0     0
            ata-SAMSUNG_SSD_2       ONLINE       0     0     0
          raidz2-1                  ONLINE       0     0     0
            ata-WDC_1               ONLINE       0     0     0
            ata-WDC_2               ONLINE       0     0     0
            ata-WDC_3               ONLINE       0     0     0
            ata-WDC_4               ONLINE       0     0     0
            ata-WDC_5               ONLINE       0     0     0
            ata-WDC_6               ONLINE       0     0     0

errors: No known data errors

Interpretación: Identifica los vdevs de nivel superior (mirror-0, raidz2-1). El pool falla si cualquiera de los vdevs de nivel superior falla. Se permiten tipos de vdev mezclados, pero pueden crear rendimiento desigual y un comportamiento de expansión incómodo.

Tarea 2: Obtener capacidad y fragmentación de un vistazo

cr0x@server:~$ zpool list -o name,size,alloc,free,capacity,health,fragmentation
NAME   SIZE  ALLOC   FREE  CAPACITY  HEALTH  FRAG
tank  100T    72T    28T       72%  ONLINE   31%

Interpretación: Capacidad por encima de ~80% y fragmentación en aumento son una receta común para quejas de latencia, especialmente en RAIDZ. La fragmentación no es inherentemente mala, pero se correlaciona con dificultad de asignación y amplificación de IO.

Tarea 3: Mostrar ashift (alineación de sector) por vdev

cr0x@server:~$ sudo zdb -C tank | egrep -i 'vdev|ashift' | head -n 30
vdev_tree:
    type: 'root'
    id: 0
    guid: 123456789
    children[0]:
        type: 'mirror'
        id: 0
        ashift: 12
    children[1]:
        type: 'raidz'
        id: 1
        ashift: 12

Interpretación: ashift=12 significa sectores 4K. ashift es efectivamente permanente para ese vdev. Si por error construiste con ashift=9 en discos 4K, podrías ver amplificación de escritura persistente y mal rendimiento.

Tarea 4: Identificar datasets con sync habilitado (relevancia del SLOG)

cr0x@server:~$ zfs get -r -o name,property,value sync tank
NAME         PROPERTY  VALUE
tank         sync      standard
tank/vm      sync      always
tank/backups sync      disabled

Interpretación: Si datasets importantes están en sync=always, un SLOG adecuado puede importar. Si la mayoría están en standard y tus apps no hacen escrituras sync, el SLOG no moverá la aguja.

Tarea 5: Confirmar elecciones de recordsize y volblocksize

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

cr0x@server:~$ zfs get -o name,property,value volblocksize tank/vm-zvol
NAME         PROPERTY     VALUE
tank/vm-zvol volblocksize 16K

Interpretación: recordsize importa para sistemas de archivos; volblocksize importa para zvols y no es trivial de cambiar después de la creación. Desajustes pueden crear overhead de read-modify-write y mal comportamiento de compresión.

Tarea 6: Observar IO y latencia en tiempo real por vdev

cr0x@server:~$ sudo zpool iostat -v tank 2
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                         72T    28T    120    800    15M   110M
  mirror-0                  1.2T   0.8T     90    500    12M    60M
    ata-SAMSUNG_SSD_1         -      -      45    250     6M    30M
    ata-SAMSUNG_SSD_2         -      -      45    250     6M    30M
  raidz2-1                  70T    27T     30    300     3M    50M
    ata-WDC_1                 -      -       5     50   0.5M   8.5M
    ...

Interpretación: Si un vdev está saturado o muestra trabajo desproporcionado, has encontrado tu cuello de botella. Los pools no “promedian” mágicamente un vdev lento; se encolan detrás de él cuando las asignaciones aterrizan allí.

Tarea 7: Revisar contadores de errores y detectar un disco “muriendo en silencio”

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

        NAME                      STATE     READ WRITE CKSUM
        tank                      ONLINE       0     0     0
          mirror-0                ONLINE       0     0     0
            ata-SAMSUNG_SSD_1     ONLINE       0     0     0
            ata-SAMSUNG_SSD_2     ONLINE       0     0     0
          mirror-1                ONLINE       0     0     0
            ata-WDC_7             ONLINE       0     0    12
            ata-WDC_8             ONLINE       0     0     0

errors: No known data errors

Interpretación: Errores CKSUM en un dispositivo suelen ser cableado, controladora o el propio disco. “No known data errors” significa que ZFS corrigió lo que pudo, pero tu hardware está enviando datos malos. No normalices errores de checksum.

Tarea 8: Borrar errores transitorios después de arreglar hardware (solo tras evidencia)

cr0x@server:~$ sudo zpool clear tank

Interpretación: Borrar errores esconde el historial. Hazlo después de haber reemplazado un cable/HBA/disco y querer confirmar que el problema se fue. Si los errores vuelven, todavía estás en el radio de impacto.

Tarea 9: Reemplazar un disco fallado en un mirror

cr0x@server:~$ sudo zpool offline tank ata-WDC_7
cr0x@server:~$ sudo zpool replace tank ata-WDC_7 /dev/disk/by-id/ata-WDC_NEW_7
cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
config:

        NAME                         STATE     READ WRITE CKSUM
        tank                         ONLINE       0     0     0
          mirror-1                   ONLINE       0     0     0
            replacing-0              ONLINE       0     0     0
              ata-WDC_7              OFFLINE      0     0     0
              ata-WDC_NEW_7          ONLINE       0     0     0  (resilvering)
            ata-WDC_8                ONLINE       0     0     0

errors: No known data errors

Interpretación: Usa rutas de dispositivo estables (by-id). Observa el resilver. Si el resilver está inesperadamente lento, revisa utilización del pool, contención de IO y si estás golpeando un dispositivo lento.

Tarea 10: Monitorizar progreso y velocidad del resilver

cr0x@server:~$ sudo zpool status tank
  scan: resilver in progress since Tue Dec 24 10:12:03 2025
        3.20T scanned at 540M/s, 1.10T issued at 185M/s, 72T total
        1.10T resilvered, 1.53% done, 4 days 10:21:19 to go

Interpretación: “Scanned” vs “issued” te dice sobre throttling y contención de IO. Si “issued” es bajo, el pool está demasiado ocupado o un vdev/dispositivo es lento. Durante el resilver, tu margen de redundancia está reducido; trátalo como un incidente hasta que termine.

Tarea 11: Ejecutar un scrub y entender su coste

cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zpool status tank
  scan: scrub in progress since Tue Dec 24 12:00:00 2025
        9.80T scanned at 1.1G/s, 2.40T issued at 270M/s, 72T total
        0B repaired, 3.33% done, 0 days 18:10:40 to go

Interpretación: Los scrubs consumen IO. Prográmalos, pero no los saltes. Un scrub que encuentra errores de checksum no es “mala suerte”; es un sistema de alerta temprana haciendo su trabajo.

Tarea 12: Mostrar ratio de compresión y confirmar que no te autoengañas

cr0x@server:~$ zfs get -o name,property,value,source compression,compressratio tank
NAME  PROPERTY       VALUE  SOURCE
tank  compression    zstd   local
tank  compressratio  1.72x  -

Interpretación: La compresión puede ser un multiplicador de capacidad y a veces una ganancia de rendimiento, pero cambia los patrones de escritura y el uso de CPU. Si compressratio es ~1.00x, no estás ganando mucho.

Tarea 13: Identificar dolor por metadata (candidatos a vdev especial)

cr0x@server:~$ zfs get -o name,property,value primarycache,secondarycache tank/home
NAME       PROPERTY        VALUE
tank/home  primarycache    all
tank/home  secondarycache  all

cr0x@server:~$ sudo zpool iostat -v tank 2 | head -n 20

Interpretación: Si tu carga son recorridos de directorio, archivos pequeños y churn de metadata, el problema puede ser latencia en IO de metadata. Los vdevs especiales pueden ayudar, pero sólo cuando se diseñan con redundancia y se monitorean como si tu trabajo dependiera de ello (porque depende).

Tarea 14: Revisar salud del ARC y si estás falto de memoria

cr0x@server:~$ grep -E 'c_min|c_max|size|hits|misses' /proc/spl/kstat/zfs/arcstats | head
c_min                           4    8589934592
c_max                           4    68719476736
size                            4    53687091200
hits                            4    2147483648
misses                          4    268435456

Interpretación: ARC es tu primera caché. Si los misses son altos y la latencia es mala, podrías estar acotado por IO o simplemente con poca caché. No compres SSDs inmediatamente; verifica si RAM es la mejora de rendimiento más barata.

Manual de diagnóstico rápido

Este es el flujo de “tienes 15 minutos antes de que el canal de incidentes se derrita”. El objetivo es identificar si el cuello de botella es la topología, un dispositivo específico, comportamiento sync, presión de capacidad o algo aguas arriba.

Primero: ¿El pool está sano y ya estás degradado?

cr0x@server:~$ sudo zpool status -x
pool 'tank' is healthy

Si no está sano: deja de fingir que esto es un “problema de rendimiento”. Los pools degradados se comportan diferente, los resilvers compiten con la carga y el riesgo está elevado.

Segundo: ¿Un vdev o un disco está lento o con errores?

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

Qué buscas: un dispositivo con ancho de banda mucho menor, errores altos, o un vdev que asume operaciones desproporcionadas. Un único disco malo puede arrastrar todo un vdev RAIDZ a un infierno de latencia.

Tercero: ¿Estás limitado por capacidad (espacio o fragmentación)?

cr0x@server:~$ zpool list -o name,capacity,fragmentation
NAME  CAPACITY  FRAG
tank      89%   54%

Interpretación: Alta capacidad más alta fragmentación es un impulsor clásico de stalls en asignación. La “solución” rara vez es un sysctl. Usualmente es “añadir vdevs, liberar espacio o migrar”.

Cuarto: ¿Estás pagando por escrituras síncronas?

cr0x@server:~$ zfs get -r sync tank | head
cr0x@server:~$ sudo zpool status tank | egrep -i 'logs|log'

Interpretación: Si sync está habilitado y no tienes SLOG (o tienes uno malo), la latencia puede dispararse bajo cargas con muchos fsync. Si sync está deshabilitado en todas partes, no persigas fantasmas de SLOG.

Quinto: ¿El ARC está haciendo su trabajo, o estás leyendo constantemente desde disco?

cr0x@server:~$ awk '{print $1,$3}' /proc/spl/kstat/zfs/arcstats | egrep 'hits|misses'
hits 2147483648
misses 268435456

Interpretación: Un aumento en la tasa de misses bajo una carga de lectura puede indicar presión de memoria o un conjunto de trabajo mayor que el ARC. También puede indicar que tu patrón de IO es inherentemente no cacheable (escaneos grandes).

Sexto: Confirma la carga y ajusta la topología

Esta parte es humana, no un comando. Pregunta:

  • ¿Es esto mayormente IO aleatorio pequeño (VMs, bases de datos)? Los mirrors suelen ganar.
  • ¿Es esto mayormente IO secuencial grande (backups, media)? RAIDZ puede estar bien.
  • ¿Estamos mezclando cargas intensas en metadata con almacenamiento en bloque? Considera vdevs especiales—con cuidado.
  • ¿Añadimos recientemente un vdev nuevo y esperábamos que los datos antiguos se reequilibraran? No lo hicieron.

Errores comunes: síntomas específicos y arreglos

Error 1: Añadir un vdev de disco único “temporal”

Síntoma: El pool queda a un fallo de disco de un outage total; luego, un disco falla y todo el pool cae.

Arreglo: No lo hagas. Si ya lo hiciste: migra los datos fuera, reconstruye el pool correctamente, migra de vuelta. Si debes añadir capacidad urgentemente, añade un vdev redundante (mirror o RAIDZ) que cumpla tus requisitos de durabilidad.

Error 2: Construir un RAIDZ gigante y esperar IOPS de mirror

Síntoma: Buenas pruebas secuenciales, latencia p95/p99 terrible bajo carga mixta; “el throughput promedio se ve bien”.

Arreglo: Rediseña con más vdevs (a menudo mirrors) o múltiples vdevs RAIDZ con anchos sensatos. Deja de intentar ajustar alrededor de una desalineación topológica.

Error 3: Ignorar ashift y la alineación de sectores

Síntoma: Latencia crónica en escrituras y throughput inferior al esperado, especialmente en SSDs; sin errores obvios.

Arreglo: Verifica ashift con zdb -C. Si está mal, la solución real es reconstruir/migrar. No puedes “arreglar” ashift en sitio de forma fiable.

Error 4: Tratar los vdevs especiales como una caché

Síntoma: Pérdida de pool o riesgo severo de corrupción tras la falla de un vdev especial; la metadata queda inaccesible aunque los discos de datos estén sanos.

Arreglo: Ponlos en mirror (u otra protección). Monitóralos como vdevs de datos. Usa SSDs de alta resistencia. Planifica reemplazos.

Error 5: Comprar un SSD barato para SLOG

Síntoma: La latencia de escrituras síncronas no mejora, o empeora; stalls ocasionales; el dispositivo se desgasta rápido.

Arreglo: Usa un dispositivo con protección ante pérdida de energía y baja latencia. Confirma que tu carga usa escrituras síncronas. Valida con latencias a nivel de aplicación, no sólo contadores de ZFS.

Error 6: Operar demasiado lleno (pool al límite)

Síntoma: Las escrituras se detienen, los tiempos de scrub/resilver se disparan, la fragmentación sube y aparecen “cosas raras” bajo carga.

Arreglo: Mantén margen de espacio libre. Añade vdevs antes de llegar al precipicio. Si ya estás lleno, migra datos fríos o amplía inmediatamente.

Error 7: Mezclar tamaños de disco esperando resultados gráciles

Síntoma: Los mirrors desperdician capacidad, los vdevs RAIDZ limitan al disco más pequeño, la expansión se vuelve desordenada.

Arreglo: Mantén miembros de vdev uniformes cuando sea posible. Si debes mezclar, hazlo intencionalmente y documenta cómo afecta al espacio usable y la estrategia de reemplazo.

Error 8: Confundir “zpool add” con una “actualización”

Síntoma: Alguien añade un vdev esperando que un RAIDZ existente aumente su ancho; luego se dan cuenta de que la topología quedó mezclada para siempre.

Arreglo: La expansión añadiendo vdevs no es lo mismo que cambiar la forma de un vdev. Planifica el ancho de vdev desde el principio; usa vdevs adicionales para crecimiento.

Listas de verificación / plan paso a paso

Paso a paso: Diseñar un pool que no detestes

  1. Escribe la carga en una frase: “almacenamiento de VM con escrituras aleatorias”, “objetivo de backup con escrituras secuenciales”, “homes NFS con churn de metadata”, etc.
  2. Elige tu tolerancia a fallos: cuántos discos pueden fallar en el mismo vdev sin causar outage. Elige mirror/raidz2/raidz3 según eso.
  3. Escoge el ancho de vdev intencionalmente: no uses “todos los discos en un grupo”. Prefiere más vdevs sobre vdevs más anchos para cargas IOPS-intensivas.
  4. Decide cómo vas a expandir: “añadir otro par mirror por trimestre”, o “añadir otro vdev raidz2 de 6 discos”, etc.
  5. Decide cómo reemplazarás discos: nombres by-id, ventanas de mantenimiento, repuestos en mano, procedimiento documentado.
  6. Configura ashift correctamente antes de crear el pool. Trátalo como permanente.
  7. Planifica scrubs y monitoreo: cadencia de scrub, umbrales de alerta (errores checksum, resilvers lentos) y quién es pagado.
  8. Mantén margen: define un techo de capacidad que dispare expansión antes de que el rendimiento colapse.
  9. Prueba comportamiento degradado: simula un disco offline y observa el impacto en la aplicación; valida el tiempo de resilver bajo carga representativa.

Paso a paso: Validación previa al vuelo antes de comprometer datos

  1. Confirma topología y redundancia.
  2. Confirma ashift.
  3. Confirma propiedades de datasets para el uso previsto (recordsize, compression, atime, sync).
  4. Ejecuta una prueba de carga representativa que incluya IO mixto y mida latencia de cola.
  5. Extrae un disco (u oflínalo) en staging y observa el resilver y la aplicación.

Checklist operativo: cuando falla un disco

  1. Confirma estado del pool (zpool status).
  2. Identifica el disco físico exacto (mapeo by-id al bahía del chasis).
  3. Verifica si el pool ya está bajo scrub/resilver.
  4. Reduce la carga evitable si es posible; resilverizar mientras está saturado extiende la ventana de riesgo.
  5. Reemplaza el disco usando rutas de dispositivo estables; monitoriza el resilver hasta completarlo.
  6. Después de completar, ejecuta un scrub si tienes alguna razón para dudar de la integridad de los datos.

Preguntas frecuentes

1) ¿Cuál es realmente la “regla única” sobre vdevs?

Diseña los vdevs como si fueras a quedarte con ellos para siempre—porque lo harás. Puedes añadir vdevs, pero no puedes deshacer casualmente una mala decisión de vdev de nivel superior sin migrar datos.

2) ¿Está bien mezclar mirrors y vdevs RAIDZ en un mismo pool?

Está permitido y a veces es práctico (por ejemplo, añadir un vdev especial o añadir un vdev mirror para aumentar IOPS). Pero las topologías mezcladas pueden crear rendimiento desigual y un comportamiento de asignación confuso. Si lo haces, documenta por qué y cómo vas a expandir de forma consistente en el futuro.

3) ¿Por qué más vdevs suelen ayudar al rendimiento?

ZFS programa IO a través de vdevs de nivel superior. Más vdevs significa más colas independientes y más paralelismo. Un vdev ancho único puede convertirse en un cuello de botella para IO aleatorio y latencia.

4) ¿Debería usar RAIDZ1?

Sólo si has aceptado explícitamente el perfil de riesgo y la ventana de reconstrucción para tus tamaños de disco y carga, y tienes backups sólidos. Para muchos despliegues modernos con discos grandes, RAIDZ2 es la línea base más defendible.

5) ¿Agregar un vdev rebalancea los datos existentes?

No. Las nuevas asignaciones preferirán el vdev nuevo basadas en espacio libre y ponderación, pero los bloques antiguos generalmente permanecen donde están. Si necesitas mover datos, debes reescribirlos (send/receive, replicación o migración a nivel de aplicación).

6) ¿Necesito un SLOG?

Solo si tu carga emite escrituras síncronas y te importa la latencia sync. Confírmalo con la propiedad sync de los datasets y el comportamiento de la aplicación. Si lo necesitas, usa un dispositivo con protección ante pérdida de energía.

7) ¿Los vdevs especiales son seguros?

Son seguros cuando se tratan como componentes críticos y redundantes. Son inseguros cuando se tratan como una caché que puedes perder. Si la metadata vive allí, perderla puede ser catastrófico.

8) ¿Cuál es un calendario sensato de scrubs?

La práctica común es mensual para muchos pools, a veces con mayor frecuencia en entornos de alto riesgo. La respuesta correcta depende de capacidad, carga y qué tan rápido quieres surfactar errores latentes. La respuesta equivocada es “nunca”.

9) ¿Por qué mi resilver toma una eternidad?

Causas comunes: alta utilización del pool, carga de producción intensa, discos lentos o marginales, problemas de controladora, o un vdev RAIDZ muy ancho. Revisa zpool status (issued vs scanned), zpool iostat -v y contadores de errores de hardware.

10) ¿Cuál es la estrategia de expansión más segura?

Añade vdevs que coincidan con tu perfil existente de redundancia y rendimiento, mantén anchos de vdev consistentes y expande antes de alcanzar los precipicios de rendimiento por alta utilización. Si debes cambiar el perfil, planifica una migración en lugar de un parche improvisado.

Conclusión

El diseño de vdevs en ZFS no es un arte oscuro. Es simplemente implacable. El sistema de archivos aceptará con gusto tu “disco temporal”, tu RAIDZ demasiado ancho, tu vdev especial mal protegido y tu ashift mal alineado—y luego ejecutará esas decisiones en producción a gran escala, bajo estrés, a las 3 a.m.

Si te llevas una cosa de esto: los vdevs no son un detalle de configuración; son el contrato que firmas con tu yo futuro. Firma algo con lo que puedas vivir: redundancia que puedas explicar, rendimiento que puedas predecir, expansión que puedas ejecutar y prácticas operativas aburridas que te mantengan fuera de llamadas de incidentes donde el almacenamiento está técnicamente “bien” pero el negocio está en llamas.

← Anterior
El ingeniero del “bus factor”: cuando una sola persona controla todo el sistema
Siguiente →
Ubuntu 24.04: las VLAN no funcionan — la única bandera del bridge que la mayoría olvida

Deja un comentario