Dimensionamiento de vdev especial en ZFS: Qué tamaño debe tener (para no arrepentirte)

¿Te fue útil?

El vdev especial es una de esas características de ZFS que parece hacer trampa: coloca metadatos (y opcionalmente bloques pequeños) en SSD rápidos y observa cómo despierta tu pool.
Luego, un día, los SSD están al 92% de uso, las asignaciones se vuelven extrañas, la latencia de sync se dispara y tu “pool rápido” empieza a comportarse como si los datos se estuvieran pasando por una manguera de jardín.

Dimensionar un vdev especial no es una cuestión de sensaciones. Es matemáticas más paranoia operativa. Si lo haces mal no solo pierdes rendimiento: puedes perder el pool.
Si lo haces bien obtienes latencias predecibles, recorridos de directorio más rápidos, arranques de VM menos traumáticos y menos tickets a las 2 a.m. que empiezan con “el almacenamiento está lento”.

Qué hace realmente el vdev especial

Un pool ZFS normalmente almacena bloques de datos y bloques de metadatos a través de sus vdev “normales” (HDDs, SSDs o lo que sea que hayas montado).
Un vdev especial es una clase de asignación adicional que puede contener metadatos y, opcionalmente, bloques de datos pequeños.
El objetivo es sencillo: mantener lo aleatorio y sensible a la latencia en medios más rápidos.

¿Qué aterriza en un vdev especial?

  • Metadatos: bloques indirectos, dnodes, estructuras de directorio, punteros de bloque, spacemaps y otras “tareas de libro” necesarias para localizar y gestionar datos.
  • Opcionalmente, bloques pequeños cuando special_small_blocks está establecido en un dataset o zvol.

No es un L2ARC. No es un SLOG. No es una “caché” que puedas perder sin consecuencias.
Si pones metadatos críticos del pool en un vdev especial, perderlo puede significar perder el pool.

Aquí está la verdad operativa: los vdevs especiales son fantásticos, pero no son indulgentes.
La pregunta de dimensionamiento no es “¿cuál es el mínimo que funciona?”, sino “¿cuál es el mínimo que sigue funcionando después de dos años de churn, snapshots y malas ideas?”.

Broma #1: El vdev especial es como un cajón de trastos: si lo haces demasiado pequeño, todo igual entra, solo que deja de cerrarse.

Los metadatos son pequeños… hasta que dejan de serlo

La gente subestima los metadatos porque imagina “nombres de archivo y marcas de tiempo”.
Los metadatos de ZFS incluyen las estructuras que hacen funcionar copy-on-write, snapshots, checksums, compresión y los árboles de punteros de bloque.
Más bloques y más fragmentación significan más metadatos. Muchos archivos pequeños significan más metadatos. Muchas snapshots significan más metadatos.

Si además rediriges bloques pequeños al vdev especial, tu “dispositivo de metadatos” se convierte en un dispositivo de metadatos más datos calientes.
Eso está bien—a menudo es excelente—pero tus supuestos sobre dimensionamiento y resistencia deben cambiar.

Hechos y contexto histórico (para entender el comportamiento)

Algunos hechos concretos ayudan a explicar por qué el dimensionamiento del vdev especial se siente contraintuitivo y por qué un valor predeterminado incorrecto puede funcionar en silencio durante meses antes de explotar.

  1. Las clases de asignación especiales de ZFS llegaron relativamente tarde respecto a las funcionalidades núcleo; el ZFS temprano dependía más de layouts “todos los vdev son iguales”,
    además de L2ARC/SLOG para moldear el rendimiento.
  2. El I/O de metadatos suele ser más aleatorio que el I/O de datos. ZFS puede transmitir grandes lecturas de datos, pero el acceso a metadatos tiende a rebotar por el árbol en disco.
  3. Copy-on-write multiplica el trabajo de metadatos. Cada nueva escritura actualiza punteros de bloque hacia arriba en el árbol, y las snapshots preservan punteros antiguos.
  4. Los dnodes aumentaron de tamaño con el tiempo. Funciones como dnodesize=auto y “fat dnodes” existen porque empaquetar más atributos en los dnodes evita I/O adicional,
    pero también cambia la huella y el layout de metadatos.
  5. La falla de un vdev especial puede ser catastrófica si almacena metadatos necesarios para ensamblar el pool. Esto no es teórico; es una consecuencia de diseño.
  6. Las diferencias de latencia entre dispositivos SSD y HDD siguen aumentando. NVMe moderno puede servir lecturas aleatorias en decenas de microsegundos; los HDDs están en milisegundos.
    Un delta de 100× en una carga de trabajo centrada en metadatos no es raro.
  7. La compresión y los registros pequeños cambian la economía. Cuando tu pool escribe muchos bloques pequeños comprimidos, los metadatos y la “calentura de bloques pequeños”
    empiezan a parecerse desde la perspectiva de I/O.
  8. Las snapshots aumentan el churn de metadatos. Cada snapshot mantiene rutas de punteros de bloque antiguas vivas; los deletes se convierten en “gestión de deadlist” en vez de reclamación inmediata.
  9. Expandir el pool es fácil; remediar un vdev especial no lo es. Puedes añadir vdevs para aumentar capacidad, pero no puedes quitar un vdev especial de la mayoría de sistemas productivos y sentarte a celebrar.

Parafraseando una idea de Werner Vogels (CTO de Amazon): “Todo falla todo el tiempo—diseña para la falla, no para el mejor escenario”.
El dimensionamiento del vdev especial es exactamente eso: diseña para los modos de falla, no para los benchmarks del día uno.

