ARC de ZFS por TB: Dimensionamiento de RAM sin mitos ni dogmas de foros

¿Te fue útil?

La conversación siempre empieza igual: “Añadimos discos, el almacenamiento es enorme ahora y el rendimiento empeoró. ¿Necesitamos 1 GB de RAM por TB?”
Luego alguien reenvía una captura de un foro como si fuera un plan de capacidad certificado.

El dimensionamiento del ARC no es astrología. Es economía de caché, física de cargas de trabajo y un poco de humildad sobre lo que ZFS realmente está haciendo. Si dimensiona la RAM
por terabytes brutos, gastará de más en algunos entornos y seguirá teniendo lentitud en otros. Reemplacemos el folclore por decisiones que pueda defender en una revisión de cambios.

Deje de usar “RAM por TB” como regla de dimensionamiento

“1 GB de RAM por TB de almacenamiento” es el equivalente para almacenamiento de “reinícialo y a ver si ayuda”. A veces funciona por accidente, y por eso perdura.
Pero no es un método de dimensionamiento. Es una superstición con una unidad adjunta.

El ARC de ZFS es una caché. Las cachés no se dimensionan por capacidad; se dimensionan por el conjunto de trabajo y por los objetivos de latencia.
Su pool podría ser 20 TB de archivos fríos que se escriben una vez y nunca se leen. O podría ser 20 TB de VMs haciendo lecturas aleatorias de 4K con un pequeño conjunto caliente que cabe en memoria.
Esos dos mundos tienen los mismos “TB” y RAM que importa radicalmente distinta.

Esto es lo que la regla por terabyte no contempla:

  • El patrón de acceso vence a la capacidad. Los escaneos secuenciales pueden atravesar cualquier tamaño de ARC; las lecturas aleatorias pueden transformarse con ARC.
  • La metadata tiene un valor distinto a los datos. Cachear metadata puede hacer que un “disco lento” se sienta rápido sin cachear mucho dato de usuario.
  • ZFS tiene controles que cambian el comportamiento de memoria. recordsize, compression, special vdevs, dnodesize y primarycache importan.
  • El ARC compite con sus aplicaciones. El mejor tamaño de ARC es el que no deja a la carga útil sin recursos.

Lo que debe hacer en su lugar es aburrido: elija un objetivo de rendimiento, observe el comportamiento de los aciertos de caché, valide su conjunto de trabajo y dimensione la RAM para alcanzar el objetivo.
Si va a comprar hardware, hágalo con plan y con reversión.

Broma #1: Si dimensiona el ARC por terabytes, acabará comprando un servidor que es básicamente un radiador con puertos SATA.

ARC: qué es y qué no es

ARC es una caché residente en memoria con conciencia de presión de memoria

ARC (Adaptive Replacement Cache) vive en RAM. Cachea tanto datos como metadata, y está diseñado para adaptarse entre
patrones de “uso reciente” y “uso frecuente”. Esa parte “adaptativa” es real: ARC rastrea múltiples listas y usa entradas fantasma
para aprender qué desearía haber cacheado.

ARC también está diseñado para convivir razonablemente con el SO cuando aumenta la presión de memoria. En Linux, el ARC se reduce según zfs_arc_max
y las señales de presión; en FreeBSD está integrado de forma diferente pero sigue la misma intención de evitar la inanición total. “Diseñado para” tiene su importancia:
todavía debe verificar que su SO y la versión de ZFS se comporten correctamente en su entorno.

ARC no es “cómo ZFS mantiene consistente su pool”

La consistencia de ZFS proviene de copy-on-write, grupos de transacciones y registro de intenciones (ZIL/SLOG para comportamiento sync). Nada de eso requiere un ARC enorme.
Sí, ZFS usa memoria para metadata y gestión, pero el mítico “ZFS necesita montones de RAM para no corromper datos” es una tontería en versiones modernas.
Puede ejecutar ZFS con RAM modesta y seguirá siendo correcto. Simplemente puede ser más lento.

ARC no es sustituto de un mal diseño de E/S

Si su carga es 90% escrituras síncronas a un pool de discos lentos y no tiene un SLOG apropiado, duplicar ARC no lo salvará.
Si el cuello de botella es CPU (compresión, checksums, cifrado) o una aplicación mono-hilo, ARC no ayudará.
Si su pool está 90% lleno y fragmentado, ARC no lo salvará. ARC es una caché, no un terapeuta.

El contenido del ARC lo modelan las propiedades de los datasets

