Si ejecutas ZFS el tiempo suficiente, alguien acabará entrando en pánico por la «desaparición» de RAM.
Te mostrarán un panel donde la “memoria libre” está cerca de cero, y dirán la frase que todo SRE escucha en sus sueños:
“ZFS se está comiendo toda nuestra RAM.”
Aquí está el remate: ZFS debe usar tu RAM. ZFS trata la memoria como un pedal de acelerador, no como una pieza de museo.
El truco no es mantener la RAM “libre”. El truco es mantenerla útil—sin dejar a las aplicaciones sin memoria, sin provocar tormentas de swap,
y sin confundir un caché sano con una fuga.
ARC en una frase
ARC (Adaptive Replacement Cache) es el caché en memoria de ZFS para bloques usados recientemente y con frecuencia—datos y metadatos—
diseñado para convertir lecturas caras de disco en lecturas baratas desde la RAM, adaptándose dinámicamente a tu carga de trabajo.
Broma #1: “RAM libre” es como un asiento vacío en un avión—reconfortante a la vista, pero lo estás pagando igual.
Por qué la “RAM libre” es un mito (en términos de producción)
En un SO moderno, la RAM sin usar es una oportunidad desperdiciada. El kernel usa la memoria agresivamente para cachés: caché del sistema de archivos,
caché de inode/dentry, asignaciones slab y ARC de ZFS. Esto no es una rareza de ZFS; es economía básica.
La RAM es el nivel de almacenamiento más rápido que tienes.
La confusión viene de paneles y métricas simplistas. Muchos gráficos aún tratan la “memoria usada” como sospechosa y
la “memoria libre” como segura. Eso está al revés. Lo que quieres es:
- Baja actividad de swap (especialmente entradas/salidas sostenidas).
- Comportamiento sano de reclamo de páginas (sin thrashing, sin OOM kills).
- Latencias de aplicación estables bajo carga.
- Comportamiento predecible del ARC en relación con tu carga de trabajo.
ARC puede ser grande y aun así inofensivo—siempre que pueda encogerse cuando llegue la presión de memoria, y si no empuja tus cargas a swap.
A la inversa, puedes tener “RAM libre” y aun así ir lento, si tu conjunto de trabajo no cabe en caché y tus discos realizan I/O aleatorio.
Una forma práctica de pensarlo: la RAM libre no es un objetivo; la RAM reclamable sí lo es. ARC debería ser reclamable bajo presión,
y el sistema debe permanecer estable cuando se reclama.
Qué es realmente ARC (y qué no es)
ARC no es la page cache de Linux (pero compite con ella)
Si estás en Linux con OpenZFS, efectivamente tienes dos sistemas de caché en juego:
la page cache de Linux y el ARC de ZFS. ZFS usa ARC para el almacenamiento gestionado por ZFS. Linux usa la page cache para I/O de archivos
y cualquier otro acceso respaldado por los mecanismos de caché del kernel.
Dependiendo de tu carga y de la ruta de I/O, puedes acabar con doble caché o compitiendo por memoria.
Por ejemplo, cargas de bases de datos que ya implementan su propio caché pueden acabar pagando por caché tres veces:
caché de la aplicación, ARC y (a veces) efectos de page cache según I/O directo vs buffered.
ARC es adaptativo (y es selectivo con lo que guarda)
ARC no es un caché tonto de “conservar los últimos N bloques”. Usa un algoritmo de reemplazo adaptativo diseñado para equilibrar:
- Recencia: “Usé esto recientemente, podría volver a usarlo pronto.”
- Frecuencia: “Uso esto repetidamente a lo largo del tiempo.”
Eso importa en sistemas reales. Considera:
un trabajo nocturno que escanea terabytes secuencialmente (fuerte en recencia, baja reutilización) versus un datastore de VM con bloques calientes
leídos repetidamente (fuerte en frecuencia). El objetivo de ARC es evitar ser “contaminado” por escaneos puntuales mientras captura
datos realmente calientes.
ARC cachea metadatos, que pueden importar más que los datos
En muchas implantaciones de ZFS en producción, el caché de metadatos es la diferencia entre “ágil” y “¿por qué se está colgando ls?”.
Los metadatos incluyen dnodes, bloques indirectos, estructuras de directorio y varias estructuras de búsqueda.
Si alguna vez has visto un sistema de almacenamiento derrumbarse bajo cargas de “archivos pequeños”, te has topado con los metadatos por las malas.
Puedes tener mucho rendimiento de disco y aun así bloquearte porque el sistema está haciendo pointer-chasing en disco
por metadatos que deberían haber estado en RAM.
Qué vive en ARC: datos, metadatos y cosas que sorprenden
Bloques de datos vs bloques de metadatos
ARC contiene bloques cacheados de tu pool. Algunos son datos de archivos. Otros son metadatos.
La mezcla cambia según la carga. Una granja de VM tiende a tener muchas lecturas repetidas y churn de metadatos; un archivo de medios
puede principalmente hacer streaming de bloques grandes una vez; un servidor Git puede ser pesado en metadatos con ráfagas.
El prefetch puede ayudar, y también puede incendiar tu RAM
ZFS hace read-ahead (prefetch) en varios escenarios. Cuando funciona, convierte lecturas secuenciales en un flujo suave.
Cuando falla—como cuando tu carga “secuencial” es en realidad muchas transmisiones entrelazadas—puede inundar ARC con
datos que no serán reutilizados.
Consecuencia real: puedes expulsar metadatos útiles para hacer espacio a datos prefetch inútiles.
Entonces todo lo demás se vuelve más lento, y la gente culpa a la “sobrecarga de ZFS” cuando en realidad es contaminación de caché.
Bloques comprimidos y las cuentas de RAM que la gente se equivoca
ZFS almacena bloques comprimidos en disco. ARC normalmente almacena datos de una manera que depende de detalles de implementación y carga,
pero la verdad operativa es: la compresión cambia tu modelo mental. Si comprimes bien, la capacidad efectiva de caché
puede aumentar porque más datos lógicos caben por unidad física. Pero el coste de CPU y la sobrecarga de memoria para la gestión
son reales, y se notan a escala.
Dedup: el “aguanta mi cerveza” del consumo de RAM
La deduplicación en ZFS es famosa por ser poderosa y peligrosa a la vez. La tabla de dedup (DDT) necesita acceso rápido, y
acceso rápido significa memoria. Si activas dedup sin suficiente RAM para el conjunto de trabajo del DDT, puedes convertir un sistema de almacenamiento
en un generador de I/O aleatorio con una línea secundaria de miseria.
Broma #2: Habilitar dedup en una máquina hambrienta de RAM es como adoptar un tigre porque conseguiste una buena oferta de comida para gatos.
Cómo ARC crece, se encoge y a veces se niega a “soltar”
Dimensionado de ARC es una negociación con el SO
ARC tiene un rango objetivo de tamaño, gobernado por tunables como zfs_arc_min y zfs_arc_max.
El kernel aplicará presión cuando otros subsistemas necesiten memoria.
En un sistema bien comportado, ARC crece cuando la RAM está disponible y se encoge cuando se necesita en otra parte.
En un sistema poco entendido, la gente ve ARC en “máximo” y asume que es una fuga. Usualmente no lo es.
ARC se comporta según el diseño: encontró memoria libre y la usó para acelerar lecturas.
Por qué ARC a veces no se encoge “lo suficientemente rápido”
Hay casos en los que el encogimiento de ARC puede quedarse atrás frente a una demanda repentina de memoria:
ráfagas de contenedores, expansiones de heap de JVM o una expansión de la page cache para una carga no-ZFS.
ARC es reclamable, pero no necesariamente instantáneamente reclamable, y el camino desde “presión” hasta “bytes liberados”
puede tener latencia.
Cuando esa latencia coincide con cargas agresivas, ves swapping, consumo de CPU en kswapd y picos de latencia en la cola.
Ahí es cuando ARC se vuelve políticamente impopular.
El dolor especial de la virtualización y los “vecinos ruidosos”
En entornos hypervisor (o hosts de contenedores grandes), la contabilidad de memoria se complica. Los invitados tienen su propio caché.
El host tiene ARC. El host también puede tener page cache para otros archivos. Si sobreasignas memoria o permites
ballooning/overcommit sin guardarruedas, ARC se convierte en chivo expiatorio de una planificación de capacidad fundamentalmente mala.
Hechos e historia: cómo llegamos aquí
- ZFS nació en Sun Microsystems como un diseño de “pool de almacenamiento + sistema de archivos”, no como un gestor de volúmenes añadido.
- ARC está basado en el algoritmo Adaptive Replacement Cache, que mejoró el simple LRU balanceando recencia y frecuencia.
- ZFS popularizó el checksum end-to-end para la integridad de datos, lo que aumenta el trabajo de metadatos—y hace que cachéar metadatos sea más valioso.
- La filosofía de “usar RAM como caché” precede a ZFS; los kernels Unix llevan tiempo usando memoria libre para caché, pero ZFS lo hizo imposible de ignorar.
- Las primeras guías de ZFS decían “la RAM es reina” en parte porque los discos eran más lentos y el I/O aleatorio era brutalmente caro comparado con la RAM.
- L2ARC (el caché secundario) llegó para extender el caché a dispositivos rápidos, pero no es gratis: necesita metadatos en ARC para ser útil.
- La dedup se volvió notoria porque movió una optimización tradicionalmente offline a una ruta de código en tiempo real y hambrienta de RAM.
- OpenZFS llevó ZFS a Linux y otras plataformas, donde tuvo que coexistir con distintos subsistemas de VM y caché, cambiando las realidades de tuneo.
- NVMe cambió las reglas: los discos se volvieron tan rápidos que las malas decisiones de caché son a veces menos obvias—hasta que golpeas la latencia cola.
Tres microhistorias del mundo corporativo
Microhistoria #1: El incidente causado por una suposición equivocada (“La RAM libre es saludable”)
Una compañía mediana ejecutaba un clúster NFS respaldado por ZFS que servía directorios home y artefactos de build.
Un nuevo manager—inteligente, rápido y recién entrenado en otra pila—implementó un cambio de “endurecimiento” de memoria:
limitar ARC agresivamente para que “al menos el 40% de la RAM quede libre”. Sonaba razonable en una hoja de cálculo.
La primera semana parecía bien. Los paneles eran reconfortantes: muchas zonas verdes, mucha “memoria libre”.
Entonces llegó el ciclo de lanzamiento trimestral. Los jobs de build se esparcieron, los archivos pequeños se multiplicaron y los servidores NFS empezaron
a tartamudear. No se cayeron, solo se pusieron lo bastante lentos para que todo lo demás pareciera roto.
El síntoma que elevó el incidente no fue “alta utilización de disco”. Fue el tipo feo:
iowait subiendo, latencias en operaciones de metadatos disparadas y los hilos NFS acumulándose.
El pool no estaba saturado en throughput. Se estaba ahogando en lecturas aleatorias de metadatos que antes vivían felices en ARC.
El postmortem no fue para culpar. Fue sobre una suposición equivocada: “memoria libre” no es un indicador de estabilidad.
La solución fue igualmente poco sexy: permitir que ARC creciera, pero poner un límite superior sensato basado en el margen real de las aplicaciones,
y añadir alertas sobre la actividad de swap real y las tasas de expulsión de ARC—no sobre la “RAM libre”.
La lección: si tratas la RAM como un trofeo, ZFS tratará tus discos como un papel de boceto.
Microhistoria #2: La optimización que salió mal (L2ARC por todas partes)
Otra empresa tenía un pool ZFS que soportaba un clúster de virtualización. Las lecturas eran el punto doloroso, así que alguien propuso
añadir dispositivos L2ARC. Tenían SSDs de sobra, y el plan era simple: “Añadimos L2ARC y la ratio de cache subirá”.
Es una venta fácil porque es hardware tangible.
Añadieron un L2ARC grande, vieron los gráficos y… no pasó nada mágico. De hecho, bajo ciertas cargas,
la latencia empeoró. No fue catastrófico; fue insidioso. Las VMs se sentían “pegajosas” durante las tormentas de arranque matutinas,
y las cargas aleatorias se volvieron más espasmódicas.
El culpable no eran los SSDs. Era la memoria. L2ARC necesita metadatos en ARC para ser efectivo. Cuanto más grande es el L2ARC,
más sobrecarga de ARC gastas en indexarlo. En un host ya ajustado de RAM, la presión extra empujó a ARC
a expulsar con más frecuencia exactamente los metadatos que el sistema necesitaba.
La reversión no fue dramática. Redujeron el tamaño de L2ARC, añadieron RAM en el siguiente ciclo de renovación y ajustaron expectativas:
L2ARC ayuda mejor cuando el conjunto de trabajo es más grande que la RAM pero sigue siendo “cacheable”, y cuando puedes costear la sobrecarga de memoria.
Si no, has construido una forma muy cara de volver tu caché menos estable.
La lección: el caching no es aditivo; es un presupuesto. Si lo gastas dos veces, te arruinas en latencia.
Microhistoria #3: La práctica aburrida que salvó el día (medir antes de tunear)
Un equipo de servicios financieros ejecutaba ZFS para una canalización de ingestión de archivos. No eran el equipo más ruidoso, pero sí disciplinados.
Su práctica era dolorosamente aburrida: antes de cualquier “tuneo”, capturaban un paquete base de métricas—estadísticas de ARC, latencia de I/O,
actividad de swap y settings por dataset de recordsize/compression. Cada cambio venía con una comparación antes/después.
Una tarde, la latencia de ingestión se duplicó. El objetivo fácil de culpar fue ARC: “Quizá el caché está thrashing”.
Pero su baseline contó otra historia. La ratio de hit de ARC era estable. Las expulsiones no eran inusuales. Lo que cambió fue
la presión de memoria: se desplegó un sidecar nuevo con un heap sin límites.
El sistema no fallaba porque ARC fuera codicioso; fallaba porque el host estaba sobreasignado.
ARC estaba haciendo lo que podía—encogiéndose bajo presión—pero el otro proceso seguía expandiéndose, empujando la máquina al swap.
Sus gráficos lo mostraron claramente: la entrada/salida de swap subió primero, luego la latencia, luego tiempo CPU en reclaim.
La solución no fue un tunable arcano de ZFS. Fue un límite de recursos y la reversión de un despliegue malo.
La práctica aburrida—capturar baselines y vigilar los indicadores correctos—les evitó empeorar la situación estrangulando ARC a ciegas.
La lección: la mayoría de “problemas de memoria ZFS” son en realidad problemas de memoria del sistema con disfraz de ZFS.
Tareas prácticas: comandos, salidas y qué significan
El objetivo aquí no es memorizar comandos. Es crear memoria muscular:
verifica la carga, confirma la presión de memoria y luego decide si ARC ayuda o perjudica.
Los comandos abajo asumen un sistema Linux con OpenZFS instalado; ajusta rutas para otras plataformas.
Tarea 1: Ver la realidad global de memoria (no el pánico por “RAM libre”)
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 251Gi 41Gi 2.1Gi 1.2Gi 208Gi 198Gi
Swap: 16Gi 0B 16Gi
Interpretación: “Libre” es bajo, pero “available” es enorme. Eso usualmente significa que el sistema está cacheando agresivamente y puede reclamar memoria.
Si el swap está tranquilo y “available” es saludable, probablemente esté bien.
Tarea 2: Comprobar si realmente está ocurriendo swapping
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
2 0 0 2212140 10240 189512000 0 0 12 44 520 880 6 2 91 1 0
1 0 0 2198840 10240 189625000 0 0 0 0 500 860 5 2 92 1 0
4 1 0 2101020 10240 189540000 0 0 220 180 1100 1600 10 4 74 12 0
3 0 0 2099920 10240 189520000 0 0 140 120 920 1300 8 3 81 8 0
2 0 0 2103200 10240 189610000 0 0 30 60 600 900 5 2 91 2 0
Interpretación: Observa si/so (swap in/out). Valores sostenidos distintos de cero significan que la máquina está bajo presión de memoria.
Un poco de I/O wait (wa) no es automáticamente culpa de ARC; correlaciona con aciertos/fallos de ARC y latencia de disco.
Tarea 3: Leer tamaño y límites de ARC directamente
cr0x@server:~$ grep -E '^(c|size|c_min|c_max|memory_throttle_count)' /proc/spl/kstat/zfs/arcstats
c 4 214748364800
c_min 4 10737418240
c_max 4 214748364800
size 4 198742182912
memory_throttle_count 4 0
Interpretación: size es el tamaño actual de ARC. c es el objetivo. c_max es el tope.
Si memory_throttle_count sube, ARC ha experimentado eventos de presión de memoria que valen la pena investigar.
Tarea 4: Comprobar comportamiento de aciertos/fallos de ARC (¿está ayudando?)
cr0x@server:~$ grep -E '^(hits|misses|demand_data_hits|demand_data_misses|demand_metadata_hits|demand_metadata_misses)' /proc/spl/kstat/zfs/arcstats
hits 4 18230933444
misses 4 1209933221
demand_data_hits 4 12055411222
demand_data_misses 4 902331122
demand_metadata_hits 4 5800122201
demand_metadata_misses 4 307602099
Interpretación: Muchos aciertos respecto a fallos es bueno, pero no idolatres la ratio de aciertos.
Lo que importa es la latencia y la carga del disco. Una buena ratio puede seguir siendo demasiado lenta si tus fallos son caros (lecturas aleatorias en HDD),
y una mala ratio puede ser aceptable si tu pool es NVMe y tu carga es de streaming.
Tarea 5: Vigilar ARC en vivo con arcstat (cuando esté instalado)
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:01 812 42 5 30 4 8 1 4 0 185G 200G
12:01:02 900 55 6 40 4 10 1 5 1 185G 200G
12:01:03 1100 220 20 190 17 18 2 12 1 184G 200G
12:01:04 980 180 18 150 15 20 2 10 1 184G 200G
12:01:05 860 60 7 45 5 10 1 5 1 184G 200G
Interpretación: Un pico de fallos durante un escaneo por lotes es normal. Una tormenta persistente de fallos durante el “estado estable”
a menudo significa que tu conjunto de trabajo no cabe, contaminación por prefetch, o un cambio de carga (nuevo dataset, nuevo patrón de acceso).
Tarea 6: Comprobar estrés de reclaim de memoria (Linux)
cr0x@server:~$ cat /proc/pressure/memory
some avg10=0.00 avg60=0.05 avg300=0.12 total=1843812
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
Interpretación: PSI memory “some” indica tiempo pasado bloqueado por presión de memoria; “full” es peor (tareas completamente bloqueadas).
PSI en ascenso junto a actividad de swap y ARC en tope es una señal para revisar presupuestos de memoria.
Tarea 7: Confirmar salud del pool y cuellos de botella obvios
cr0x@server:~$ zpool status -xv
all pools are healthy
Interpretación: No afines cachés en un pool enfermo. Si tienes errores, resilvering o vdevs degradados, tu “problema de ARC”
puede ser un “problema de hardware”.
Tarea 8: Observar latencia de I/O, no solo el throughput
cr0x@server:~$ zpool iostat -v 1 3
capacity operations bandwidth
pool alloc free read write read write
tank 48.2T 21.6T 8200 1100 690M 120M
raidz2-0 48.2T 21.6T 8200 1100 690M 120M
sda - - 1020 130 85M 10M
sdb - - 1015 135 86M 11M
sdc - - 1040 140 86M 10M
sdd - - 1030 135 85M 10M
Interpretación: Esto muestra operaciones y ancho de banda, pero no latencia. Si las cosas “se sienten lentas”, combina esto con herramientas como
iostat -x para ver await/util y correlaciona con fallos de ARC.
Tarea 9: Comprobar latencia de dispositivo con iostat
cr0x@server:~$ iostat -x 1 3
Device r/s w/s rMB/s wMB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
sda 1020.0 130.0 85.0 10.0 0.0 8.0 0.00 5.80 9.10 6.20 9.50 85.3 79.1 0.40 46.0
sdb 1015.0 135.0 86.0 11.0 0.0 9.0 0.00 6.20 9.40 6.10 9.60 86.7 83.1 0.41 46.5
Interpretación: Un aumento de r_await y alto %util durante picos de fallos de ARC significa que tus discos están pagando por los misses.
Si la latencia ya es baja (por ejemplo, NVMe), los misses de ARC pueden no ser el villano.
Tarea 10: Identificar qué datasets están configurados para comportarse caro
cr0x@server:~$ zfs get -o name,property,value -s local,received recordsize,primarycache,secondarycache,compression tank
NAME PROPERTY VALUE
tank compression lz4
tank primarycache all
tank recordsize 128K
Interpretación: primarycache=all significa que se cachean en ARC tanto datos como metadatos.
Para algunas cargas (bases de datos, streaming grande), podrías elegir metadata para reducir presión de ARC.
No lo hagas por superstición—mide.
Tarea 11: Comprobar si una carga está sortando las expectativas de caché
cr0x@server:~$ zfs get -o name,property,value atime,sync,logbias,primarycache tank/vmstore
NAME PROPERTY VALUE
tank/vmstore atime off
tank/vmstore sync standard
tank/vmstore logbias latency
tank/vmstore primarycache all
Interpretación: Ajustes como sync y logbias no cambian ARC directamente, pero cambian el comportamiento de I/O.
Si las escrituras son lentas y causan retropresión, las lecturas pueden sufrir y el “debate sobre ARC” se convierte en una distracción.
Tarea 12: Establecer un tope temporal de ARC (con cuidado) para experimentos
cr0x@server:~$ sudo sh -c 'echo $((64*1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max'
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_arc_max
68719476736
Interpretación: Esto establece el máximo de ARC a 64 GiB (el valor está en bytes). Úsalo para probar hipótesis de headroom, no como “arreglo” permanente.
El tuning permanente debe hacerse vía la configuración de parámetros del módulo de tu distro para persistir tras reinicios.
Tarea 13: Forzar la pregunta—¿el rendimiento sigue al tamaño de ARC o a la latencia de disco?
cr0x@server:~$ sudo sh -c 'echo $((128*1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max'
cr0x@server:~$ sleep 10
cr0x@server:~$ grep -E '^(size|c|c_max)' /proc/spl/kstat/zfs/arcstats
c 4 137438953472
c_max 4 137438953472
size 4 132001234944
Interpretación: Aumenta el tope de ARC temporalmente y observa si la latencia mejora y los fallos bajan.
Si no cambia nada, el cuello de botella puede ser la vía de escritura, la CPU, la red o el patrón de acceso de la aplicación.
Tarea 14: Detectar mensajes del kernel relacionados con ARC
cr0x@server:~$ dmesg -T | grep -i -E 'arc|spl|zfs' | tail -n 10
[Thu Dec 25 09:44:10 2025] ZFS: Loaded module v2.2.4-1
[Thu Dec 25 10:02:31 2025] ZFS: ARC size 197G, target 200G, min 10G, max 200G
Interpretación: Busca advertencias sobre throttling de memoria, fallos al asignar o eventos repetidos de reclaim.
Si los logs están ruidosos, estás más allá de “ARC es grande” y en “ARC está peleando con el kernel”.
Tarea 15: Determinar si tu carga está dominada por metadatos
cr0x@server:~$ grep -E '^(demand_metadata_hits|demand_metadata_misses|demand_data_hits|demand_data_misses)' /proc/spl/kstat/zfs/arcstats
demand_data_hits 4 12055411222
demand_data_misses 4 902331122
demand_metadata_hits 4 5800122201
demand_metadata_misses 4 307602099
Interpretación: Si los fallos de metadatos son significativos y correlacionan con operaciones de directorio lentas, aperturas de archivo lentas o IOPS altos en disco,
prioriza mantener metadatos calientes: evita contaminación de caché, evita caps de ARC muy pequeños y considera ajustes de caché por dataset.
Guía rápida de diagnóstico
Cuando alguien te manda “ZFS está usando toda la RAM” o “ZFS va lento”, no tienes tiempo para un seminario filosófico.
Necesitas una secuencia corta y fiable que encuentre el cuello de botella rápido.
Paso 1: ¿El host está bajo presión de memoria o solo cacheando?
- Revisa
free -hy céntrate en available, no en free. - Revisa
vmstat 1buscandosi/sosostenidos > 0. - Revisa PSI memory (
/proc/pressure/memory) buscando “some/full” en ascenso.
Si el swap está activo y PSI sube, tienes un problema de presión de memoria. ARC puede estar involucrado, pero rara vez es el único actor.
Paso 2: ¿Las lecturas son lentas porque ARC falla, o porque los discos ya son lentos?
- Revisa aciertos/fallos de ARC (
/proc/spl/kstat/zfs/arcstatsoarcstat). - Revisa latencia de disco (
iostat -x 1) y comportamiento del pool (zpool iostat 1).
Si los fallos de ARC suben y la latencia de disco sube, tu caché no cubre tu conjunto de trabajo—o está siendo contaminada.
Si los fallos suben pero los discos mantienen baja latencia, el problema de rendimiento puede estar en otro lado (CPU, red, app).
Paso 3: ¿La carga está cambiando la economía del caché?
- Busca escaneos grandes, backups, reindex, tormentas de arranque de VM o replicación.
- Identifica si los fallos de metadatos aumentaron (cargas de archivos pequeños, millones de inodos).
- Revisa propiedades de dataset:
primarycache,recordsize, compresión, sync/logbias.
Muchos “incidentes de ARC” son realmente incidentes de “hubo un job por lotes”. Tu respuesta debería ser aislar o programar el job,
no dejar permanentemente el caché lisiado.
Paso 4: Decide: ¿tunear límites de ARC, tunear la carga o añadir RAM?
- Si el host está haciendo swap: reserva margen (cap ARC) y soluciona el culpable de memoria.
- Si los discos están saturados por fallos: aumenta el caché efectivo (más RAM, mejor política de caché, reducir contaminación).
- Si la latencia está bien: no lo toques y pasa al verdadero cuello de botella.
Listas de verificación / plan paso a paso
Checklist A: “¿ARC está perjudicando mis aplicaciones?”
- Confirmar actividad de swap:
cr0x@server:~$ vmstat 1 10Busca
si/sosostenidos ywaen aumento. - Confirmar disponibilidad de memoria:
cr0x@server:~$ free -hSi
availablees bajo y sigue cayendo, realmente te falta memoria. - Comprobar tope y tamaño de ARC:
cr0x@server:~$ grep -E '^(size|c_max|c_min|memory_throttle_count)' /proc/spl/kstat/zfs/arcstatsSi ARC está en tope y memory_throttle_count sube, considera cambiar el headroom.
- Correlacionar con latencia de apps y logs de OOM:
cr0x@server:~$ dmesg -T | tail -n 50Si ves OOM kills, el dimensionado de ARC no es la causa raíz; es overcommit.
Checklist B: “¿ARC es demasiado pequeño para esta carga?”
- Medir fallos de ARC durante la ventana del problema:
cr0x@server:~$ arcstat 1 30Fallos persistentes durante carga normal es una bandera roja.
- Comprobar latencia de disco al mismo tiempo:
cr0x@server:~$ iostat -x 1 30Si las awaits suben durante las tormentas de fallos, el pool lo está pagando.
- Probar un aumento controlado de ARC max (si tienes margen):
cr0x@server:~$ sudo sh -c 'echo $((192*1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max'Observa si la latencia mejora y los fallos bajan. Si sí, la solución suele ser “más RAM o mejor aislamiento”.
Checklist C: “Mantener metadatos calientes, detener contaminación de caché”
- Identificar jobs tipo escaneo (backup, scrub, rsync, reindex) y programarlos fuera de pico.
- Considerar
primarycache=metadatapara datasets de streaming que no se benefician de cachear datos:cr0x@server:~$ sudo zfs set primarycache=metadata tank/archiveEsto puede reducir el churn de ARC mientras mantiene rápidas las búsquedas de directorio.
- Validar con estadísticas de ARC: los fallos de metadatos deberían bajar; las IOPS de disco deberían estabilizarse.
Errores comunes (síntomas y soluciones)
Error 1: Alertar por “RAM libre”
Síntomas: Llamadas constantes al on-call, sin problema real de rendimiento, presión para “arreglar la memoria de ZFS.”
Solución: Alertar sobre actividad de swap (vmstat si/so), PSI memory “full”, eventos OOM y latencia de aplicación.
Usa la memoria “available”, no “free”, en los paneles.
Error 2: Limitar ARC sin medir la carga
Síntomas: Salto en IOPS de disco, operaciones pesadas en metadatos lentas, “todo se siente lento” en picos.
Solución: Restaurar un tope razonable de ARC; medir fallos de ARC y latencia de disco.
Si necesitas margen para apps, limita ARC según un presupuesto (apps + kernel + margen de seguridad), no según un porcentaje de “libre”.
Error 3: Tratar la ratio de aciertos de ARC como KPI
Síntomas: Gente celebra una alta tasa de aciertos mientras la latencia cola es terrible; o se asusta por una baja tasa en cargas de streaming.
Solución: Prioriza latencia y salud del swap. La ratio de aciertos depende del contexto.
Un streaming de medios puede tener baja ratio y aun así ser rápido; un servidor NFS pesado en metadatos no.
Error 4: Habilitar dedup porque “ahorra espacio”
Síntomas: Colapso de rendimiento súbito, muchas lecturas aleatorias, presión de memoria, escrituras lentas, sobrecarga relacionada con DDT.
Solución: No actives dedup sin un modelo real de capacidad/rendimiento y presupuesto de memoria.
Si ya está habilitado y sufres, planifica una estrategia de migración; “apagarlo” no es instantáneo para los bloques existentes.
Error 5: Lanzar L2ARC al problema en un sistema ajustado de RAM
Síntomas: Sin mejora o latencia peor; presión de ARC aumenta; persistencia de fallos de metadatos.
Solución: Asegura primero RAM adecuada; mantén L2ARC de tamaño apropiado; valida que la carga tenga reutilización.
Si tu carga son lecturas mayormente puntuales, L2ARC es un placebo caro.
Error 6: Ignorar problemas de la vía de escritura y culpar a ARC
Síntomas: Lecturas lentas “a veces”, pero el gatillo real son escrituras sync, latencia de commit o un SLOG/vdev de escritura saturado.
Solución: Mide de extremo a extremo: zpool iostat, latencia de dispositivo y patrones de escritura de la aplicación.
Arregla cuellos de botella de escritura; no microgestiones ARC para compensar.
Error 7: Ejecutar cargas mixtas sin aislamiento
Síntomas: Jobs de backup arruinan cargas interactivas; tormentas de arranque de VM aplastan servicios de archivos; churn de caché.
Solución: Aísla cargas por host, pool o horario. Usa políticas de caché por dataset donde corresponda.
Considera límites de memoria con cgroups para servicios ruidosos en Linux.
Preguntas frecuentes
1) ¿Es malo que ZFS use la mayor parte de mi RAM?
No por sí mismo. Es malo si el sistema está intercambiando, reclamando agresivamente (PSI “full” alto) o las aplicaciones pierden memoria y se ralentizan.
Si la memoria “available” está saludable y el swap está tranquilo, que ARC use RAM suele ser una característica.
2) ¿Por qué ARC no libera memoria inmediatamente cuando una app la necesita?
ARC es reclamable, pero el reclaim tiene mecánica y tiempos. Ante picos súbitos, ARC puede quedarse atrás frente a la demanda,
y el kernel puede hacer swap antes de que ARC se haya encogido lo suficiente. Por eso presupuestas margen y evitas operar al borde del acantilado.
3) ¿Debería establecer zfs_arc_max en cada sistema?
Si el host ejecuta solo cargas ZFS (como un NAS dedicado), los valores por defecto suelen funcionar bien.
Si es un host de uso mixto (bases de datos, JVMs, contenedores), poner un tope puede evitar contenciones sorpresa.
La respuesta correcta es un presupuesto de memoria: lo que tus apps necesitan en pico, más margen de seguridad, más lo que puedas permitir para ARC.
4) ¿Cuál es una “buena” ratio de aciertos de ARC?
Depende de la carga. Para lecturas por streaming, una baja ratio puede todavía entregar alto throughput.
Para lecturas aleatorias y cargas pesadas en metadatos, una baja ratio suele significar dolor real.
Sigue tendencias de aciertos/fallos y correlaciónalas con latencia de disco y latencia visible por usuarios.
5) ¿ARC es lo mismo que L2ARC?
No. ARC está en RAM. L2ARC es un caché secundario en almacenamiento rápido (SSD/NVMe). L2ARC puede extender el caché,
pero necesita RAM para metadatos y no ayuda mucho en lecturas de una sola vez.
6) Si añado más RAM, ¿ZFS siempre será más rápido?
No siempre, pero a menudo sí. Más RAM ayuda cuando tu conjunto de trabajo es cacheable y los fallos son caros.
Si estás limitado por escrituras, CPU, red o diseño de la aplicación, más ARC no te salvará.
7) ¿Por qué mi sistema muestra poca “memoria libre” incluso en reposo?
Porque el SO usa la RAM para cachés para acelerar trabajo futuro. Sistemas inactivos con mucho caché son normales.
Céntrate en la memoria “available” y el swapping, no en “free”.
8) ¿Puedo configurar ZFS para cachear solo metadatos?
Sí, por dataset con primarycache=metadata. Es útil para datasets con lecturas en streaming grandes
que no se benefician de cachear bloques de datos, mientras se mantienen rápidas las búsquedas y los lookups.
Mide antes y después—esto puede salir mal en cargas que realmente reutilizan datos.
9) ¿Cómo sé si ARC está thrashing?
Busca fallos de ARC altos y sostenidos durante carga estable, comportamiento de expulsiones en aumento y picos de latencia de disco que correlacionen con los fallos.
Si el sistema además está haciendo swap, puedes entrar en un ciclo vicioso: la presión provoca churn en ARC, lo que incrementa I/O, lo que aumenta la latencia.
10) ¿Por qué bajó el rendimiento justo después de un backup grande o scrub?
Grandes lecturas secuenciales pueden expulsar bloques cacheados útiles (especialmente metadatos) si el caché no está dimensionado o sintonizado para cargas mixtas.
La solución usual es programar, aislar o prevenir la contaminación del caché—no encoger ARC permanentemente.
Conclusión
El ARC de ZFS no es una fuga de memoria con disfraz de sistema de archivos. Es una elección de diseño deliberada: usar RAM para evitar I/O de disco
y adaptarse a lo que hace la carga. El error operativo es tratar la “RAM libre” como métrica de salud y tratar el tamaño de ARC como una falla moral.
Cuando el rendimiento falla, no discutas filosofía—mide. Comprueba la presión de memoria, el swap, los fallos de ARC,
la latencia de disco y identifica la carga que cambió las reglas. Luego decide: limitar ARC para margen, tunear datasets
para evitar contaminación, aislar cargas o comprar más RAM. El mejor tuning de ZFS suele ser el más simple:
deja que ARC haga su trabajo, y asegúrate de que el resto del sistema no lo sabotee.