Principios de dimensionamiento que no envejecen mal

Principio 1: Decide qué problema estás resolviendo

Hay dos razones legítimas para añadir un vdev especial:

  • Aceleración de metadatos: listados de directorio más rápidos, aperturas de archivo, tormentas de stat, operaciones de snapshot y comportamiento con “muchos archivos pequeños”.
  • Aceleración de bloques pequeños: almacenar bloques por debajo de un umbral en SSD para reducir I/O aleatorio en HDDs y mejorar la latencia de lecturas/escrituras pequeñas.

Si solo quieres aceleración de metadatos, a menudo puedes mantenerlo modesto (pero no minúsculo).
Si quieres aceleración de bloques pequeños, estás construyendo un sistema de tiering parcial y debes dimensionarlo en consecuencia.

Principio 2: “Solo son metadatos” es cómo terminas intercambiando tu almacenamiento

Subdimensionar el vdev especial crea un resultado perverso: ZFS intenta colocar metadatos/bloques pequeños allí, se llena, las asignaciones se vuelven restringidas,
y de repente lo que añadiste para rendimiento se convierte en un cuello de botella y a veces en un factor de riesgo.

Principio 3: Mirrors para vdevs especiales en producción

Si te importa el pool, el vdev especial debería ser en mirror (o mejor).
Existen vdevs especiales RAIDZ en algunas implementaciones, pero los mirrors mantienen los dominios de fallo limpios y el comportamiento de rebuild predecible.
Además: NVMe falla de maneras excitantes. No siempre, pero lo suficiente como para asumir que puede suceder.

Principio 4: Planea para crecimiento y churn, no solo capacidad bruta

El vdev especial es sensible al churn: snapshots, deletes, cargas con reescritura intensiva y reorganizaciones de datasets pueden aumentar la presión de metadatos.
La planificación de capacidad debe incluir un impuesto por “tu yo futuro está más ocupado y es menos cuidadoso”.

Principio 5: Evita el patrón “un vdev especial tiny para todo”

El vdev especial aplica al pool entero, pero puedes controlar la colocación de bloques pequeños por dataset.
Eso significa que puedes ser selectivo. Si estableces special_small_blocks globalmente y lo olvidas, estás comprometiéndote al crecimiento del vdev especial.
Ser selectivo no es cobardía; es gestión del riesgo.

Broma #2: Los ingenieros de almacenamiento no creen en la magia—excepto cuando un dataset “temporal” vive en el vdev especial durante tres años.

Matemáticas de dimensionamiento que puedes defender en una revisión

No existe una fórmula perfecta porque el tamaño de metadatos depende de recordsize, compresión, distribución del número de archivos, snapshots y fragmentación.
Pero puedes llegar a una respuesta que sea conservadora, explicable y operativamente segura.

Paso 1: Decide si se incluyen los bloques pequeños

Si no vas a establecer special_small_blocks, estás dimensionando principalmente para metadatos.
Si lo vas a establecer (valores comunes: 8K, 16K, 32K), debes presupuestar también bloques pequeños de datos.

Paso 2: Usa reglas empíricas (luego valida)

Puntos de partida prácticos que no te costarán el empleo:

  • Vdev especial solo metadatos: parte de 0.5%–2% de la capacidad bruta del pool para cargas generales de archivos.
    Si tienes muchos archivos pequeños, muchas snapshots o alto churn, apunta más alto.
  • Metadatos + bloques pequeños: parte de 5%–15% dependiendo del umbral de bloques pequeños y la carga.
    Imágenes de VM con bloques de 8K–16K pueden consumir la capacidad especial muy rápido.

El “rango” de dimensionamiento no es indecisión; refleja que un pool que guarda 10 millones de archivos de 4K se comporta diferente que uno que guarda 20 TB de medios.

Paso 3: Convierte la regla empírica en un número concreto

Ejemplo: tienes un pool HDD bruto de 200 TB.

  • Solo metadatos al 1%: 2 TB en special.
  • Metadatos + bloques pequeños al 10%: 20 TB en special (ahora estás construyendo un tier, no un adorno).

Si esos números te parecen “demasiado grandes”, es que tu cerebro está anclado a la idea de que los metadatos son diminutos.
Tu futura caída no se preocupará por cómo te sientes.

Paso 4: Aplica un buffer de “no te encierres”

La ocupación del vdev especial da miedo operativamente porque puede restringir la asignación de metadatos.
Trátalo como un filesystem tipo log: no lo operas al 95% y lo celebras.

Una política razonable:

  • Uso en estado estable: 50–70%
  • Alerta en: 75%
  • Parar todo en: 85%

Paso 5: Ten en cuenta la sobrecarga por redundancia del vdev especial

Un vdev especial en mirror reduce a la mitad la capacidad usable. Dos NVMes de 3.84 TB te dan ~3.84 TB usable (menos slop/overhead).
Si tu cálculo dice “necesito 2 TB”, no compres “dos de 1.92 TB” y esperes. Compra más grande. La resistencia del SSD y la amplificación de escritura son reales.

Paso 6: Considera la endurance (DWPD) si los bloques pequeños van al special

Las escrituras de metadatos no son gratuitas, pero suelen ser manejables.
Los bloques pequeños pueden convertir el vdev especial en un tier con muchas escrituras, especialmente con VMs, bases de datos y alto churn.
Si estás redirigiendo bloques pequeños, selecciona SSDs con endurance adecuada y monitoriza las tasas de escritura.

El dimensionamiento del vdev especial también es una decisión de riesgo