El caché de ZFS no es monolítico. Las propiedades del dataset influyen en qué se cachea y cuán dolorosos son los misses:

  • recordsize cambia la amplificación de I/O y la granularidad de los bloques cacheados.
  • primarycache puede ser all, metadata o none.
  • compression modifica cuánto “dato lógico” cabe por byte de ARC y afecta a la CPU.
  • atime y la rotación de metadata pueden convertir lecturas en presión de escritura.

Una cita, porque sigue siendo el encuadre más claro:
La esperanza no es una estrategia. — James Cameron

Dimensionamiento centrado en la carga: el único modelo que sobrevive en producción

Paso 1: clasifique la carga que realmente ejecuta

“Servidor de archivos” no describe una carga. Necesita al menos este nivel de detalle:

  • Tipo de I/O: principalmente lecturas, principalmente escrituras, mixto.
  • Semántica de escritura: intensivo en sync (bases de datos, NFS con sync), mayormente async (ingest masivo).
  • Patrón de acceso: aleatorio 4K/8K, secuencial, muchos archivos pequeños, archivos grandes de streaming.
  • Conjunto caliente: aproximadamente cuánto dato se toca repetidamente por hora/día.
  • Objetivo de latencia: “las VMs se sienten ágiles” no es un objetivo; “p95 de lectura por debajo de 5 ms” sí lo es.

Paso 2: decida qué quiere que haga el ARC

ARC puede aportar valor de tres maneras comunes:

  1. Acelerar lecturas aleatorias sirviendo bloques calientes desde RAM.
  2. Acelerar metadata (recorridos de directorios, apertura de archivos, cargas de archivos pequeños, exploración de snapshots).
  3. Reducir búsquedas en disco convirtiendo lecturas repetidas en aciertos de memoria y liberando discos para escrituras.

El tercero está subestimado: a veces escribe lento porque los discos están ocupados haciendo lecturas evitables.
ARC puede acelerar indirectamente las escrituras al eliminar la presión de lectura.

Paso 3: elija un punto de partida intencionalmente conservador

Línea base práctica (no por TB ni ley):

  • Host de VMs pequeño / NAS pequeño: 16–32 GB RAM, y luego validar.
  • Nodo de virtualización general con pool SSD: 64–128 GB RAM si espera localidad de lectura.
  • Pools grandes en HDD que sirven cargas activas: priorice cache de metadata y considere special vdevs; solo RAM puede no escalar.
  • Bases de datos con escrituras sync: ARC ayuda lecturas; para escrituras enfoque en SLOG y topología del pool primero.

Si no puede explicar qué cacheará ARC y por qué importa, no compre RAM todavía. Mida primero.

Paso 4: entienda por qué “más ARC” puede empeorar

Un ARC mayor no es gratis:

  • Presión de memoria puede empujar al SO a hacer swapping o tormentas de reclaim. Si su hipervisor hace swap, su “caché” se convierte en una interrupción a cámara lenta.
  • Tiempo de calentamiento aumenta tras reinicios o failovers. Un ARC enorme implica más tiempo para alcanzar el estado estable.
  • Contaminación de caché por escaneos/backups puede expulsar lo que realmente importa, especialmente si permite cacheo de datos en todas partes.
  • Restricciones de memoria del kernel y fragmentación pueden volverse su nuevo problema raro.

Un modelo mental útil: “conjunto caliente + metadata + margen de seguridad”

El dimensionamiento de ARC que no lo avergüence en un postmortem tiende a seguir esta lógica:

  • Estime el conjunto de datos calientes: la porción de datos leída repetidamente dentro de su ventana de latencia.
  • Agregue espacio para metadata: entradas de directorio, bloques indirectos, dnodes, objetos ZAP. Esto depende mucho de la carga.
  • Deje memoria para el SO y las apps: page cache (si aplica), sobrecarga del hipervisor, contenedores, bases de datos, agentes de monitorización y las “cosas que olvidó”.
  • Limite el ARC: no permita que “gane” siempre. Su aplicación paga la cuenta.

