Tu almacenamiento está “bien” hasta la mañana del lunes. Picos de latencia, CPUs aburridas, discos ocupados y alguien dice las palabras
“pero tenemos montones de RAM”. Ahí es cuando ARC de ZFS se convierte en tu mejor amigo o en aquello que silenciosamente te está comiendo el almuerzo.
arcstat es la comprobación de realidad más rápida que conozco. Convierte la mitología de la caché en números con los que puedes discutir en una revisión de cambios,
y lo hace en segundos—sin reinicio, sin benchmarks y sin el habitual baile interpretativo alrededor de las “tasas de aciertos”.
Qué es arcstat (y qué no es)
arcstat es un pequeño script que toma muestras de las estadísticas del ARC de ZFS y las imprime como un panel en vivo. Lo ejecutas, lo observas,
y dejas de adivinar. No “ajusta” nada. No arregla nada. Solo te dice qué está haciendo la caché ahora mismo:
aciertos, fallos, tamaños y a veces la forma de tu carga de trabajo.
Si intentas responder “¿la caché ayuda?” hay una prueba brutalmente honesta:
si la tasa de aciertos del ARC es baja y tus discos están sobrecargados, la caché no te está salvando.
Si la tasa de aciertos del ARC es alta y los discos están tranquilos, ARC está haciendo trabajo útil.
La trampa: la gente trata las estadísticas del ARC como una métrica de vanidad. “¡Mira ese 99% de aciertos!” Genial—¿en qué exactamente? ¿Metadatos? ¿Archivos pequeños? ¿Prefetch inútil?
Tu trabajo es mapear los números al verdadero cuello de botella: latencia y rendimiento donde la aplicación realmente espera.
ARC en términos operativos sencillos
ARC (Adaptive Replacement Cache) es la caché en memoria de ZFS. No es “una caché de páginas” genérica. Compite con la caché de páginas del SO, con la memoria de tu aplicación
y con tu sensación de calma. Cachea bloques de datos y metadatos, y es agresivo porque el disco es lento y la RAM es rápida.
ARC es “adaptativo” porque intenta equilibrar dos clases de objetos cacheados:
los usados recientemente y los usados con frecuencia. En la práctica, esto significa que ARC intenta sobrevivir cargas que arruinarían caches LRU más simples:
lecturas con scans, cargas mixtas aleatorias y operaciones de sistema de archivos ricas en metadatos.
Pero ARC no puede romper la física. Si tu conjunto de trabajo no cabe en memoria, tu tasa de aciertos sufrirá. Si la carga es mayoritariamente lecturas en streaming,
el cache puede ser neutro o incluso perjudicial. Si tienes restricciones de memoria y ARC crece demasiado, cambiarás esperas de disco por tormentas de swap—
un intercambio que nadie debería aceptar.
Una cita para mantener cerca de tu ventana de cambios:
La esperanza no es una estrategia.
— Gene Kranz
Hechos interesantes e historia para usar en reuniones
- ARC no fue inventado para ZFS. El algoritmo ARC se publicó en 2003 y más tarde lo adoptó ZFS porque se adapta bien a cargas cambiantes.
- La caché de ZFS es basada en bloques, no en archivos. Cachea bloques desde la capa DMU, por eso las intuiciones de “caché de archivos” a menudo fallan.
- ARC cachea metadatos agresivamente. Para muchos entornos (hosts de VM, servidores de compilación, repositorios Git), los aciertos en metadatos marcan la diferencia entre “está bien” y “¿por qué ls va lento?”
- L2ARC no es una caché de escritura. Es una extensión de ARC a dispositivos rápidos, pero aún necesita ARC para indexarse, así que consume RAM para usar “más caché”.
- L2ARC solía ser volátil tras reinicios. Las implementaciones tempranas arrancaban frías; mejoras posteriores hicieron posible L2ARC persistente en algunas implementaciones.
- ZFS tiene una ruta separada de registro de intenciones (ZIL/SLOG). ARC ayuda las lecturas; la latencia de escrituras síncronas suele depender más del comportamiento del ZIL que del ARC.
- El prefetch puede ser un matón silencioso del ARC. Para cargas secuenciales, el prefetch de ZFS puede llenar ARC con datos que nunca vas a reutilizar, expulsando bloques valiosos.
- La compresión cambia la aritmética de la caché. ARC almacena bloques comprimidos (en muchas implementaciones), así que la compresión puede aumentar efectivamente la capacidad de caché para datos compresibles.
- La tasa de aciertos del ARC puede parecer “buena” mientras los usuarios sufren. Porque los fallos que importan pueden estar en la ruta crítica (p. ej., lecturas aleatorias pequeñas) mientras los aciertos son en operaciones baratas.
Broma #1: ARC es como las golosinas de la oficina—todos las aman hasta que se comen el presupuesto y alguien empieza a esconder barras de granola en su cajón.
Guion de diagnóstico rápido (primero/segundo/tercero)
Primero: confirma que el sistema realmente está esperando por almacenamiento
No empieces por ARC. Empieza por “¿cuál es el cuello de botella?”. Si la CPU está saturada, ARC no te salvará. Si estás haciendo swap, ARC es parte del problema.
Si los discos están inactivos pero la latencia es alta, podrías estar bloqueado en otro lugar (red, bloqueos, comportamiento single-threaded de la app).
Segundo: usa arcstat para clasificar la carga
Observa aciertos/fallos del ARC con el tiempo mientras ocurre el problema. Mira la demanda de lectura y la tasa de fallos, no solo la columna “hit%”.
Una ratio de aciertos sin contexto es una KPI diseñada para hacerte sentir mejor.
Tercero: decide qué perilla realmente importa
Basado en lo que encuentres:
- Si ARC es demasiado pequeño para el conjunto de trabajo, necesitas más RAM o cambiar la carga (recordsize, primarycache, patrón de acceso).
- Si ARC es grande pero está thrasheadando, probablemente tienes lecturas en streaming, demasiado prefetch o una carga que vence la caché; revisa el comportamiento de la aplicación y las propiedades del dataset.
- Si la tasa de aciertos del ARC está bien pero la latencia es mala, deja de mirar ARC y revisa escrituras síncronas, fragmentación, diseño de vdev y profundidad de cola.
Cómo leer arcstat como si estuvieras de guardia
arcstat muestra columnas que varían ligeramente según la implementación, pero los conceptos centrales se mantienen:
tamaño de caché, tamaño objetivo, aciertos, fallos, lecturas por demanda, lecturas por prefetch, y a menudo estadísticas separadas de metadatos.
El modelo mental que funciona en producción:
- Aciertos ahorran I/O. Los fallos generan I/O.
- Lecturas por demanda son las lecturas que la aplicación pidió. Lecturas por prefetch son ZFS adivinando el futuro.
- Fallos por demanda dañan la latencia. Fallos por prefetch mayormente dañan el ancho de banda y contaminan la caché.
- Tamaño del ARC debería ser estable bajo carga sostenida. Oscilaciones salvajes significan presión de memoria o una carga que revuelve la caché.
Deja de adorar la tasa de aciertos; comienza a correlacionar con el dolor
Una tasa de aciertos es una fracción. Las fracciones mienten por omisión. Puedes tener una gran tasa de aciertos mientras tu app está bloqueada por los pocos fallos
que tocan una tabla caliente o el patrón aleatorio de lecturas de una VM. También puedes tener una tasa de aciertos mediocre con una latencia perfectamente aceptable
si los fallos son secuenciales y tus discos pueden transmitirlos eficientemente.
Tamaño del ARC vs objetivo: quién está ganando la pelea por la RAM
ARC normalmente tiene un “objetivo” y un “tamaño” actual. Si ARC no puede alcanzar su objetivo, algo más está demandando memoria. Si ARC sigue encogiéndose,
el kernel está reclamando páginas—a veces correctamente, otras veces violentamente. El modo de fallo es predecible: presión de memoria provoca expulsión del ARC,
la expulsión del ARC aumenta I/O de disco, el I/O de disco aumenta la latencia, la latencia aumenta el encolamiento, y ahora estás diagnosticando la capa equivocada.
Demanda vs prefetch: test de personalidad de tu carga
Si los aciertos por demanda son altos, ARC está haciendo su trabajo. Si las lecturas por prefetch dominan y los aciertos de prefetch son bajos, probablemente estés cacheando basura.
Ahí es cuando miras primarycache, secondarycache, recordsize y si deberías desactivar el prefetch para cargas específicas.
No “apagas el prefetch” globalmente porque una máquina tuvo un mal día.
Broma #2: Encender L2ARC para arreglar una carga es como comprar una tostadora más rápida porque el servicio de cena va lento.
Tareas prácticas: comandos, significado de la salida y decisiones
Estas son tareas reales que he usado durante incidentes y trabajo de rendimiento. Cada una tiene tres partes: el comando, lo que significa la salida,
y la decisión que tomas a partir de ello. Ejecútalas mientras el problema ocurre. Los promedios históricos son bonitos; los síntomas en vivo pagan las cuentas.
Task 1: Run arcstat live and identify demand vs prefetch
cr0x@server:~$ arcstat 1
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:01 822 61 7 34 4 27 3 2 0 42.1G 48.0G
12:01:02 910 80 9 52 6 26 3 2 0 42.2G 48.0G
Significado: read es la actividad total de lectura del ARC; miss/miss% son fallos totales; dmis/dm% son fallos por demanda; pmis/pm% son fallos por prefetch; arcsz es el tamaño del ARC; c es el objetivo del ARC.
Decisión: Si los fallos por demanda son altos durante latencia visible al usuario, la caché no cubre el conjunto de trabajo. Si predominan los fallos por prefetch, podrías estar contaminando el ARC con read-ahead.
Task 2: Confirm ARC isn’t being forced to shrink (memory pressure)
cr0x@server:~$ arcstat -f time,arcsz,c,avail 1
time arcsz c avail
12:03:10 39.8G 48.0G 1.2G
12:03:11 38.9G 48.0G 900.0M
12:03:12 37.5G 48.0G 620.0M
Significado: ARC se está encogiendo mientras la memoria disponible colapsa. Eso es el kernel reclamando RAM.
Decisión: Si avail es bajo y ARC se encoge, prioriza memoria: reduce el máximo de ARC, arregla el proceso que consume memoria o añade RAM. No añadas L2ARC; también cuesta RAM.
Task 3: Check ARC summary counters (Linux)
cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep '^(hits|misses|demand_data_hits|demand_data_misses|prefetch_data_hits|prefetch_data_misses|size|c) '
hits 4 231889442
misses 4 18122344
demand_data_hits 4 168221991
demand_data_misses 4 12188511
prefetch_data_hits 4 23311233
prefetch_data_misses 4 4932100
size 4 45188173824
c 4 51539607552
Significado: Contadores crudos desde el arranque. Úsalos para calcular ratios y confirmar lo que muestra arcstat.
Decisión: Si demand_data_misses sube rápidamente durante incidentes, arregla el ajuste del conjunto de trabajo en memoria (RAM, recordsize, política de caché). Si solo suben los fallos de prefetch, atiende el comportamiento de prefetch.
Task 4: Compute demand hit ratio quickly (without lying to yourself)
cr0x@server:~$ python3 - <<'PY'
import re
d={}
for line in open("/proc/spl/kstat/zfs/arcstats"):
m=re.match(r'^(\w+)\s+\d+\s+(\d+)$', line.strip())
if m: d[m.group(1)]=int(m.group(2))
h=d.get("demand_data_hits",0); m=d.get("demand_data_misses",0)
print("demand_data_hit_ratio = {:.2f}%".format(100*h/(h+m) if (h+m) else 0))
PY
demand_data_hit_ratio = 93.25%
Significado: Ratio de aciertos por demanda solamente, excluyendo el ruido de prefetch.
Decisión: Si esto es alto y aún estás lento, tu cuello de botella probablemente no sea la caché de lectura (piensa en escrituras síncronas, CPU, bloqueos, red).
Task 5: Verify whether you’re swapping (ARC’s favorite way to ruin your day)
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 1 10488 51200 18000 7230000 12 45 620 130 8200 9100 10 5 70 15 0
1 1 10520 48900 17920 7215000 0 32 1110 140 7600 8800 9 4 68 19 0
Significado: si/so distintos de cero indican swap in/out; wa es I/O wait. Si estás haciendo swap, ARC compite con todo.
Decisión: Para, deja de tunear y arregla la presión de memoria. Reduce ARC, detén el proceso que consume memoria o escala. Swap con ZFS es una mala sitcom.
Task 6: Check ZFS pool I/O and latency (are disks the real culprit?)
cr0x@server:~$ zpool iostat -v 1 3
capacity operations bandwidth
pool alloc free read write read write
tank 9.12T 3.45T 640 210 82.1M 21.3M
raidz2 9.12T 3.45T 640 210 82.1M 21.3M
sda - - 110 36 13.8M 3.2M
sdb - - 108 35 13.7M 3.1M
sdc - - 107 34 13.6M 3.0M
sdd - - 109 35 13.7M 3.1M
Significado: Si los discos están al máximo en operaciones de lectura mientras los fallos por demanda del ARC son altos, estás limitado por I/O de lectura. Si los discos están tranquilos pero la app va lenta, ARC no es la historia principal.
Decisión: Si las operaciones de lectura saturan y los fallos del ARC son altos: añade RAM, añade vdevs, cambia la forma de la carga o reconsidera el nivel de almacenamiento. Si dominan las escrituras: mira escrituras síncronas y ZIL/SLOG.
Task 7: Check per-process I/O (catch the “one weird job”)
cr0x@server:~$ sudo iotop -oPa
Total DISK READ: 115.62 M/s | Total DISK WRITE: 22.10 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
18234 be/4 backup 98.12 M/s 1.40 M/s 0.00 % 92.00 % /usr/bin/rsync -a --delete /data /backup
9121 be/4 postgres 12.40 M/s 10.10 M/s 0.00 % 8.00 % postgres: checkpointer
Significado: Un trabajo secuencial o de backup puede arrasar el ARC con read-ahead y crear fallos que perjudican cargas interactivas.
Decisión: Si un job por lotes domina las lecturas, prográmalo, limita su tasa o aíslalo en un dataset con política de caché diferente.
Task 8: Inspect dataset caching policy (primarycache/secondarycache)
cr0x@server:~$ zfs get -o name,property,value primarycache,secondarycache tank/vmstore
NAME PROPERTY VALUE
tank/vmstore primarycache all
tank/vmstore secondarycache all
Significado: primarycache controla qué va al ARC; secondarycache controla qué va al L2ARC.
Decisión: Para imágenes de VM con comportamiento de streaming intenso, considera primarycache=metadata para proteger ARC para metadatos mientras las lecturas de invitados impactan el disco de forma predecible.
Task 9: Change primarycache for a dataset (surgical, reversible)
cr0x@server:~$ sudo zfs set primarycache=metadata tank/backup
cr0x@server:~$ zfs get -o name,property,value primarycache tank/backup
NAME PROPERTY VALUE
tank/backup primarycache metadata
Significado: Le estás diciendo a ZFS que cachee metadatos pero no datos de archivo para ese dataset.
Decisión: Usa esto cuando un dataset sea mayoritariamente lecturas/escrituras secuenciales y quieras evitar que expulse contenido útil del ARC. Si la latencia mejora para otras cargas, mantenlo. Si perjudica el rendimiento propio del dataset, revierte.
Task 10: Check recordsize (workload fit matters more than people admit)
cr0x@server:~$ zfs get -o name,property,value recordsize tank/postgres
NAME PROPERTY VALUE
tank/postgres recordsize 128K
Significado: Recordsize afecta la amplificación de I/O y la eficiencia de caché. Las bases de datos a menudo prefieren bloques más pequeños (p. ej., 16K) para evitar leer 128K para satisfacer una lectura de 8K.
Decisión: Si ves muchas lecturas aleatorias pequeñas y poca efectividad del ARC, considera ajustar recordsize para ese dataset (con cuidado; afecta escrituras nuevas, no las existentes).
Task 11: Observe prefetch behavior via ARC counters
cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep '^(prefetch_data_hits|prefetch_data_misses|demand_data_hits|demand_data_misses)'
demand_data_hits 4 168331120
demand_data_misses 4 12194410
prefetch_data_hits 4 23311610
prefetch_data_misses 4 4981044
Significado: Si los fallos de prefetch suben rápidamente mientras los fallos por demanda también suben, el prefetch puede estar expulsando datos útiles. Si los fallos de prefetch suben mientras los de demanda se mantienen, puede ser solo ancho de banda desperdiciado.
Decisión: Si el prefetch parece dañino, aísla el dataset culpable y considera cambiar la política de caché o la programación de la carga. No desactives el prefetch del sistema por reflejo.
Task 12: Check ARC sizing parameters (Linux OpenZFS)
cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_arc_max
68719476736
cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_arc_min
4294967296
Significado: ARC max/min en bytes. Si el máximo es demasiado alto respecto a la RAM del sistema y la carga, puedes provocar presión de memoria y swap.
Decisión: Si el host ejecuta apps que necesitan RAM (bases de datos, JVMs, hypervisores), limita ARC intencionalmente. Si el host es un appliance de almacenamiento, permite que ARC use la mayor parte de RAM pero dejando margen para kernel y ráfagas.
Task 13: Temporarily cap ARC max (careful, but effective)
cr0x@server:~$ echo $((32*1024*1024*1024)) | sudo tee /sys/module/zfs/parameters/zfs_arc_max
34359738368
cr0x@server:~$ sudo cat /sys/module/zfs/parameters/zfs_arc_max
34359738368
Significado: Has reducido el máximo del ARC a 32 GiB. ARC se adaptará gradualmente; no se encogerá instantáneamente al nuevo límite.
Decisión: Usa esto cuando la presión de memoria está causando swap o riesgo de OOM. Después de aplicarlo, monitoriza swapping y el comportamiento de fallos del ARC. Si los fallos se disparan y los discos se saturan, puede que hayas cambiado un problema por otro; reconsidera la arquitectura (más RAM, roles separados, añadir vdevs).
Task 14: Validate whether L2ARC is even being used
cr0x@server:~$ cat /proc/spl/kstat/zfs/arcstats | egrep '^(l2_hits|l2_misses|l2_size|l2_asize)'
l2_hits 4 892331
l2_misses 4 3211044
l2_size 4 17179869184
l2_asize 4 21474836480
Significado: Aciertos/fallos de L2ARC muestran si tu “SSD de caché” realmente está sirviendo lecturas. l2_size es datos almacenados; l2_asize es asignado.
Decisión: Si l2_hits apenas se mueve durante la carga, L2ARC no está ayudando. Razones comunes: el conjunto caliente ya cabe en ARC, el dataset no es elegible para secondarycache, o la carga es dominada por escrituras o streaming.
Task 15: Correlate ARC misses with real latency at the block device
cr0x@server:~$ iostat -x 1 3
avg-cpu: %user %nice %system %iowait %steal %idle
10.12 0.00 4.01 18.55 0.00 67.32
Device r/s w/s rkB/s wkB/s aqu-sz await svctm %util
sda 110.0 36.0 14120 3300 9.20 68.2 2.4 35.2
sdb 108.0 35.0 14080 3200 9.10 66.7 2.3 34.8
Significado: await es el tiempo medio que las peticiones pasan (cola + servicio). Alto await con altos fallos por demanda del ARC es la imagen clásica de “la caché no cubre y los discos están encolados”.
Decisión: Si await sube cuando suben los fallos por demanda, céntrate en el conjunto de trabajo de lectura, el diseño de vdev o en añadir IOPS. Si await está bien pero la latencia de la app es alta, investiga bloqueos, CPU, red o comportamiento de escrituras síncronas.
Task 16: Verify sync write behavior (because not everything is ARC)
cr0x@server:~$ zfs get -o name,property,value sync logbias tank/postgres
NAME PROPERTY VALUE
tank/postgres sync standard
tank/postgres logbias latency
Significado: Si tu problema es “las escrituras son lentas”, ARC no es tu héroe. sync y logbias influyen el manejo de escrituras síncronas y el comportamiento del ZIL.
Decisión: Para incidentes de latencia de escrituras, comprueba si la carga es intensiva en sync y si tienes un dispositivo SLOG apropiado. No lo tapes todo con mitos de caché.
Tres micro-historias corporativas (con dolor incluido)
Incidente causado por una suposición errónea: “Más ARC significa bases de datos más rápidas”
Una empresa mediana ejecutaba un clúster PostgreSQL sobre ZFS con una buena cantidad de RAM. El equipo de almacenamiento supuso “ARC debe usar tanta memoria como sea posible.”
Aumentaron zfs_arc_max y celebraron un número mayor de caché en los dashboards. Una semana después, durante el cierre de mes, la latencia explotó.
El equipo de bases de datos culpó a almacenamiento. Almacenamiento culpó a las consultas. Todos culparon a la “red” por costumbre. Los gráficos mostraban una tasa de aciertos del ARC aparentemente sana.
Esa fue la métrica equivocada a adorar.
Al observar arcstat durante el incidente, los fallos por demanda no eran catastróficos—pero había presión de memoria. La memoria disponible bajó,
el kernel reclamó agresivamente y empezó la actividad de swap. La base de datos tenía shared buffers dimensionados por una razón, pero ARC se había metido
y forzado al SO a tomar decisiones feas. La decisión de “hacer ARC más grande” no creó más aciertos; creó un comportamiento de memoria menos estable.
La solución fue aburrida: limitar ARC para dejar espacio a la base de datos y al kernel, luego ajustar la memoria de la base de datos con intención. Los fallos por demanda subieron ligeramente,
pero la latencia mejoró porque el sistema dejó de hacer swap. La gran lección: ARC no es “rendimiento gratis”. Es un inquilino en tu apartamento de RAM,
y aún necesitas pagar renta a los otros inquilinos.
Una optimización que salió mal: “Añadamos SSDs L2ARC por todos lados”
Otro equipo estandarizó “dos NVMe para L2ARC” en cada host de almacenamiento porque alguien leyó que “SSD cache hace ZFS rápido.”
Lo desplegaron como plantilla de hardware. Parecía moderno. Compras felices. A la gente le encanta comprar cosas brillantes.
Luego lo raro: algunos hosts se volvieron más lentos bajo carga mixta. No “un poco.” Notablemente. El clúster de procesamiento por lotes empezaba bien y luego degradaba.
Los dashboards mostraban uso de memoria en aumento y la CPU con sobrecarga extra en el kernel. La latencia de almacenamiento no siempre mejoró.
Sampleamos arcstat y comprobamos contadores de L2ARC. Los aciertos de L2ARC eran bajos. ARC ya servía la mayoría del conjunto caliente en RAM.
Mientras tanto, el sistema pagaba overhead para alimentar y gestionar L2ARC, y usaba RAM para los encabezados del L2ARC. Bajo presión, ARC se encogía,
y la caché restante se volvía menos efectiva. Añadir “más caché” redujo la calidad efectiva de la caché.
La solución fue de nuevo aburrida: quitar L2ARC de nodos donde no ayudaba y reservarlo para cargas específicas con un perfil de fallos probado.
También dejamos de tratar L2ARC como predeterminado y empezamos a justificarlo con medidas. El problema no fue que L2ARC sea “malo.”
Fue el culto al cargo de caché sin medir su coste.
Una práctica aburrida pero correcta que salvó el día: “Mide durante el incidente, no después”
Un gran servicio Git interno empezó a fallar durante una semana de lanzamientos. El síntoma era “lentitud aleatoria”: a veces los clones colgaban,
a veces la UI web se atascaba, a veces todo parecía bien. El on-call hizo algo raro y correcto: recogió evidencia en vivo
mientras los usuarios gritaban.
Ejecutaron arcstat, zpool iostat y iotop simultáneamente en una sesión tmux y capturaron cinco minutos de salida.
El patrón fue claro. Los fallos por demanda subían en sincronía con un job de mantenimiento que recorría grandes árboles de directorios.
Los discos se encolaban, los fallos de metadatos subían y la latencia seguía. Nada mágico—solo una colisión de cargas.
Porque tenían datos, no sensaciones, la mitigación fue limpia: mover la ventana del job, aislar la política de caché del dataset y mantener ARC
sesgado hacia metadatos para el dataset de repositorios. El incidente terminó sin cambios de hardware, sin culpas y sin un “proyecto de rendimiento” de dos semanas.
La práctica no era glamorosa. Simplemente fue: recopilar las estadísticas en vivo correctas temprano, luego decidir con evidencia. Así evitas
el postmortem con la línea “no pudimos reproducirlo.”
Errores comunes: síntoma → causa raíz → solución
1) “La tasa de aciertos del ARC es alta, pero las lecturas siguen siendo lentas”
Síntoma: Gran hit%, latencia de usuario aún mala.
Causa raíz: Los aciertos son mayoritariamente metadatos u operaciones baratas; los fallos en la ruta crítica son pocos pero dolorosos (lecturas aleatorias pequeñas, páginas calientes de BD). O el cuello de botella son escrituras/CPU/red.
Solución: Usa estadísticas solo de demanda y correlaciónalas con latencia de disco (iostat -x) y I/O del pool (zpool iostat). Si los discos no son el limitador, pivota: escrituras síncronas, saturación de CPU, contención a nivel de aplicación.
2) “ARC no para de encogerse y crecer; el rendimiento es inestable”
Síntoma: arcsz oscila, latencia hace jitter, a veces swap.
Causa raíz: Presión de memoria. ARC está siendo reclamado; el host hace demasiado (VMs + BD + ARC) sin límites.
Solución: Limita ARC (zfs_arc_max), reduce el uso de memoria competidor o separa roles entre hosts. Verifica que el swap esté casi a cero bajo carga normal.
3) “Los fallos por prefetch son enormes; ARC parece inútil”
Síntoma: pmis domina, la tasa de aciertos por demanda cae durante scans.
Causa raíz: Carga de streaming (backups, scrubs, scans) y prefetch tirando datos que no se reutilizarán; contaminación de la caché.
Solución: Aísla esa carga (programa/limita), pon primarycache=metadata en datasets con scans intensos y confirma mejora en los fallos por demanda de los datasets sensibles a latencia.
4) “Añadimos L2ARC y no cambió nada”
Síntoma: SSD de caché instalado, pero l2_hits apenas sube; latencia sin cambio.
Causa raíz: El conjunto de trabajo ya cabe en ARC; el dataset no es elegible para secondarycache; o la carga es dominada por escrituras y no por fallos de lectura.
Solución: Prueba primero la necesidad: fallos por demanda sostenidos y discos saturados en lectura. Luego asegúrate de secondarycache=all donde proceda y dimensiona RAM para la sobrecarga de metadatos de L2ARC.
5) “Después de reducir ARC, el sistema se volvió más lento”
Síntoma: Limitas ARC y la latencia de lectura aumenta.
Causa raíz: La carga realmente necesitaba caché de lectura; ARC ocultaba discos lentos. Tu límite quitó la tirita.
Solución: Decide intencionalmente: añade RAM, añade vdevs/IOPS o cambia la carga. Si el host debe ejecutar apps y almacenamiento juntos, planifica capacidad para que ambos respiren.
6) “Carga de lecturas aleatorias en RAIDZ se siente terrible”
Síntoma: Bajo acierto del ARC, alta demanda de IOPS de lectura, encolamiento, mala latencia.
Causa raíz: Los vdevs RAIDZ no son máquinas de IOPS; las lecturas aleatorias pequeñas los penalizan. ARC no puede arreglar una falta de coincidencia entre la carga y el layout de vdev.
Solución: Añade mirrors para IOPS, añade más vdevs o mueve la carga a un pool diseñado para I/O aleatorio. Usa ARC para ayudar, no para compensar la arquitectura.
7) “Afinamos recordsize y ahora la caché parece peor”
Síntoma: Tras cambiar recordsize, la tasa de aciertos cambia inesperadamente; rendimiento mixto.
Causa raíz: Recordsize afecta solo escrituras nuevas; los datos antiguos permanecen con el tamaño de bloque anterior. Ahora tienes un formato en disco mixto y estadísticas confusas.
Solución: Evalúa sobre datos escritos después del cambio, o reescribe datos (cuando sea apropiado). Evita cambios de recordsize sin un plan de migración y un objetivo claro de carga.
Listas de verificación / plan paso a paso
Lista A: “¿Está ARC ayudando ahora mismo?” (5 minutos)
- Inicia
arcstat 1y observa los fallos por demanda y la estabilidad del tamaño del ARC. - Ejecuta
zpool iostat -v 1para ver si los vdevs están saturados. - Ejecuta
iostat -x 1para comprobarawaity profundidad de cola. - Si los fallos por demanda son bajos y los discos están tranquilos: deja de culpar a la caché.
- Si los fallos por demanda son altos y los discos están encolados: la caché no cubre; planea cambios en RAM/vdev/carga.
Lista B: “¿Está ARC causando problemas?” (tríaje de presión de memoria)
- Revisa
vmstat 1por swapping (si/so). - Revisa
arcstat -f arcsz,c,avail 1por ARC encogiéndose y poca memoria disponible. - Si hay swap o
availpersistentemente bajo: limita ARC y/o reduce la presión de memoria de aplicaciones. - Tras los cambios, confirma que el swap siga silencioso y que los fallos por demanda no se hayan disparado.
Lista C: “¿Deberíamos añadir L2ARC?” (no compres hardware por sensaciones)
- Prueba fallos por demanda sostenidos durante ventanas reales de trabajo.
- Prueba que los discos están saturados en lectura (ops y latencia) cuando ocurren esos fallos.
- Confirma que la carga tiene relecturas (no es un stream de pasada única).
- Confirma que tienes margen de RAM para la sobrecarga e indexado de L2ARC.
- Despliega en un host, mide el crecimiento de
l2_hitsy el impacto en latencia, luego escala.
Lista D: “Realizar cambios a nivel de dataset de forma segura”
- Identifica el dataset que causa contaminación (con
iotop+ temporización + comportamiento de arcstat). - Ajusta
primarycacheorecordsizesolo en ese dataset, no globalmente. - Documenta la línea base: cinco minutos de arcstat, zpool iostat, iostat -x.
- Aplica el cambio, vuelve a medir durante la misma ventana de carga.
- Si empeora, revierte inmediatamente. Mantén el ego fuera.
Preguntas frecuentes
1) ¿Qué número único de arcstat debería vigilar?
Los fallos por demanda durante la ventana del problema. No la hit% global. Si los fallos por demanda suben y la latencia de disco sube con ellos, la caché no cubre.
2) ¿Es 90–95% de tasa de aciertos del ARC “bueno”?
Quizá. Depende de qué está teniendo aciertos. Una alta tasa con mala latencia a menudo significa que los fallos son en la ruta crítica, o que el problema no es caché de lectura.
3) ¿Por qué los fallos de prefetch son tan altos, y debo entrar en pánico?
Los fallos de prefetch pueden ser altos en cargas secuenciales. Entra en pánico solo si la actividad de prefetch se correlaciona con la expulsión de datos útiles del ARC y latencia visible por usuarios.
4) ¿ARC cachea escrituras?
ARC es principalmente una caché de lectura. Las escrituras pasan por grupos de transacciones y pueden estar en memoria, pero las quejas sobre latencia de escritura suelen deberse a escrituras síncronas y ZIL/SLOG, no a ARC.
5) Si añado RAM, ¿siempre mejorará el rendimiento?
Si estás limitado por faltas de lectura y tu conjunto de trabajo es cacheable, sí—frecuentemente de forma dramática. Si estás limitado por escrituras síncronas, CPU o red, la RAM no te salvará.
6) ¿Cuándo ayuda realmente L2ARC?
Cuando tienes una carga de solo lectura con un conjunto de trabajo mayor que la RAM pero con relecturas significativas, y tus discos son el cuello de botella. L2ARC no es un acelerador universal.
7) ¿Por qué mi sistema empeoró tras añadir L2ARC?
Porque L2ARC consume RAM para metadatos y añade trabajo de gestión. Si ARC ya era suficiente, pagaste overhead sin beneficio y posiblemente aumentaste la presión de memoria.
8) ¿Debería poner primarycache=metadata para imágenes de VM?
A menudo es una buena idea cuando las VMs hacen muchas lecturas en streaming que revuelven la caché. Pruébalo en una subconjunto primero; algunas cargas de VM sí se benefician de cachear datos.
9) ¿La compresión mejora la efectividad del ARC?
Con frecuencia sí, porque los bloques cacheados pueden almacenarse comprimidos, permitiendo meter más datos lógicos en la misma RAM. Pero la compresión también cuesta CPU—mide ambos lados.
10) ¿Por qué arcstat se ve diferente entre sistemas?
Diferentes distribuciones y scripts imprimen columnas y nombres distintos. Los conceptos subyacentes—aciertos, fallos, tamaño del ARC, demanda vs prefetch—son los que debes anclar.
Conclusión: próximos pasos que realmente ayudan
Si adoptas un hábito de esto: ejecuta arcstat durante el incidente, no después. Combínalo con zpool iostat y iostat -x.
En diez minutos normalmente puedes responder la única pregunta que importa: “¿Estamos bloqueados por lecturas de disco que la caché podría haber servido?”
Pasos prácticos:
- Captura una línea base de cinco minutos durante carga normal: arcstat + zpool iostat + iostat -x.
- Durante la próxima ralentización, captura el mismo trío y compara fallos por demanda y latencia de disco.
- Si existe presión de memoria, limita ARC intencionalmente y elimina swap primero.
- Si los fallos por demanda son el limitador, elige una: añadir RAM, rediseñar el layout de vdev para IOPS o cambiar la política de caché del dataset/carga.
- Si ARC parece sano, deja de tunear caché y busca el verdadero cuello de botella (escrituras síncronas, CPU, red, bloqueos).
La caché no es una estrategia de rendimiento. Es un multiplicador de rendimiento—úsala cuando la aritmética funcione, ignórala cuando no, y mide como si hablas en serio.