Subdimensionar implica:

  • un precipicio de rendimiento cuando se llena,
  • pánico operativo durante picos de crecimiento,
  • y en casos peores, inestabilidad del pool si la asignación de metadatos se ve constreñida.

Sobredimensionar implica:

  • algo de espacio SSD sin usar,
  • una partida de compra ligeramente mayor,
  • y menos reuniones de emergencia.

Elige tu dolor.

Dimensionamiento por carga de trabajo (VMs, archivos, backup, tipo objeto)

Servidor de archivos general (home directories, almacenamiento compartido de ingeniería)

Aquí es donde los vdevs especiales brillan. Los recorridos de directorio y las aperturas de archivo son operaciones intensivas en metadatos.
Para compartidos corporativos “normales” con mezcla de tamaños, los vdevs especiales solo de metadatos suelen ofrecer la mejor ganancia por dólar.

Guía de dimensionamiento:

  • Empieza en 1–2% de la capacidad bruta para solo metadatos.
  • Si esperas millones de archivos pequeños, empuja hacia 2–4%.
  • Mantén special_small_blocks desactivado a menos que puedas justificarlo con patrones de I/O observados.

Almacenamiento para VM (zvols, backing store del hipervisor)

Las cargas de VM son donde la gente se vuelve codiciosa y activa special_small_blocks.
Puede funcionar extremadamente bien porque mucho I/O de VM es pequeño y aleatorio.
También puede devorar tu vdev especial, porque el umbral actúa como una aspiradora: no le importa si el bloque es “importante”, solo si es pequeño.

Guía de dimensionamiento:

  • Sólo metadatos: sigue siendo útil, pero menos dramático.
  • Metadatos + bloques pequeños: dimensiona 8–15% de la capacidad bruta dependiendo de volblocksize y perfil de I/O.
  • Considera pools separados para cargas de VM críticas en latencia en vez de sobrecargar un pool de propósito general.

Targets de backup (escrituras secuenciales grandes, dedup a veces)

Los repositorios de backup tienden a ser cargas de bloques grandes y amigables al streaming.
La aceleración de metadatos ayuda para la gestión de snapshots y operaciones de directorio, pero no siempre es la solución definitiva.

  • Vdev especial solo metadatos: dimensionado modesto (0.5–1.5%) suele ser suficiente.
  • Bloques pequeños: a menudo innecesario; evita a menos que hayas medido un problema real de I/O aleatorio.

Diseños “tipo objeto” (muchos objetos pequeños, mucho listado)

Si estás usando ZFS como un store de objetos con millones de archivos pequeños, los metadatos se vuelven una prioridad.
El vdev especial puede mantener el sistema responsivo durante enumeraciones de directorio y tormentas de stat.

  • Planifica 2–5% solo metadatos, dependiendo de la distribución del tamaño de objetos.
  • Vigila la estrategia de snapshots; stores de objetos más snapshots pueden multiplicar la retención de metadatos.

Decisiones de diseño: mirrors, RAIDZ, ashift, redundancia y por qué debes ser aburrido

Haz mirror, y duerme tranquilo

Un vdev especial no es una “caché”. Trátalo como almacenamiento central del pool.
Usa SSDs en mirror (o triple mirror si tu modelo de riesgo lo exige).
El coste extra de discos es más barato que explicar al CFO por qué “el pool no se importa”.

Elige un ashift sensato

Usa ashift=12 para la mayoría de SSDs y HDDs modernos; se alinea a sectores de 4K.
Equivocarte con ashift puede desperdiciar espacio o golpear el rendimiento.
Generalmente no puedes cambiar ashift después de crear el vdev sin reconstruir.

No mezcles SSDs dudosos con roles críticos

Un SSD de consumo con comportamiento de pérdida de energía cuestionable y endurance mediocre no es automáticamente incorrecto,
pero ponerlo en el vdev especial es donde “probablemente bien” se convierte en “informe de incidente”.
Si debes usar SSDs de consumo, sobreprovisión y mirroriza agresivamente, y monitoriza SMART como si te debieran dinero.

Define expectativas: el vdev especial mejora latencia, no ancho de banda

Tu throughput secuencial puede no cambiar mucho.
Lo que cambia es la experiencia con I/O aleatorio pequeño: obtenciones de metadatos, lecturas de bloques pequeños y la cadena de punteros para encontrar datos.
Es trabajo de latencia, lo que significa que se manifiesta como “todo se siente más rápido”, no como “duplicamos GB/s”.

Entiende qué pasa cuando el vdev especial se llena

Cuando el vdev especial se queda sin espacio, ZFS no puede colocar metadatos allí.
El comportamiento depende de la implementación y flags de features, pero debes asumir:

  • el rendimiento se degrada (los metadatos van a vdevs más lentos o la asignación se vuelve restringida),
  • la asignación se fragmenta y actúa de forma extraña,
  • y estás operando más cerca de un modo de fallo a nivel de pool de lo deseable.

La postura correcta es: no dejes que se acerque a lleno. Expande temprano.

Tareas prácticas con comandos (y cómo decidir)

Estos no son “demos bonitos”. Son los comandos que ejecutas un martes por la tarde cuando intentas prevenir una caída del jueves.
Cada tarea incluye qué buscar y la decisión que tomas basada en ello.

Tarea 1: Identificar si siquiera tienes un vdev especial (y su layout)

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

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            sda                     ONLINE       0     0     0
            sdb                     ONLINE       0     0     0
            sdc                     ONLINE       0     0     0
            sdd                     ONLINE       0     0     0
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0
          special
            mirror-1                ONLINE       0     0     0
              nvme0n1               ONLINE       0     0     0
              nvme1n1               ONLINE       0     0     0