Datos e historia interesantes (porque los mitos tienen historias de origen)

  • ARC existía antes de la adopción amplia de ZFS en Linux. El algoritmo ARC se describió en la academia (IBM) antes de que ZFS lo hiciera famoso en círculos de almacenamiento.
  • La regla “1 GB por TB” probablemente empezó como una advertencia aproximada para pools con mucha metadata. Despliegues tempranos con grandes directorios en discos lentos eran terribles sin suficiente RAM.
  • Las versiones iniciales de ZFS consumían más memoria y eran menos configurables. OpenZFS moderno mejoró la contabilidad de memoria y añadió controles como L2ARC persistente y special vdevs.
  • L2ARC originalmente no era persistente tras reboot. Eso lo hacía menos valioso en sistemas que se reiniciaban a menudo; L2ARC persistente cambió la economía para algunos equipos.
  • ZIL y SLOG suelen confundirse como “caché de escritura”. Se refieren a semántica de sync, no a acelerar todas las escrituras. Esta confusión alimenta decisiones de RAM equivocadas.
  • Los valores por defecto de recordsize se eligieron para archivos generales, no para VMs. Un recordsize por defecto como 128K tenía sentido históricamente, pero cargas aleatorias suelen necesitar un ajuste distinto.
  • Los special vdevs se introdujeron para resolver un dolor específico. Poner metadata (y opcionalmente bloques pequeños) en SSD puede superar “solo añadir RAM” en pools HDD.
  • La compresión se recomendó por defecto porque la CPU se abarató. Con CPUs modernas, la compresión puede aumentar la efectividad del ARC y reducir I/O—hasta que la CPU se convierta en cuello de botella.

Guion de diagnóstico rápido

Cuando alguien dice “ZFS está lento”, tiene unos cinco minutos para evitar una hora de especulación. Aquí el orden que suele dar resultado.

Primero: decida si el cuello de botella son lecturas, escrituras o latencia por sync

  • Compruebe I/O del pool y latencia (¿están saturados los discos, las ops esperan?).
  • Verifique si las escrituras sync dominan (NFS sync, fsync de bases de datos).
  • Compruebe si hay misses de caché o thrash en la caché.

Segundo: verifique la presión de memoria y el comportamiento del ARC

  • ¿Está el SO haciendo swap o reclamando agresivamente?
  • ¿Está ARC cerca de su límite y aun así fallando mucho?
  • ¿Se reduce ARC por presión?

Tercero: busque las trampas clásicas de configuración

  • Pool demasiado lleno, fragmentación y topología de vdevs HDD lenta.
  • recordsize inadecuado para la carga.
  • Backups/scrubs/resilver coincidiendo con la carga pico.
  • Abuso de L2ARC (SSD de caché enorme con muy poca RAM).

Cuarto: solo entonces hable de comprar RAM

Si el pool está limitado por IOPS y tiene un conjunto caliente estable, ARC ayuda. Si el pool está limitado por escrituras sync, arregle SLOG/topología.
Si el pool está limitado por CPU, arregle la CPU. Si “lo llenamos al 92%”, arregle la capacidad.

Tareas prácticas: comandos, salidas y la decisión que toma

Estas son tareas de campo. No son teóricas. Ejecútelas, lea las salidas y tome una decisión.
Los comandos asumen OpenZFS en Linux con herramientas típicas; ajuste para su distro.

Tarea 1: Compruebe la presión básica de memoria (el swapping mata más rendimiento ZFS que cualquier ajuste de ARC)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           125Gi        79Gi       3.2Gi       1.1Gi        42Gi        44Gi
Swap:          8.0Gi       2.6Gi       5.4Gi

Qué significa: Hay uso de swap. Eso no prueba un incidente, pero es un olor.
Decisión: Si el swap crece durante cargas o picos de latencia, limite ARC y/o añada RAM solo después de confirmar que la carga necesita cacheo.

Tarea 2: Identifique si el kernel está thrasheando por reclaim

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 3  0 270336 3421120  91264 41277440   0   0   120   250 5400 7200 12  6 78  4  0
 5  1 270336 2897408  91264 41300224   0  64    90  1800 6100 9100 18 10 55 17  0
 6  2 271360 2019328  91264 41311232   0 512    60  4200 6900 9800 15 11 42 32  0

Qué significa: so (swap out) está subiendo y wa (I/O wait) es alto. Está pagando la presión de memoria con latencia en disco.
Decisión: Reduzca el máximo de ARC (o arregle el verdadero consumidor de memoria) antes de hacer cualquier otra cosa. ZFS no puede cachear eficazmente cuando el SO lo está expulsando.

Tarea 3: Confirme el tamaño del ARC y si está cerca del máximo

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:01:10   820    96     11    12    1    84   10     0    0   88.2G  92.0G
12:01:11   901   210     23    18    2   192   21     0    0   88.3G  92.0G
12:01:12   870   245     28    20    2   225   26     0    0   88.3G  92.0G

Qué significa: El tamaño de ARC (arcsz) está cerca del objetivo (c) y el miss% está subiendo.
Decisión: Si esto es estado estable y la carga es muy lectora, añadir RAM puede ayudar. Si miss% sube durante backups/scans, arregle la contaminación de caché primero.

Tarea 4: Vea el desglose detallado del ARC (metadata vs datos, y si lo está pagando)

cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep '^(size|c_max|c_min|hits|misses|mfu_hits|mru_hits|metadata_size|data_size) '
size                            94701989888
c_min                           4294967296
c_max                           103079215104
hits                            182993948
misses                          23120291
mfu_hits                        119002331
mru_hits                        56211617
metadata_size                   22811942912
data_size                       70100215808

Qué significa: Está cacheando mucha metadata (~22 GB) y muchos datos (~70 GB). Los hits superan ampliamente a los misses en general.
Decisión: Si la latencia sigue mala, su problema puede no ser la caché de lectura. Pase a ver la latencia del pool y las escrituras sync.

Tarea 5: Compruebe la salud del pool y restricciones obvias de layout de vdev

cr0x@server:~$ zpool status -v
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 04:12:33 with 0 errors on Sun Dec 22 03:10:19 2025
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

errors: No known data errors

Qué significa: Un único vdev RAIDZ2 se comporta como un solo vdev para IOPS. Excelente para capacidad y throughput secuencial, no para IOPS aleatorios.
Decisión: Si la carga es I/O aleatorio (VMs), no intente “salvarlo con ARC” por topología. Añada vdevs, use mirrors o mueva cargas calientes a SSD.

Tarea 6: Compruebe el llenado del pool (el acantilado de rendimiento es real)

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

Qué significa: El pool está efectivamente ~95% usado. La asignación se vuelve costosa; la fragmentación y el comportamiento de metaslab empeoran.
Decisión: Deje de debatir ARC. Añada capacidad o elimine/migre datos. Luego reevalúe el rendimiento.

Tarea 7: Detecte presión de escrituras sync (la trampa “¿por qué mis escrituras son lentas?”)

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

Qué significa: El comportamiento sync es el predeterminado. Aplicaciones que llaman a fsync o clientes que exigen sync forzarán el comportamiento ZIL.
Decisión: Si ejecuta una base de datos o NFS con carga intensiva en sync, investigue SLOG y latencia, no el tamaño de ARC.

Tarea 8: Compruebe si tiene un dispositivo SLOG y cuál es

cr0x@server:~$ zpool list -v tank
NAME         SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank        83.6T  78.3T  5.3T        -         -    41%    93%  1.00x  ONLINE  -
  raidz2-0  83.6T  78.3T  5.3T        -         -    41%  93.6%      -      -  -

Qué significa: No se lista un log vdev. Las escrituras sync van al pool principal.
Decisión: Si la latencia de escrituras sync es el dolor, un SLOG de baja latencia y protección ante pérdida de energía puede ayudar más que cualquier actualización de RAM.

Tarea 9: Mida I/O del pool y latencia en tiempo real

cr0x@server:~$ zpool iostat -v tank 1 3
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        78.3T  5.3T   1200    980   210M  145M
  raidz2-0  78.3T  5.3T   1200    980   210M  145M
    sda         -      -    210    160  35.0M  23.5M
    sdb         -      -    195    165  33.1M  24.0M
    sdc         -      -    205    155  34.2M  22.8M
    sdd         -      -    180    170  30.8M  25.1M
    sde         -      -    195    165  33.0M  24.0M
    sdf         -      -    215    165  34.9M  23.9M
----------  -----  -----  -----  -----  -----  -----

Qué significa: El pool está realizando muchas operaciones. Si son I/O pequeños y aleatorios en HDDs, la latencia probablemente sea alta aunque el ancho de banda parezca correcto.
Decisión: Si las ops son altas y la carga es sensible a latencia, considere mirrors/más vdevs/tiering SSD antes de comprar RAM.

Tarea 10: Compruebe propiedades de datasets que afectan la eficiencia del ARC

cr0x@server:~$ zfs get -o name,property,value recordsize,compression,atime,primarycache tank/vmstore
NAME         PROPERTY      VALUE
tank/vmstore recordsize    128K
tank/vmstore compression   lz4
tank/vmstore atime         on
tank/vmstore primarycache  all

Qué significa: recordsize de 128K y atime=on para un almacén de VMs es un error común autoinfligido. atime añade carga de escritura; registros grandes inflan I/O aleatorio.
Decisión: Considere atime=off y un recordsize apropiado para VMs (a menudo 16K) tras pruebas. Si el conjunto caliente es pequeño, ARC también se comportará mejor.

Tarea 11: Compruebe si la compresión ayuda o perjudica (y si la CPU es el verdadero cuello de botella)

cr0x@server:~$ zfs get -o name,property,value compressratio tank/vmstore
NAME         PROPERTY       VALUE
tank/vmstore compressratio  1.62x

Qué significa: La compresión es efectiva: 1.62x significa que está ahorrando I/O y encajando más dato lógico en el ARC.
Decisión: Manténgala a menos que la CPU esté al máximo. Si la CPU está saturada, la compresión puede ser el cuello de botella y más RAM no lo solucionará.