errors: No known data errors

Significado de la salida: Tienes una clase special compuesta por un par NVMe en mirror. Bien.
Si el vdev especial es un disco único, es una decisión de riesgo que debes revisar de inmediato.

Decisión: Si special no está en mirror, programa una remediación (reconstruir en mirrors mediante un pool nuevo o un plan de migración).

Tarea 2: Ver la presión de capacidad del special rápidamente

cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint tank
NAME   USED  AVAIL  REFER  MOUNTPOINT
tank  120T   48T   256K   /tank

Significado de la salida: El espacio del pool no es lo mismo que el espacio del vdev special. Este comando no muestra uso del special directamente.
Te indica si la plenitud general del pool probablemente contribuye a fragmentación y estrés de asignación.

Decisión: Si el pool en sí está por encima de ~80% usado, espera peor comportamiento de asignación en todas partes y trata el dimensionamiento del special como más urgente.

Tarea 3: Mostrar asignación por vdev, incluyendo special

cr0x@server:~$ zpool list -v tank
NAME         SIZE   ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH
tank        200T    152T    48T        -         -    38%    76%  1.00x  ONLINE
  raidz2-0  200T    148T    52T        -         -    39%    74%      -  ONLINE
  special  3.50T   3.10T   410G       -         -    52%    88%      -  ONLINE

Significado de la salida: El vdev special está al 88% de capacidad. Ese es el punto peligroso. La fragmentación también es alta.

Decisión: Planea expandir el vdev special ahora. No esperes al 95%. Tu margen ya se fue.

Tarea 4: Confirmar si los bloques pequeños están siendo dirigidos al special

cr0x@server:~$ zfs get -r special_small_blocks tank
NAME            PROPERTY              VALUE                  SOURCE
tank            special_small_blocks  0                      default
tank/vmstore    special_small_blocks  16K                    local
tank/home       special_small_blocks  0                      inherited from tank

Significado de la salida: Solo tank/vmstore está enviando bloques ≤16K al special. Ese dataset probablemente sea el impulsor del crecimiento.

Decisión: Si el special se está llenando, primero identifica qué datasets tienen special_small_blocks distinto de cero y evalúa si aún lo necesitan.

Tarea 5: Comprobar cuántas snapshots llevas (indicador de presión de metadatos)

cr0x@server:~$ zfs list -t snapshot -o name,used -S used | head
NAME                               USED
tank/vmstore@hourly-2025-12-26     2.3T
tank/vmstore@hourly-2025-12-25     2.1T
tank/home@daily-2025-12-25         320G
tank/vmstore@hourly-2025-12-24     1.9T

Significado de la salida: Muchas snapshots con gran “used” sugiere que la retención mantiene árboles de bloques antiguos vivos.
El trabajo de metadatos y spacemap aumenta con el número de snapshots y el churn.

Decisión: Ajusta la retención de snapshots si no está alineada con los requisitos de recuperación, o planifica más capacidad special para soportar el requisito real.

Tarea 6: Detectar patrones de dataset que crean tormentas de metadatos (muchos archivos diminutos)

cr0x@server:~$ zfs get -r recordsize,compression,atime,xattr tank/home
NAME       PROPERTY     VALUE     SOURCE
tank/home  recordsize   128K      default
tank/home  compression  lz4       local
tank/home  atime        off       local
tank/home  xattr        sa        local

Significado de la salida: Defaults sensatos. xattr=sa puede reducir I/O extra al almacenar xattrs en el dnode (cuando es posible).
Eso puede cambiar patrones de metadatos, a menudo para bien, pero sigue residiendo en “territorio de metadatos”.

Decisión: Mantén estas configuraciones consistentes; evita ajustes aleatorios por dataset a menos que puedas justificarlos.

Tarea 7: Verificar dedup (el dimensionamiento del special cambia drásticamente)

cr0x@server:~$ zpool get dedup tank
NAME  PROPERTY  VALUE  SOURCE
tank  dedup     off    default

Significado de la salida: Dedup está off. Bien; las tablas de dedup pueden ser masivas y cambiar la matemática de tamaño/endurance.

Decisión: Si dedup está activado, revisa el dimensionamiento del special con extrema cautela; puede que necesites mucha más capacidad SSD y RAM.

Tarea 8: Ver si los metadatos están realmente golpeando el special (iostat por vdev)

cr0x@server:~$ zpool iostat -v tank 1 5
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank         152T    48T  1.20K  3.80K   95M  210M
  raidz2-0   148T    52T    200  1.10K   70M  180M
    sda         -      -     30    180   11M   30M
    sdb         -      -     28    175   10M   30M
    sdc         -      -     32    185   12M   32M
    sdd         -      -     33    190   12M   32M
    sde         -      -     35    185   12M   31M
    sdf         -      -     42    185   13M   31M
  special   3.10T   410G  1.00K  2.70K   25M   30M
    mirror-1     -      -  1.00K  2.70K   25M   30M
      nvme0n1    -      -    520  1.40K   12M   15M
      nvme1n1    -      -    480  1.30K   13M   15M

Significado de la salida: El special está realizando la mayoría de operaciones (IOPS), incluso si el ancho de banda es modesto. Eso es típico: los metadatos consumen IOPS, no ancho de banda.

Decisión: Si el special está saturado en IOPS (alta latencia en NVMe, colas), puede que necesites más anchura en la clase special o SSDs más rápidos—no solo más capacidad.

Tarea 9: Revisar soporte TRIM y si está habilitado (afecta longevidad y rendimiento SSD)