Tarea 12: Verifique saturación de CPU durante quejas de “almacenamiento lento”

cr0x@server:~$ mpstat -P ALL 1 2
Linux 6.8.0 (server)  12/26/2025  _x86_64_  (32 CPU)

12:05:01 PM  CPU   %usr  %nice   %sys %iowait  %irq  %soft  %steal  %guest  %gnice  %idle
12:05:02 PM  all   58.2    0.0   18.9     1.1   0.0    0.8     0.0     0.0     0.0   21.0
12:05:02 PM   7    96.0    0.0    3.8     0.0   0.0    0.0     0.0     0.0     0.0    0.2

Qué significa: Un CPU está casi saturado. Puede ser un hilo muy ocupado (checksums, compresión, una VM, una ruta de interrupción).
Decisión: Si la latencia de almacenamiento se correlaciona con saturación de CPU, añadir ARC no ayudará. Investigue hotspots de CPU y distribución de carga.

Tarea 13: Compruebe presencia de L2ARC y si es razonable para su RAM

cr0x@server:~$ zpool status tank | egrep -A3 'cache|special|logs'
        cache
          nvme1n1p1               ONLINE       0     0     0

Qué significa: Tiene un dispositivo L2ARC. L2ARC no es mágico; consume recursos del ARC para cabeceras y metadata y puede aumentar la amplificación de lectura.
Decisión: Si la RAM es pequeña y L2ARC grande, puede acabar más lento. Valide con estadísticas ARC/L2ARC antes de asumir que ayuda.

Tarea 14: Compruebe si ARC está dominado por metadata (una pista de que la aceleración de metadata es el objetivo)

cr0x@server:~$ arc_summary | egrep 'ARC Size|Most Recently Used|Most Frequently Used|Metadata Size|Data Size'
ARC Size:                                88.3 GiB
Most Recently Used Cache Size:           31.2 GiB
Most Frequently Used Cache Size:         56.1 GiB
Metadata Size:                           21.3 GiB
Data Size:                               65.8 GiB

Qué significa: Una porción importante es metadata. Eso es bueno cuando su carga son “muchos archivos”, snapshots y recorridos de directorios.
Decisión: Si la metadata es el problema y está en HDDs, considere special vdevs para metadata antes de lanzar RAM indefinidamente.

Tarea 15: Encuentre culpables de contaminación de caché (lectores secuenciales que aplastan su ARC)

cr0x@server:~$ iotop -oPa
Total DISK READ:         422.31 M/s | Total DISK WRITE:         12.05 M/s
  PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN  IO>    COMMAND
18322 be/4  backup    410.12 M/s    0.00 B/s  0.00 %  92.14 % tar -cf - /tank/vmstore | ...

Qué significa: Un job de backup está leyendo en streaming. Eso puede expulsar contenido útil de la caché a menos que se gestione.
Decisión: Considere poner primarycache=metadata en datasets de backup, usar patrones send/receive de snapshots o programar/limitar I/O de backups.

Tarea 16: Confirme su tope de ARC y ajústelo con seguridad (prueba temporal)

cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_arc_max
103079215104
cr0x@server:~$ echo 68719476736 | sudo tee /sys/module/zfs/parameters/zfs_arc_max
68719476736

Qué significa: Redujo zfs_arc_max a 64 GiB (el valor está en bytes). Este es un cambio en vivo en muchos entornos.
Decisión: Si la latencia de las aplicaciones mejora (menos swap, menos reclaim), mantenga un tope más bajo. Si la latencia de lectura empeora y la presión de memoria está bien, aumente RAM en su lugar.

Broma #2: L2ARC es como un segundo congelador—útil, hasta que se da cuenta de que lo compró porque olvidó cómo funcionan las compras.

Tres micro-historias corporativas (cómo falla esto en la vida real)

Micro-historia 1: El incidente causado por una suposición equivocada (“RAM por TB” como especificación de compra)

Una empresa mediana renovó sus nodos de almacenamiento para una nube privada. El RFP literalmente especificaba memoria como “1 GB por TB usable”.
Nadie lo cuestionó porque sonaba técnico y venía con un número. A procurement le encantan los números.

Los nuevos nodos llegaron con mucho disco y una cantidad respetable de RAM—según la regla por terabyte. El problema: la carga eran VMs,
mayormente lecturas y escrituras aleatorias, alojadas en un par de vdevs RAIDZ2 anchos por nodo. El conjunto caliente era pequeño y con picos, y el limitador real
eran los IOPS de escritura aleatoria y la latencia durante tormentas de snapshots.