cr0x@server:~$ zpool get autotrim tank
NAME  PROPERTY  VALUE     SOURCE
tank  autotrim  on        local

Significado de la salida: Autotrim está habilitado. Esto ayuda a mantener el rendimiento de los SSDs y reduce la amplificación de escritura en muchos casos.

Decisión: Si autotrim está off en special respaldado por SSDs, considera habilitarlo (tras validar la estabilidad de trim en tu plataforma).

Tarea 10: Confirmar que los dispositivos del vdev special están sanos a nivel disco (SMART)

cr0x@server:~$ sudo smartctl -a /dev/nvme0n1 | egrep "Critical Warning|Percentage Used|Media and Data Integrity Errors|Data Units Written"
Critical Warning:                   0x00
Percentage Used:                    18%
Media and Data Integrity Errors:    0
Data Units Written:                 62,114,928

Significado de la salida: Sin advertencias críticas, 18% de endurance consumida, sin errores de media. Bien.

Decisión: Si Percentage Used es alto o aparecen errores de media, planifica el reemplazo proactivo—los vdevs especiales no son donde “esperas a ver”.

Tarea 11: Estimar cuánto espacio está ocupado por datasets con muchos metadatos (indicador aproximado)

cr0x@server:~$ zfs list -o name,used,logicalused,compressratio -S used tank | head
NAME         USED  LOGICALUSED  COMPRESSRATIO
tank/vmstore 78T   110T        1.41x
tank/home    22T   26T         1.18x
tank/backup  18T   19T         1.05x

Significado de la salida: VM store domina y está comprimido, lo que a menudo se correlaciona con bloques en disco más pequeños y más actividad de metadatos.

Decisión: Trata tank/vmstore como el impulsor principal para dimensionamiento y planificación de endurance del vdev special.

Tarea 12: Ver si el special se está usando para datos normales por ajustes de bloques pequeños

cr0x@server:~$ zdb -bbbbb tank/vmstore | head -n 30
Dataset tank/vmstore [ZPL], ID 54, cr_txg 12345, 4.20T, 10.2M objects
  bpobj: 0x0000000000000000
  flags: 
  dnode flags: USED_BYTES USERUSED_ACCOUNTED USEROBJUSED_ACCOUNTED
  features: 
    org.openzfs:spacemap_histogram
    org.openzfs:allocation_classes
...

Significado de la salida: La presencia de org.openzfs:allocation_classes indica que las clases de asignación están en uso.
Esto no cuantifica uso, pero confirma que el pool soporta el conjunto de features.

Decisión: Si no ves features de classes de asignación y pensabas que tenías un special vdev, estás en una stack más antigua o en otra implementación.
Ajusta expectativas y confirma con zpool status.

Tarea 13: Detectar si estás cerca del precipicio “special lleno”

cr0x@server:~$ zpool list -Ho name,cap,frag tank
tank	76%	38%

Significado de la salida: El pool global está al 76% y la fragmentación al 38%. La fragmentación aumenta el trabajo de metadatos y la sobrecarga de asignación.

Decisión: Si la fragmentación sube y el special también está alto, prioriza la expansión; te diriges a un dolor compuesto.

Tarea 14: Añadir un nuevo special mirror (expansión de capacidad de la forma sensata)

cr0x@server:~$ sudo zpool add tank special mirror /dev/nvme2n1 /dev/nvme3n1

Significado de la salida: Esto añade otro vdev special en mirror al pool, aumentando capacidad y IOPS del special.
Los metadatos existentes no se migran automáticamente, pero las nuevas asignaciones pueden usar el espacio añadido según comportamiento y configuración.

Decisión: Si special está por encima de 75–80%, la expansión es un cambio de producción que merece hacerse más pronto que tarde.
Valida modelo/firmware de los dispositivos y las implicaciones de ashift antes de comprometerte.

Tarea 15: Confirmar que el pool muestra ahora el vdev special adicional

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

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            sda                     ONLINE       0     0     0
            sdb                     ONLINE       0     0     0
            sdc                     ONLINE       0     0     0
            sdd                     ONLINE       0     0     0
            sde                     ONLINE       0     0     0
            sdf                     ONLINE       0     0     0
          special
            mirror-1                ONLINE       0     0     0
              nvme0n1               ONLINE       0     0     0
              nvme1n1               ONLINE       0     0     0
            mirror-2                ONLINE       0     0     0
              nvme2n1               ONLINE       0     0     0
              nvme3n1               ONLINE       0     0     0

errors: No known data errors

Significado de la salida: Existen dos mirrors special. Tu clase special ahora es más ancha y más grande.

Decisión: Actualiza el monitoreo para rastrear uso de la clase special y la salud de dispositivos en ambos mirrors.

Tarea 16: Verificar qué datasets son candidatos para desactivar la colocación de bloques pequeños (control de riesgo)

cr0x@server:~$ zfs get -r -s local special_small_blocks tank | grep -v "VALUE *0"
tank/vmstore  special_small_blocks  16K  local

Significado de la salida: Solo un dataset lo tiene establecido localmente.

Decisión: Si la capacidad special es la limitación, considera bajar el umbral (por ejemplo, 16K → 8K) o desactivarlo en datasets menos críticos.
No lo cambies a ciegas; prueba el impacto en latencia primero.

Guion de diagnóstico rápido

Te despiertan: “El pool ZFS está lento.” Sospechas del vdev special porque antes todo iba bien y ahora los listados de directorio se arrastran.
Aquí está la ruta más rápida hacia una hipótesis de causa raíz sin convertirlo en un proyecto arqueológico de una semana.

Primero: ¿el vdev special está cerca de lleno?

cr0x@server:~$ zpool list -v tank
NAME         SIZE   ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH
tank        200T    152T    48T        -         -    38%    76%  1.00x  ONLINE
  raidz2-0  200T    148T    52T        -         -    39%    74%      -  ONLINE
  special  3.50T   3.10T   410G       -         -    52%    88%      -  ONLINE

Si el special está por encima de ~80%, trátalo como sospechoso principal. La plenitud se correlaciona con restricciones de asignación y picos de latencia.
Decisión: expande la clase special o reduce el uso de special_small_blocks antes de perseguir otros ajustes.

Segundo: ¿está saturado el special en IOPS o latencia?

cr0x@server:~$ zpool iostat -v tank 1 10
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank         152T    48T  1.60K  5.10K  120M  260M
  raidz2-0   148T    52T    220  1.30K   80M  190M
  special   3.10T   410G  1.38K  3.80K   40M   70M

Si special domina las operaciones y el sistema está lento, eso es consistente con presión de metadatos.
Decisión: si NVMe está al 100%, considera ampliar la clase special (otro mirror) o usar dispositivos más rápidos.

Tercero: ¿alguien redirigió bloques pequeños al special y lo olvidó?

cr0x@server:~$ zfs get -r special_small_blocks tank
NAME            PROPERTY              VALUE                  SOURCE
tank            special_small_blocks  0                      default
tank/vmstore    special_small_blocks  16K                    local
tank/home       special_small_blocks  0                      inherited from tank

Si esto está activado en un dataset muy activo, probablemente sea la razón por la que el special creció más rápido de lo esperado.
Decisión: mantenerlo, reducirlo o limitarlo solo a los datasets que realmente se benefician.

Cuarto: ¿el problema es realmente fragmentación a nivel de pool o presión de capacidad general?

cr0x@server:~$ zpool list -Ho cap,frag tank
76%	38%

Si la capacidad del pool es alta y la fragmentación aumenta, el rendimiento puede degradarse incluso con un special sano.
Decisión: libera espacio, añade capacidad y ajusta retención/churn.

Quinto: ¿está enfermo el dispositivo special (SMART, errores, resets)?

cr0x@server:~$ dmesg | egrep -i "nvme|I/O error|reset|timeout" | tail -n 10
[123456.789] nvme nvme0: I/O 987 QID 6 timeout, aborting
[123456.790] nvme nvme0: Abort status: 0x371
[123456.800] nvme nvme0: reset controller

Si ves resets/timeouts, no “tunes ZFS”. Arregla el hardware/firmware.
Decisión: reemplaza el dispositivo, actualiza firmware, revisa la topología PCIe, gestión de energía y cableado (si es U.2/U.3).

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

1) Síntoma: listados de directorio y find de repente lentos

Causa raíz: El vdev special está cerca de lleno o saturado con IOPS de metadatos; los metadatos se derraman a los HDDs o las asignaciones se ven constreñidas.

Solución: Revisa zpool list -v. Si la CAP del special > 80%, expande la clase special (añade otro par mirror). Si está saturado, amplíalo o usa SSDs más rápidos.

2) Síntoma: El pool “parece sano” pero la latencia de la aplicación se dispara durante ventanas de snapshot

Causa raíz: La creación/eliminación de snapshots aumenta las operaciones de metadatos; el vdev special se convierte en cuello de botella.

Solución: Reduce frecuencia/retención de snapshots para datasets con alto churn; programa pruning de snapshots fuera de pico; expande capacidad e IOPS del special si las snapshots son innegociables.

3) Síntoma: El vdev special se llena inesperadamente rápido tras activar special_small_blocks

Causa raíz: Umbral demasiado alto (p. ej., 32K) en una carga con muchas escrituras pequeñas (VMs, bases de datos), tierizando efectivamente una gran fracción de datos en SSD.

Solución: Baja el umbral (p. ej., 16K → 8K), aplícalo solo a los datasets que lo necesiten y expande capacidad special antes de hacer cambios en producción.

4) Síntoma: Tras añadir un vdev special, el rendimiento no mejoró mucho

Causa raíz: La carga es mayormente I/O secuencial grande; los metadatos no eran el cuello de botella. O los misses de ARC están dominados por datos, no metadatos.

Solución: Valida con zpool iostat -v y métricas de la aplicación. No sigas tocando botones; los vdevs especiales no son un acelerador universal.

5) Síntoma: El import del pool falla o se cuelga tras perder un NVMe

Causa raíz: El vdev special no era redundante o la redundancia no fue suficiente ante la falla del dispositivo; la pérdida de metadatos impide ensamblar el pool.

Solución: En producción usa vdevs special en mirror. Si ya lo construiste mal, la solución correcta es migrar a un pool bien diseñado.

6) Síntoma: El desgaste de NVMe se dispara

Causa raíz: El vdev special recibe escrituras de bloques pequeños más churn de metadatos; autotrim está off; la clase de endurance del SSD es insuficiente.

Solución: Habilita autotrim si es estable, elige SSDs de mayor endurance, reduce el alcance de offload de bloques pequeños y monitoriza Percentage Used de SMART.

7) Síntoma: Regresiones “aleatorias” de rendimiento tras upgrades o cambios de propiedades

Causa raíz: Cambiaron propiedades de datasets (recordsize/volblocksize/special_small_blocks), desplazando patrones de asignación y moviendo I/O caliente al special inesperadamente.

Solución: Audita cambios de propiedades con zfs get -r (valores locales). Trata special_small_blocks como un cambio controlado con plan de rollback.