En una semana, se acumularon tickets: “las VMs se congelan”, “time-outs en bases de datos”, “los gráficos de almacenamiento se ven bien”. Los gráficos se veían bien porque eran gráficos de ancho de banda.
La latencia fue la asesina, y ZFS hizo exactamente lo esperado: no pudo sacar IOPS mágicas de vdevs RAIDZ anchos bajo carga aleatoria.

El postmortem fue incómodo. Más RAM habría ayudado algunas lecturas, claro. Pero el fallo fue impulsado por latencia de escritura y topología de vdev.
La solución no fue “duplicar memoria”. Fue “dejar de poner cargas aleatorias de VMs en un pequeño número de vdevs RAIDZ anchos” y “separar cargas por clase de rendimiento”.

La lección: una regla de dimensionamiento que ignora IOPS es una responsabilidad. “RAM por TB” no dice nada sobre lo que suele doler primero.

Micro-historia 2: La optimización que salió mal (L2ARC en todas partes, porque los SSD son baratos)

Otro equipo gestionaba un parque de nodos de virtualización con backend ZFS. Alguien hizo las cuentas: NVMe era barato,
así que añadieron dispositivos L2ARC en cada nodo. Más caché, lecturas más rápidas. El cambio se aprobó con un buen resumen en Jira y cero mediciones.

En días, la latencia de lectura empeoró bajo carga. No catastrófica, pero suficiente para molestar a clientes y causar microinterrupciones periódicas.
El equipo culpó a la red, luego al hipervisor, luego a “sobrecarga de ZFS”.

El problema real era predecible: los nodos no tenían suficiente RAM para soportar el L2ARC de forma efectiva. L2ARC consume recursos del ARC para cabeceras y metadata,
y cambia el patrón de I/O. Los dispositivos de caché eran grandes en relación con la RAM, lo que aumentó el churn y la sobrecarga sin mantener los datos calientes correctos.
Bajo carga mixta, pagaban trabajo extra por misses.

Revertir L2ARC en algunos nodos mejoró la estabilidad de inmediato. Más tarde, reintrodujeron L2ARC solo en nodos con RAM suficiente y en cargas con localidad de lectura confirmada que excedía ARC.

La lección: “caché SSD” no es automáticamente bueno. Si no conoce sus tipos de miss y su conjunto de trabajo, solo añade otra pieza móvil que puede decepcionarlo.

Micro-historia 3: La práctica aburrida pero correcta que salvó el día (tope de ARC + disciplina de cambios)

Un equipo gestionaba un servicio de archivos ZFS para builds internos y artefactos. Durante un lanzamiento intenso, el servicio empezó a hacer time-outs.
El primer respondedor notó actividad de swap y tormentas de reclaim. Clásico.

Tenían un runbook aburrido: “Comprobar presión de memoria; capar ARC temporalmente; validar recuperación de aplicaciones; luego ajustar permanentemente.”
Sin heroísmos, sin buscar en foros. Redujeron zfs_arc_max en vivo, liberando memoria para los servicios que realmente fallaban.

La latencia bajó en minutos. No porque ARC fuera malo, sino porque el sistema había derivado: nuevos agentes, más contenedores y una mayor carga de builds consumían memoria. ARC hacía su trabajo—usar lo que había—hasta que el SO empezó a swapear.

La solución permanente no fue “apagar ARC”. Fue fijar un tope sensato de ARC, aumentar RAM en el siguiente ciclo de hardware y añadir monitorización
que alertara sobre swap y eventos de reducción del ARC. El servicio sobrevivió el lanzamiento sin otro incidente.

La lección: guardarraíles aburridos vencen a conjeturas ingeniosas. ARC es poderoso, pero nunca debe dejar sin recursos la lógica de negocio.

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

1) “ZFS está lento después de que añadimos más discos”

Síntoma: Más capacidad, peor latencia; los gráficos de ancho de banda parecen correctos.

Causa raíz: El nuevo layout de vdevs aumentó la sobrecarga de paridad o amplió RAIDZ sin añadir IOPS; la fragmentación empeoró; el pool ahora está demasiado lleno.

Solución: Compruebe zpool iostat y el llenado del pool; añada vdevs (IOPS), no solo discos (capacidad). Mantenga el uso del pool bajo control.

2) “La tasa de aciertos del ARC es alta, pero las apps siguen haciendo time-outs”

Síntoma: Hit% del ARC parece aceptable; los picos de latencia persisten.

Causa raíz: Latencia de escrituras sync (ZIL/SLOG), saturación de CPU o un vdev lento único; ARC no arregla semánticas de escrituras sync.

Solución: Mida el comportamiento sync; valide SLOG; verifique CPU y latencia por vdev. Resuelva el cuello de botella real.

3) “Añadimos L2ARC y todo empeoró”

Síntoma: Mayor latencia de lectura y más jitter tras añadir SSDs de caché.

Causa raíz: L2ARC demasiado grande respecto a la RAM; sobrecarga incrementada; churn de caché; carga inadecuada (sin localidad).

Solución: Elimine o reduzca L2ARC; asegure RAM suficiente; confirme beneficio con estadísticas de misses antes de reintroducirlo.

4) “Las VMs tartamudean durante backups”

Síntoma: Caídas de rendimiento previsibles durante ventanas de backup.

Causa raíz: Lecturas secuenciales que contaminan ARC y compiten por disco; scrub/resilver colisionando con I/O de producción.

Solución: Limite I/O de backups, separe datasets, use primarycache=metadata donde proceda, programe scrubs con cuidado.

5) “Tenemos mucha RAM; ¿por qué ARC no es enorme?”

Síntoma: El tamaño del ARC parece limitado o menor al esperado.

Causa raíz: zfs_arc_max establecido intencionalmente o por defecto de la distro; presión de memoria; límites de contenedores; interacciones con hugepages.

Solución: Inspeccione parámetros de ARC y disponibilidad de memoria; cambie topes deliberadamente; no deje sin recursos al SO.

6) “Operaciones con archivos pequeños son lentas en pool HDD”

Síntoma: Listados de directorios, descomprimir, operaciones git son dolorosas.

Causa raíz: Búsquedas de metadata en HDDs; cache de metadata insuficiente; sin special vdev.

Solución: Asegure RAM adecuada para metadata; considere special vdev para metadata/bloques pequeños; verifique con comportamiento de aciertos de metadata.

7) “El rendimiento se desploma cuando el pool se acerca al lleno”

Síntoma: Estaba bien al 60%, fatal al 90%.

Causa raíz: Sobrecarga de asignación y fragmentación; metaslabs restringidos; la amplificación de escritura de RAIDZ duele más.

Solución: Añada capacidad, migre datos, aplique cuotas/reservas. No trate 95% como “operación normal”.

8) “Ajustamos recordsize y las lecturas aleatorias empeoraron”

Síntoma: Aumenta la latencia tras cambiar ajustes del dataset.

Causa raíz: recordsize mal elegido para la carga; cambió el patrón de I/O y el comportamiento de caché; desajuste con el tamaño de bloque de la aplicación.

Solución: Use recordsize apropiado por dataset; pruebe con carga representativa; no lo cambie globalmente en pánico.

Listas de verificación / plan paso a paso

Plan A: Va a comprar hardware y quiere dimensionar RAM sin religión

  1. Escriba la carga. ¿VMs? ¿NFS home dirs? ¿Object store? ¿Base de datos? ¿Mixta?
  2. Elija dos métricas que importen. Ejemplo: p95 de latencia de lectura y p95 de latencia de escritura sync.
  3. Decida la hipótesis del conjunto caliente. “Creemos que 200 GB se leen repetidamente durante horas laborales.” Ponga un número.
  4. Elija una base conservadora de RAM. Deje espacio para SO/apps; planifique capar ARC.
  5. Elija topología del pool priorizando IOPS. Mirrors y más vdevs superan a RAIDZ ancho para cargas aleatorias.
  6. Decida si necesita aceleración de metadata. Si sí, considere special vdevs (con redundancia) en lugar de RAM infinita.
  7. Planifique observabilidad. Estadísticas de ARC, latencia, swap, CPU y métricas por vdev desde el día uno.
  8. Ejecute una prueba de carga parecida a producción. Si no puede, está adivinando—admítalo y añada margen de seguridad.

Plan B: Producción está lenta y necesita una solución con riesgo mínimo

  1. Compruebe swap y reclaim. Si hay swapping, limite ARC y estabilice.
  2. Compruebe el llenado del pool. Si está peligrosamente lleno, deténgase y arregle capacidad. Todo lo demás es maquillaje.
  3. Compruebe latencia y comportamiento sync. Identifique si el problema son lecturas o escrituras.
  4. Identifique contaminación de caché. Backups y scans son ofensoras frecuentes.
  5. Solo entonces ajuste propiedades del dataset. Hágalo por dataset, con notas de reversión.
  6. Reevalúe con las mismas métricas. Si no midió antes, mida después y no pretenda demostrar nada sin datos.