Tres micro-historias corporativas (anonimizadas, dolorosamente plausibles)

Incidente causado por una suposición errónea: “Los metadatos son pequeños”

Una empresa mediana tenía un gran pool HDD que respaldaba un share monolítico y un repositorio de artefactos de build.
Añadieron un vdev special en mirror formado por dos NVMes pequeños pero rápidos. El ticket de cambio decía “los metadatos son pequeños; 400 GB usable son suficientes.”
Todos asintieron porque a todo el mundo le gusta una ganancia barata.

Durante seis meses se vio genial. Los builds se aceleraron. Los home directories de desarrolladores se sintieron ágiles. Alguien incluso escribió “ZFS special vdev = rendimiento gratis”
en un chat, lo cual debería haber sido tratado como un indicador pre-incidente.

Entonces llegó un requerimiento de compliance: mayor frecuencia de snapshots y retención más larga “por si acaso”.
Las snapshots se acumularon. Los builds siguieron churnando. Se crearon y eliminaron muchos archivos pequeños. La capacidad special subió, pero nadie vigilaba la clase special por separado.
Miraban la capacidad del pool, veían espacio HDD libre y asumían que todo iba bien.

El primer síntoma no fue una alerta. Fueron personas quejándose: “ls está lento”, “git status se cuelga”, “los jobs de CI timeoutean durante la limpieza”.
Cuando SRE revisó, el special ya estaba en los 90s y el sistema pasaba su tiempo en costosas operaciones de asignación.
La solución fue sencilla pero desagradable: añadir de emergencia otro par mirror special y triage de políticas de snapshot.

La causa real no fue “ZFS es raro”. Fue creer que los metadatos son una nota al pie de tamaño constante. No lo son.
Los metadatos crecen con el churn y la historia. Y la historia de snapshots es literalmente historia almacenada.

Optimización que salió mal: Activar small blocks en todas partes

Otra organización corría virtualización sobre ZFS con un pool híbrido: HDDs para capacidad y un vdev special para metadatos.
Hubo un sprint de tuning porque algunas VMs sensibles a latencia sufrían en horas pico.
Alguien leyó sobre special_small_blocks y decidió “hacer el pool más rápido” configurándolo en el dataset padre para que heredara en todas partes.

El benchmark inmediato se vio bien. Las VMs problemáticas mejoraron. El sprint terminó con una diapositiva pulcra: “Usamos SSDs para I/O pequeño.”
Nadie preguntó qué fracción de las escrituras totales estaban bajo el umbral, o si el special tenía el presupuesto de endurance para servir como tier parcial.

Dos trimestres después, el special estaba muy utilizado y el desgaste de NVMe era alarmante.
Peor aún: la clase special se convirtió en un cuello de botella único para escrituras aleatorias en toda la base de virtualización.
El pool no era “más rápido”. Era “rápido hasta que dejó de serlo”, que es el peor tipo de rápido.

Revirtieron la configuración en la mayoría de datasets y la mantuvieron solo para un subconjunto pequeño de VMs que realmente la necesitaban.
También expandieron la clase special y estandarizaron SSDs de mayor endurance.
La lección quedó: special_small_blocks no es un almuerzo gratis; es una decisión de diseño que convierte dispositivos de metadatos en un tier.

Práctica aburrida pero correcta que salvó el día: alertas en CAP y desgaste del special

Un equipo de servicios financieros trató los vdevs special como infraestructura de primera clase desde el día uno.
Usaron NVMes empresariales en mirror, habilitaron autotrim y—aquí la parte verdaderamente emocionante—crearon alertas específicamente para la capacidad de la clase special,
no solo la capacidad general del pool.

También controlaron indicadores de desgaste de NVMe y establecieron una política de reemplazo antes de que los dispositivos se pusieran picantes.
Cuando la CAP del special alcanzó su umbral de advertencia, se disparó un flujo de cambio normal, no una sala de guerra.
El equipo tenía un playbook: verificar qué datasets usaban colocación de bloques pequeños, revisar el crecimiento de snapshots y proyectar capacidad.

Un año, un servicio interno nuevo empezó a generar millones de archivos diminutos en un dataset compartido.
Las alertas sonaron temprano. El equipo de almacenamiento se reunió con el equipo del servicio, cambió el layout y amplió el special antes de que fuera un incidente visible para usuarios.
Nadie fuera de infraestructura lo notó, que es el mayor elogio en operaciones.

La práctica no fue ingeniosa. Fue atenta: monitoreo separado para el special, umbrales conservadores y revisiones rutinarias de capacidad.
Ser aburrido es una característica.

Listas de verificación / plan paso a paso

Paso a paso: dimensionar un nuevo vdev special

  1. Clasifica la carga de trabajo: aceleración solo de metadatos vs metadatos + bloques pequeños.
    Si no puedes responder, detente y mide primero los patrones de I/O.
  2. Elige una ratio inicial:

    • Solo metadatos: 1–2% del pool bruto (2–4% si muchos archivos pequeños/snapshots).
    • Metadatos + bloques pequeños: 5–15% del pool bruto (más alto si VMs y umbral pequeño).
  3. Añade buffer: dimensiona para que la operación normal se mantenga por debajo del 70% de uso de la clase special.
  4. Elige redundancia: vdevs special en mirror. Sin excepciones en producción a menos que disfrutes apostar con los datos de otros.
  5. Elige la clase de SSD: prefiere PLP (protección ante pérdida de energía) y endurance adecuada, especialmente si se enrutan bloques pequeños.
  6. Configura monitoreo: rastrea CAP special, frag special, errores/resets NVMe, desgaste SMART y cambios en zpool status.
  7. Despliegue con cuidado: si habilitas colocación de bloques pequeños, hazlo por dataset y valida antes de ampliar.

Paso a paso: cuando el special ya es demasiado pequeño

  1. Confirma la CAP del special con zpool list -v.
  2. Identifica datasets que impulsan el crecimiento vía zfs get -r special_small_blocks y conteos de snapshots.
  3. Expande la clase special añadiendo otro par mirror special.
  4. Reduce presión futura: baja el umbral special_small_blocks o límitealo a datasets críticos.
  5. Ajusta retención: políticas de snapshot alineadas a RPO/RTO reales, no a la ansiedad.
  6. Revisa desgaste: asegura que el presupuesto de endurance del SSD aún aguante.

Checklist operacional: semanal (sí, semanal)

  • Revisa zpool status por errores de dispositivo.
  • Revisa zpool list -v y alerta si CAP del special > 75%.
  • Revisa desgaste SMART en dispositivos special.
  • Audita datasets con special_small_blocks habilitado.
  • Revisa conteos de snapshots y prunea responsablemente.

Preguntas frecuentes

1) ¿Puedo tratar el vdev special como una caché?

No. L2ARC es caché. SLOG es dispositivo de registro. Los vdevs special pueden contener metadatos críticos del pool. Perderlos puede significar perder el pool.
Diseñalo como almacenamiento primario.

2) ¿Cómo sé si debo habilitar special_small_blocks?

Habilítalo solo si tienes un problema medido de I/O aleatorio en vdevs HDD y cuentas con el presupuesto de capacidad/endurance en SSD.
Los stores de VM son candidatos comunes; los compartidos de archivos generales normalmente funcionan bien con solo metadatos en special.

3) ¿Qué valor debería usar para special_small_blocks?

Valores conservadores: 8K o 16K para datasets dirigidos. Umbrales más altos capturan más I/O pero consumen capacidad special más rápido.
Empieza pequeño, mide y luego amplia si es necesario.

4) ¿Qué pasa cuando el vdev special se llena?

Mejor caso: el rendimiento se degrada mientras las asignaciones se vuelven menos óptimas y la colocación de metadatos empeora.
Peor caso: inestabilidad o fallos relacionados con asignaciones. Trata “special cercano a lleno” como un asunto urgente de capacidad.

5) ¿Puedo quitar un vdev special después?

Planifica como si la respuesta fuera “no”. En muchas implementaciones productivas, eliminar vdevs special no está soportado o no es práctico.
Asume que es una puerta de no retorno y dimensiona en consecuencia.

6) ¿Deben los vdevs special ser NVMe, SATA SSD u otra cosa?

NVMe es ideal para IOPS y latencia de metadatos. Un SSD SATA aún puede ayudar mucho frente a HDDs.
Cuanto más centrada en metadatos esté tu carga, más importa la baja latencia de NVMe.

7) ¿Añadir más mirrors special mejora el rendimiento?

A menudo, sí. Más mirrors aumentan la capacidad de IOPS y reducen el encolamiento. También aumentan la capacidad.
Pero no arreglará un pool fundamentalmente sobrecargado o datasets con churn patológico.

8) ¿Es seguro usar RAIDZ para vdevs special?

Los mirrors son la recomendación por defecto por una razón: comportamiento de rebuild predecible y dominios de fallo más simples.
Si consideras RAIDZ special, deberías poder explicar tiempo de rebuild, tolerancia a fallos e impacto operativo en detalle.

9) ¿Cómo se relaciona el dimensionamiento del special con ARC/RAM?

ARC ayuda a cachear metadatos y datos en RAM. Un vdev special reduce la penalidad cuando los metadatos no están en ARC.
Si ARC está subdimensionado, el special aún ayuda, pero podrías estar enmascarando un problema de memoria.

10) Si añado vdevs special, ¿los metadatos existentes se moverán a ellos?

No asumas que “se reequilibrará mágicamente” de forma que arregle tu pasado. Algunas nuevas asignaciones usarán la nueva capacidad special,
pero el comportamiento de migración depende de detalles de implementación y del churn de la carga. Planea expansiones antes de estar en llamas.

Próximos pasos que puedes hacer esta semana

Si ya usas vdevs special: comprueba su capacidad y salud hoy. La plenitud del special es uno de esos problemas que se mantiene silencioso hasta que grita.

  1. Ejecuta zpool list -v y registra la CAP del special. Si está por encima de 75%, abre un ticket de cambio de capacidad.
  2. Ejecuta zfs get -r special_small_blocks y haz una lista de datasets que lo usan. Valida que cada uno sea intencional.
  3. Revisa conteos de snapshots y retención. Si guardas historia “por si acaso”, la estás pagando en metadatos.
  4. Añade monitoreo para utilización de la clase special y desgaste NVMe. Si solo monitorizas la capacidad global del pool, estás mirando el dashboard equivocado.
  5. Si diseñas un pool nuevo, dimensiona el special para que en estado estable esté por debajo del 70%, mirrorízalo y compra SSDs con endurance acorde a la carga.

El mejor dimensionamiento de vdev special es el que nunca tienes que explicar durante un incidente.
Ve por lo aburrido, redundante y un poco más grande de lo que tu ego dice que necesitas.

← Anterior
Supervisión SMART de ZFS: correlacionando advertencias de disco con errores ZFS
Siguiente →
DNS: Movimientos poderosos con dig/drill — comandos que responden al 90% de los misterios DNS

Deja un comentario