Plan C: Sospecha que falta RAM para ARC (y quiere evidencias)

  1. Confirme que ARC está en/near el máximo bajo carga normal.
  2. Confirme que miss% permanece elevado durante el periodo lento.
  3. Confirme que la carga es lectora y tiene localidad. Lecturas aleatorias que golpean repetidamente el mismo conjunto, no un escaneo.
  4. Confirme que los discos son el cuello de botella en los misses. Si los SSD ya son lo bastante rápidos, el beneficio de ARC puede ser marginal.
  5. Añada RAM o reasigne memoria y vuelva a probar. La mejora debe mostrarse en p95 de latencia, no solo en “se siente mejor”.

Preguntas frecuentes

1) ¿Cuánta RAM necesito para ZFS?

Suficiente para ejecutar su carga sin swapear, más ARC suficiente para reducir de forma material sus lecturas costosas. Empiece con una base sensata (16–64 GB según rol),
mida misses y latencia del ARC y escale RAM solo si reduce su cuello de botella.

2) ¿Es “1 GB RAM por TB” alguna vez una regla útil?

Como advertencia de que “pools grandes con cargas ricas en metadata en discos lentos necesitan memoria”, sí. Como especificación de compra, no.
Ignora IOPS, carga, ajuste de datasets y la realidad de que existe dato frío.

3) ¿Más ARC siempre mejora el rendimiento?

No. Si está limitado por latencia de escrituras, CPU, topología o sufre contaminación de caché, más ARC puede no hacer nada o empeorar al aumentar la presión de memoria.

4) ¿Debería capar ARC?

En servidores de uso mixto (hipervisores, hosts de contenedores, cajas con bases de datos), sí—capéelo deliberadamente.
En appliances de almacenamiento dedicados puede dejarlo crecer, pero valide comportamiento bajo presión y tras reinicios.

5) ¿Qué tasa de aciertos del ARC es “buena”?

“Buena” es cuando la latencia de la aplicación cumple el objetivo. La tasa de aciertos es contextual. Una carga de streaming puede tener hit% bajo y estar bien.
Una carga de VMs con hit% bajo y alta latencia de lectura se sentirá mal.

6) ¿Cuándo tiene sentido L2ARC?

Cuando su conjunto de trabajo es mayor que la RAM pero aún tiene localidad, y sus discos son lo bastante lentos como para que los aciertos en SSD importen.
También cuando tiene suficiente RAM para alimentarlo. L2ARC no es un parche para mala topología de pool.

7) ¿ZFS es “glotón” de memoria comparado con otros sistemas de archivos?

ZFS usará la RAM disponible para ARC porque es útil. Eso puede parecer “glotonería” en paneles.
La pregunta no es “¿es grande el ARC?”, sino “¿es el sistema estable y la latencia mejora?”.

8) ¿La compresión cambia las necesidades de RAM?

A menudo sí—para bien. La compresión puede aumentar la capacidad efectiva del ARC porque más dato lógico cabe por byte cacheado, y reduce I/O.
Pero si la CPU se convierte en cuello de botella, simplemente movió el problema.

9) ¿Qué hay de la deduplicación?

Úsela solo si puede probar los ahorros y entiende las implicaciones de memoria y rendimiento para su versión y carga.
Si activa dedup sin plan, se está postulando voluntario para un incidente.

10) ¿Por qué cambia el rendimiento tras un reinicio?

ARC empieza frío. Si su rendimiento depende de una caché caliente, verá un periodo lento después del reinicio.
Eso es comportamiento normal de caché. Soluciónelo con RAM adecuada, diseño consciente de la carga y evitando suposiciones “dependientes de caché” en rutas críticas.

Siguientes pasos que puede hacer esta semana

Si quiere una decisión de dimensionamiento de ARC defendible—que no lo ridiculicen en una revisión—haga esto en orden:

  1. Establezca la línea base del sistema: recopile free -h, vmstat, estadísticas ARC y zpool iostat durante un periodo de lentitud.
  2. Separe el problema: decida si está limitado por lecturas, escrituras o latencia sync. No adivine.
  3. Elimine el daño autoinfligido: arregle llenado del pool, deje de swapear y evite que los backups aplasten su caché.
  4. Afine por dataset: alinee recordsize, primarycache y atime con la carga.
  5. Sólo entonces compre RAM: si los misses siguen altos bajo localidad estable y los discos son el cuello de botella, añada RAM y verifique la mejora con las mismas métricas.

Si alguien insiste en “RAM por TB”, haga una pregunta: “¿Qué carga y qué objetivo de latencia?” Si no pueden responder, no están dimensionando. Están recitando.

← Anterior
Ubuntu 24.04: Filtrado de ruta inversa — el ajuste oculto que rompe el multihoming (caso nº 54)
Siguiente →
Corregir contenido duplicado en WordPress: canónica, barra final y www sin canibalización

Deja un comentario