Algunos incidentes llegan con estruendo. Los problemas de latencia de lectura en ZFS normalmente no. Aparecen como «la aplicación se siente rara», paneles que parecen bien hasta que amplías la vista, y clientes que descubren que tienen más paciencia de la que pensaban.
Si ejecutas producción sobre ZFS y alguna vez te has quedado mirando zpool iostat preguntándote por qué el rendimiento por ancho de banda parece sano mientras la latencia se dispara, esta es tu guía de campo. Vamos a usar zpool iostat -r como adultos: medir lo correcto, aislar el cuello de botella rápido y hacer cambios que no provoquen un segundo incidente.
Qué te dice realmente -r (y qué no)
zpool iostat es la prueba más rápida de «¿está mi pool enfermo?» que tenemos y que no requiere un rastreo del kernel. Añade -r y obtienes la latencia por intervalo para operaciones de lectura (y, dependiendo de plataforma/versión, una vista estructurada de la latencia desglosada por etapas). Esta es la herramienta a la que recurrir cuando la pregunta es:
- ¿Se están encolando las solicitudes de lectura?
- ¿El pool es lento porque los discos son lentos o porque le pedimos a ZFS trabajo costoso?
- ¿Un vdev está arrastrando hacia abajo al pool?
Aquí la verdad incómoda: -r no revela mágicamente toda la ruta que sigue una lectura a través de ARC, compresión, checksums, reconstrucción RAID-Z, firmware del dispositivo, controlador, HBA y de vuelta. Te da señales fuertes. Aún tienes que pensar.
Qué significa «latencia de lectura» en términos ZFS
La latencia de lectura es el tiempo desde «se emitió una lectura» hasta «los datos fueron devueltos». Pero el pool la ve de una forma muy concreta: ZFS mide e informa los tiempos a nivel de pool/vdev. Eso incluye encolamiento y tiempo de servicio en la pila de almacenamiento. Puede no incluir el tiempo que tu aplicación pasó esperando CPU, bloqueos o demoras de planificación antes de emitir el I/O.
Por qué -r es diferente de las herramientas de «latencia de disco»
Herramientas como iostat -x y sar -d se centran en dispositivos de bloque. Son estupendas, pero no entienden la topología de vdev. ZFS sí. Un mirror se comporta distinto a un RAID-Z, y un vdev especial cambia la ruta de lectura. zpool iostat -r es lo más cercano a una vista «nativa ZFS» de la latencia de lectura que puedes obtener sin usar DTrace/eBPF a fondo.
Un modelo práctico de latencia para pools ZFS
Si quieres leer zpool iostat -r como un profesional, necesitas un modelo mental lo bastante simple para usar bajo estrés, pero lo bastante preciso para evitar decisiones malas.
La latencia suele ser una de cuatro cosas
- Penalidad por fallo de caché (si ARC/L2ARC no la tiene, tocas disco).
- Encolamiento (el pool/vdev está saturado; las solicitudes esperan su turno).
- Tiempo de servicio (el dispositivo es lento por I/O: medio, firmware, controlador, problemas SMR, contención por rebuild/scrub).
- Trabajo de amplificación (paridad RAID-Z, descompresión, checksum, gang blocks, lecturas aleatorias pequeñas a través de vdevs anchos).
Tu trabajo es averiguar cuál domina ahora mismo. No cuál es filosóficamente importante. No cuál queda bonito en una diapositiva.
La latencia de lectura está moldeada por la carga
El comportamiento de lectura de ZFS difiere mucho según el patrón de acceso:
- Lecturas aleatorias de 4–16K: limitadas por IOPS. Los mirrors brillan. Los vdevs RAID-Z anchos pueden sufrir.
- Lecturas secuenciales grandes: limitadas por ancho de banda. RAID-Z puede verse bien hasta que no (la fragmentación y el recordsize importan).
- Cargas con mucha metadata: muchas lecturas pequeñas; los vdevs especiales y la elección de recordsize importan mucho.
- Lectura/escritura mixta: las lecturas pueden verse arrastradas por escrituras vía contención, especialmente en periodos sync-intensos y trabajo en segundo plano.
Conoce tu latencia «buena»
No existe una «latencia de lectura buena» universal. Pero hay rangos saludables:
- Mirrors NVMe: cifras de ms de un solo dígito bajo carga suelen ser aceptables; sub-ms es común con carga ligera.
- SSD SAS/SATA: unos pocos ms es normal; decenas de ms sugieren encolamiento o recolección de basura.
- HDD 7200 RPM: 8–15 ms de tiempo de servicio es normal; 30–100+ ms probablemente indica encolamiento o contención por rebuild/scrub.
La clave es la correlación: latencia con IOPS y ancho de banda. Latencia alta con IOPS bajos es «el dispositivo o la ruta es lenta». Latencia alta sólo a IOPS altos es «estás saturando algo».
Una cita que deberías pegar en tu monitor:
«La esperanza no es una estrategia.» — Gene Kranz
Datos interesantes y contexto histórico (breve y útil)
- ZFS se diseñó con integridad de datos de extremo a extremo incorporada (checksums por todas partes). Ese trabajo de integridad puede aparecer como coste de CPU bajo tasas extremas de lectura.
- ARC (Adaptive Replacement Cache) reemplazó el simple LRU con algo más resistente a scans; excelente para cargas reales, a veces sorprendente durante lecturas secuenciales grandes.
- RAID-Z existe en gran parte porque «el RAID de hardware mentía» sobre el orden de escrituras y manejo de errores; ZFS quería semánticas previsibles y corrección verificable con scrubs.
- Los scrubs no son mantenimiento opcional; son cómo ZFS valida la redundancia. Pero los scrubs compiten absolutamente por I/O de lectura y pueden inflar la latencia de lectura.
- ashift es para siempre en un vdev: elegir mal (p. ej., 512-byte en discos 4K) puede crear amplificación que perseguirá la latencia.
- L2ARC tuvo históricamente la reputación de «cache que devora RAM» porque su metadata puede presionar ARC; las implementaciones más nuevas mejoraron el comportamiento, pero el tradeoff sigue siendo real.
- Los vdevs especiales (metadata/pequeños bloques) son una adición relativamente moderna en OpenZFS y pueden cambiar dramáticamente la latencia de lectura para cargas con mucha metadata—también un nuevo lugar para equivocarse.
- La expansión de RAID-Z es una capacidad más reciente; antes de eso, cambiar el ancho de vdev a menudo significaba reconstruir pools, lo que influyó en por qué la gente diseñaba con mirrors por defecto.
- El prefetch de ZFS ha evolucionado; puede ayudar lecturas secuenciales pero puede perjudicar cuando predice mal, generando I/O inútil y latencia para las lecturas reales.
Recorrido por la salida: columnas, unidades y trampas
zpool iostat tiene múltiples modos de salida y las columnas exactas varían según la versión de OpenZFS y el empaquetado del SO. El principio sigue consistente: estás mirando estadísticas por pool y por vdev, por intervalo, y con -r obtienes datos de latencia de lectura.
Dos trampas aparecen constantemente:
- Mirar sólo la latencia a nivel de pool. Un pool es la suma de sus vdevs, y un vdev malo puede envenenar la experiencia.
- Confundir «latencia media» con «latencia cola».
zpool iostates por intervalo y generalmente algo promedio. Tus clientes viven en la cola.
Además: la latencia que informa ZFS no siempre es la misma que experimenta la aplicación. Si la app está bloqueada por CPU o contención de locks, ZFS puede parecer inocente mientras los usuarios sufren.
Broma #1: La latencia es como la basura: puedes ignorarla un tiempo, hasta que empieza a tomar decisiones sobre tu vida.
Manual de diagnóstico rápido (primero/segundo/tercero)
Primero: confirma que es real y encuentra el alcance
- Ejecuta
zpool iostat -rcon un intervalo corto para atrapar picos e identificar qué pool/vdev está implicado. - Comprueba si hay trabajo en segundo plano (scrub, resilver). Si lo hay, decide si pausarlo/reducirlo.
- Revisa el comportamiento del ARC: si estás sufriendo fallos de caché, los discos estarán ocupados y la latencia subirá. Confirma con estadísticas ARC.
Segundo: decide si es saturación, un actor único o una mala configuración
- Saturación: la latencia sube con IOPS/ancho de banda y baja cuando la carga disminuye. Probablemente encolamiento o límites del dispositivo.
- Actor único: un vdev muestra latencia de lectura mucho más alta que sus pares. Sospecha disco, camino, cableado, firmware o un mirror degradado.
- Mala configuración: amplificación de lectura alta (recordsize pequeño en RAID-Z en HDD, ashift equivocado, vdev especial casi lleno, volblocksize raro) crea latencia persistente bajo carga normal.
Tercero: valida con una herramienta de comprobación cruzada, no con cinco
Escoge la herramienta extra mínima necesaria:
iostat -xpara validar encolamiento/tiempo de servicio a nivel de dispositivo.zpool statuspara confirmar errores, vdevs degradados, operaciones en curso.arcstato equivalente para confirmar tendencias de tasa de aciertos de caché.
Si necesitas saltar a trazado, hazlo deliberadamente. Los incidentes de latencia aman a la gente que se desespera recogiendo «todos los datos».
Tareas prácticas: comandos, qué significa la salida y la decisión que tomas
Estas son tareas de calidad producción. Cada una incluye: un comando ejecutable, un fragmento representativo de salida, qué significa y qué haces después. Ajusta nombres de pool y rutas de dispositivo a tu sistema.
Task 1: Obtener la latencia de lectura base por vdev
cr0x@server:~$ zpool iostat -v -r 1 10
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 3200 410 210M 18.2M 7ms
mirror-0 1.07T 2.56T 1580 210 104M 9.1M 6ms
sda - - 790 105 52.1M 4.6M 6ms
sdb - - 790 105 52.0M 4.6M 6ms
mirror-1 1.08T 2.56T 1620 200 106M 9.1M 7ms
sdc - - 810 100 53.0M 4.5M 7ms
sdd - - 810 100 53.0M 4.5M 7ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Significado: Las lecturas del pool se distribuyen bastante equitativamente entre mirrors. La latencia es consistente entre vdevs y discos. Esto parece carga normal, no un disco fallando.
Decisión: Si la latencia es «demasiado alta», probablemente sea saturación o desajuste de carga—no un solo disco. Continúa con comprobaciones de carga y caché.
Task 2: Capturar latencia puntual extendiendo la ventana de muestreo
cr0x@server:~$ zpool iostat -v -r 5
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 900 60 58.0M 2.1M 3ms
tank 2.15T 5.12T 4100 120 260M 6.0M 22ms
tank 2.15T 5.12T 800 55 52.0M 1.8M 4ms
^C
Significado: El segundo intervalo muestra un pico: IOPS y ancho de banda saltan y la latencia sube. Eso es encolamiento clásico bajo carga puntual.
Decisión: Identifica la fuente del pico (job de backup, consulta analítica, scrub/resilver). Considera limitar la carga o aumentar la paralelidad de vdevs (más mirrors) si es sostenido.
Task 3: Confirmar salud del pool y operaciones en segundo plano
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
scan: resilver in progress since Tue Dec 24 10:12:11 2025
1.24T scanned at 820M/s, 410G issued at 270M/s, 1.24T total
0B resilvered, 32.9% done, 1:05:12 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
Significado: El resilvering es una operación intensiva en lectura y puede elevar la latencia para clientes, especialmente en HDD.
Decisión: Si esto es un incidente de latencia, programa resilvers/scrubs para ventanas de baja carga o ajusta la velocidad de escaneo (ver Task 10).
Task 4: Comprobar latencia y encolamiento a nivel de dispositivo
cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
12.10 0.00 4.60 1.80 0.00 81.50
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
sda 380.0 52000.0 0.0 0.0 6.10 136.8 55.0 4600.0 3.20 2.10 78.0
sdb 379.0 51900.0 0.0 0.0 6.00 136.9 55.0 4600.0 3.10 2.05 77.5
sdc 402.0 53000.0 0.0 0.0 7.20 131.8 50.0 4500.0 3.00 2.40 82.0
sdd 401.0 52900.0 0.0 0.0 7.10 131.9 50.0 4500.0 3.10 2.35 81.5
Significado: El await de lectura a nivel de dispositivo coincide aproximadamente con la latencia de lectura que vimos antes en ZFS. La utilización es relativamente alta y el tamaño de cola no es trivial: estás trabajando los discos.
Decisión: Si necesitas menor latencia, reduce la carga, añade vdevs o mueve los datos calientes a medios más rápidos. No intentes «tunear» para evitar las leyes de la física.
Task 5: Identificar si ARC te está ayudando o traicionando
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
10:44:01 8200 980 12 40 0 920 11 20 0 96.2G 128G
10:44:02 7900 1100 13 38 0 1040 13 22 0 96.2G 128G
10:44:03 8100 4200 51 45 0 4130 51 25 0 96.2G 128G
10:44:04 8300 3900 46 42 0 3830 46 28 0 96.2G 128G
10:44:05 8000 1000 12 40 0 940 12 20 0 96.2G 128G
Significado: Dos segundos muestran un pico de miss repentino. Eso suele ser un scan, una consulta que provoca thrash de caché, o un nuevo working set que no cabe. Los picos de misses correlacionan fuertemente con picos de latencia de lectura.
Decisión: Si es un scan programado (backup, AV, analítica), aislarlo o limitar su tasa. Si es tráfico normal, puede que necesites más RAM, mejor layout de datasets o discos más rápidos.
Task 6: Revisar propiedades del dataset que moldean la latencia de lectura
cr0x@server:~$ zfs get -o name,property,value,source recordsize,compression,atime,primarycache,secondarycache tank/app
NAME PROPERTY VALUE SOURCE
tank/app recordsize 128K local
tank/app compression lz4 inherited from tank
tank/app atime off local
tank/app primarycache all default
tank/app secondarycache all default
Significado: recordsize afecta cuánto dato lee ZFS por lectura lógica. Para lecturas aleatorias tipo base de datos, 128K puede crear amplificación de lectura innecesaria. La compresión puede ayudar reduciendo I/O físico, pero cuesta CPU.
Decisión: Para lecturas aleatorias OLTP, considera recordsize más pequeño (p. ej., 16K) a nivel de dataset. No cambies todo el pool a la vez.
Task 7: Validar topología del pool y desequilibrio de vdevs
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
Significado: Un único vdev RAID-Z2 ancho concentra límites de IOPS. La latencia de lectura aleatoria subirá antes respecto a múltiples mirrors o vdevs más estrechos.
Decisión: Si tu carga es sensible a latencia y con muchas lecturas aleatorias, prefiere mirrors o múltiples vdevs. RAID-Z está bien para capacidad y streaming, no es magia para IOPS.
Task 8: Detectar un disco lento dentro de un mirror
cr0x@server:~$ zpool iostat -v -r 1 5
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 2400 200 160M 8.0M 18ms
mirror-0 1.07T 2.56T 1200 100 80.0M 4.0M 35ms
sda - - 600 50 40.0M 2.0M 34ms
sdb - - 600 50 40.0M 2.0M 36ms
mirror-1 1.08T 2.56T 1200 100 80.0M 4.0M 2ms
sdc - - 600 50 40.0M 2.0M 2ms
sdd - - 600 50 40.0M 2.0M 2ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Significado: Mirror-0 es dramáticamente peor que mirror-1. Incluso si ambos discos en mirror-0 muestran latencia similar, puede ser una ruta compartida (lane del expander SAS, puerto HBA) o problema de medio.
Decisión: Investiga la ruta de hardware: intercambia cables/puertos, revisa SMART, comprueba logs del HBA. Si confirmas que un disco es lento, sustitúyelo antes de que se convierta en «degradado + lento», la peor combinación.
Task 9: Revisar errores de checksum que fuerzan lecturas costosas
cr0x@server:~$ zpool status -v
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error.
action: Replace the device or restore the pool from backup.
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 12
sdb ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/app@autosnap:2025-12-25:00:00:00:/var/lib/app/index.dat
Significado: Los errores de checksum pueden desencadenar reintentos, reconstrucción y lecturas lentas. Aunque el pool permanezca ONLINE, la latencia puede dispararse cuando ZFS tiene que trabajar más para devolver datos correctos.
Decisión: Trata los errores de checksum como urgentes. Reemplaza medios/rutas sospechosas, ejecuta scrub después del reemplazo y valida el riesgo de corrupción a nivel de aplicación.
Task 10: Controlar el impacto de scrub/resilver en la latencia de lectura
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_vdev_scrub_min_active
1
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_active
2
Significado: Estos parámetros influyen en cuán agresivamente ZFS emite I/O de scrub. Valores más altos pueden finalizar scrubs más rápido pero pueden aumentar la latencia de lectura durante horas laborables.
Decisión: En sistemas sensibles a latencia, mantén la agresividad de scrub conservadora durante picos y programa scrubs fuera de horario. Si tu plataforma expone zpool scrub -s, pausar scrubs durante incidentes es una medida pragmática.
Task 11: Validar salud y espacio del vdev especial (ruta caliente de metadata)
cr0x@server:~$ zpool list -v tank
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 7.27T 2.15T 5.12T - - 18% 29% 1.00x ONLINE -
special 894G 770G 124G - - 35% 86% - ONLINE -
mirror-2 894G 770G 124G - - 35% 86% - ONLINE -
nvme0n1 - - - - - - - - ONLINE -
nvme1n1 - - - - - - - - ONLINE -
Significado: El vdev especial está al 86% de capacidad. Ahí es donde nacen los incidentes de latencia. Cuando el especial se llena, el comportamiento de ZFS cambia y la colocación de metadata puede volverse problemática.
Decisión: Mantén el vdev especial muy por debajo de una utilización «peligrosa». Si se está llenando, añade capacidad especial o ajusta qué bloques son elegibles (con cuidado). Trata el vdev especial como una dependencia de nivel 0 en producción.
Task 12: Detectar lecturas patológicas de bloques pequeños usando la vista por tamaño de zpool iostat
cr0x@server:~$ zpool iostat -v -r -w 1 3
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 9000 200 72.0M 6.0M 14ms
mirror-0 1.07T 2.56T 4600 100 36.0M 3.0M 15ms
mirror-1 1.08T 2.56T 4400 100 36.0M 3.0M 13ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Significado: IOPS de lectura altos con ancho de banda moderado implican tamaños de I/O pequeños. Eso es un juego de IOPS, no de throughput.
Decisión: Si esto es RAID-Z sobre HDD, espera dolor. Para mirrors SSD/NVMe, revisa CPU y ruta de metadata. Considera vdevs especiales para metadata/pequeños bloques si procede.
Task 13: Verificar ashift para evitar amplificación read-modify
cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_path' -n
45: ashift: 12
62: path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_2TB_S5...'
88: ashift: 9
105: path: '/dev/disk/by-id/ata-WDC_WD40EFRX-68...'
Significado: Pueden aparecer valores ashift mixtos entre vdevs, especialmente si el pool creció en el tiempo. ashift: 9 (512B) en discos 4K-native o 4K-emulados puede crear trabajo extra y latencia.
Decisión: Si encuentras ashift incorrecto en un vdev, planifica remediación: reemplazar vdev mediante migración, reconstruir pool o aceptar el coste. No hay un botón seguro «flip ashift» in-place.
Task 14: Comprobar si tu «optimización» es en realidad thrash por prefetch
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_prefetch_disable
0
Significado: El prefetch está habilitado. Para cargas secuenciales puede ayudar. Para algunos patrones mixtos/aleatorios, puede aumentar lecturas inútiles y empeorar la latencia.
Decisión: No deshabilites prefetch a ciegas. Pruébalo en la carga específica y observa zpool iostat -r junto con patrones de misses ARC. Si deshabilitarlo reduce la latencia de lectura sin dañar el throughput, mantenlo así para ese host.
Tres mini-historias corporativas desde las trincheras de la latencia
1) El incidente causado por una asunción equivocada
El equipo tenía una plataforma de VMs basada en ZFS. Mirrors en SSD, mucha RAM, un HBA decente. Un lunes, los usuarios se quejaron de que las consolas de VM iban lentas y los despliegues se quedaban sin tiempo. Los gráficos mostraban CPU bien, red bien y «throughput de disco» no exagerado. El on-call miró zpool iostat y vio el ancho de banda de lectura cómodamente por debajo de lo que los SSD podían manejar. Asumieron que el almacenamiento no era el problema.
Lo era. zpool iostat -v -r mostró picos de latencia de lectura a decenas de milisegundos en ráfagas cortas. Nada sostenido, justo lo suficiente para hacer que operaciones síncronas (como lecturas de metadata durante tormentas de arranque) fallaran. El pool tenía un vdev especial para metadata en un par de NVMe pequeños. Uno de ellos estaba discretamente arrojando errores de medio que aún no degradaban el mirror por completo, pero sí provocaban reintentos y rutas lentas.
La asunción equivocada fue «si el throughput está bien, el almacenamiento está bien». En realidad, el throughput es una métrica en bloque; la plataforma moría por miles de pequeñas lecturas. Cada reintento extendía la ruta crítica para operaciones dependientes de metadata.
Reemplazaron el NVMe, hicieron scrub y el problema desapareció. El postmortem incluyó una regla simple: cuando los usuarios informan «lag», mira la latencia primero. El throughput es de lo que presumes después del incidente.
2) La optimización que salió mal
Un equipo de base de datos quería lecturas más rápidas. Habilitaron L2ARC en un SSD grande y celebraron cuando la tasa de aciertos de ARC mejoró durante un benchmark sintético. Luego la producción… se volvió más lenta. No catastróficamente, pero lo suficiente para que las latencias de cola pasaran de «molestas» a «generadoras de tickets».
zpool iostat -r mostró picos de latencia de lectura coincidiendo con softirqs de CPU y presión de memoria. El tamaño del ARC parecía estable, pero el host pasaba mucho tiempo gestionando metadata de caché. El dispositivo L2ARC era rápido; el host no estaba libre. En su caso, la carga tenía un componente secuencial grande además de un conjunto aleatorio caliente. L2ARC ayudó a veces, pero también incentivó más churn y sobrecarga.
El fallo no fue que L2ARC sea malo. Fue que lo trataron como una mejora gratuita. L2ARC cuesta RAM y CPU, y bajo algunos patrones de acceso puede incrementar el trabajo por lectura lo suficiente como para anular la reducción de I/O de disco.
Lo revirtieron, luego reintrodujeron L2ARC con tamaño reducido y más RAM en el host. La verdadera ganancia vino después: mover algunos datasets pesados en metadata a un vdev especial mirror NVMe, lo que redujo la latencia de lecturas pequeñas directamente sin el drama del churn de caché.
3) La práctica aburrida pero correcta que salvó el día
Un clúster de almacenamiento ejecutaba scrubs nocturnos y tenía una política impopular: las ventanas de scrub eran fijas, y cualquier equipo que quisiera ejecutar lecturas batch pesadas debía coordinarse. La gente se quejaba. Parecía burocrático.
Una semana, una regresión de firmware afectó a un lote de discos. Nada falló abiertamente. En lugar de eso, una unidad en un mirror empezó a tardar más en responder bajo lecturas sostenidas. La latencia subió lentamente. Lo interesante: el monitoreo del sistema tenía un «perfil semanal de latencia de scrub» porque los scrubs eran consistentes. Cuando la unidad empezó a comportarse mal, la ventana de scrub mostró una desviación clara: la latencia de lectura en un vdev subía mientras las demás se mantenían planas.
Reemplazaron el disco proactivamente. Sin outage, sin vdev degradado en hora punta, sin «incidente de rendimiento misterioso». La práctica aburrida—scrubs regulares en horario fijo y comparar iguales con iguales—se convirtió en un sistema de alerta temprana.
Cuando preguntaron por qué no «scrubear cuando haga falta», la respuesta fue simple: la consistencia crea baselines, y las baselines detectan fallos lentos. La aleatoriedad crea folklore.
Broma #2: Lo único más predecible que fallos de disco es la reunión donde alguien dice, «Pero funcionó en staging».
Errores comunes: síntoma → causa raíz → solución
1) Síntoma: picos de latencia de lectura del pool durante horas laborables, especialmente en ráfagas cortas
Causa raíz: escaneos en segundo plano (scrub/resilver) o jobs batch con ráfagas que crean encolamiento.
Solución: programa scrubs pesados fuera de horario, reduce la agresividad de scrub y limita la tasa de lectores batch. Confirma con zpool status y compara zpool iostat -r con y sin el job.
2) Síntoma: un vdev muestra latencia de lectura mucho más alta que los demás
Causa raíz: disco lento único, lane SAS malo, puerto HBA con problema o errores de medio intermitentes que provocan reintentos.
Solución: verifica con iostat -x, SMART y logs del HBA. Cambia puertos/cables si es posible; reemplaza el disco sospechoso pronto.
3) Síntoma: latencia de lectura alta pero IOPS y ancho de banda bajos
Causa raíz: el dispositivo es lento por I/O (GC de firmware, comportamiento SMR, recuperación de errores) o congestión a nivel kernel.
Solución: valida con iostat -x (r_await alto, %util baja-moderada), revisa logs de disco, considera reemplazar la clase de dispositivo. Para pools HDD, asegúrate de que no se colaron discos SMR.
4) Síntoma: la latencia de lectura sube con cargas de pequeños I/O en RAID-Z
Causa raíz: limitación de IOPS y amplificación de lectura en vdevs RAID-Z anchos; las búsquedas de metadata dominan.
Solución: rediseña con mirrors o añade vdevs para aumentar paralelismo. Para pools existentes, considera mover datasets sensibles a latencia a un pool mirror SSD/NVMe.
5) Síntoma: tras habilitar un vdev especial, la latencia mejora y luego empeora meses después
Causa raíz: el vdev especial se llena o fragmenta; metadata/pequeños bloques se ven forzados de nuevo al vdev principal o se colocan ineficientemente.
Solución: mantén el vdev especial muy por debajo de la utilización peligrosa, añade capacidad pronto y monitoriza la asignación del especial por separado. Trátalo como crítico en producción.
6) Síntoma: picos de latencia después de cambiar recordsize o volblocksize
Causa raíz: desajuste entre patrón de I/O y tamaño de bloque causando amplificación, más datos antiguos no reescritos (las propiedades se aplican sobre todo a nuevas escrituras).
Solución: prueba cambios en un dataset canario, reescribe datos si hace falta (migración/replicación) y valida con zpool iostat -r bajo carga representativa.
7) Síntoma: picos de latencia que parecen de almacenamiento, pero la latencia ZFS es normal
Causa raíz: contención de CPU de la aplicación o del host VM, contención de locks o demoras del planificador. El almacenamiento es el chivo expiatorio porque es medible.
Solución: correlaciona con cola de ejecución de CPU, vmstat y perfiles de la app. No «tunées ZFS» cuando ZFS no es el problema.
Listas de verificación / plan paso a paso
Paso a paso: cuando te pageran por «lecturas lentas»
- Confirma el síntoma: ¿es latencia visible para usuarios, timeouts de app o ralentización batch? Obtén un ejemplo concreto y una marca temporal.
- Ejecuta
zpool iostat -v -r 1 10en el host afectado. Identifica el peor pool/vdev. - Revisa
zpool statuspor scrub/resilver, errores, vdevs degradados. - Comprueba con
iostat -x 1 3si los dispositivos están saturados o lentos por I/O. - Revisa la tasa de aciertos ARC (Task 5). Si los misses se disparan, identifica la carga que lo causa.
- Haz la intervención mínima segura:
- pausar o reprogramar scrub/resilver si es posible y apropiado,
- restringir el lector batch,
- fallar un disco claramente enfermo si tienes evidencia fuerte y redundancia,
- mover el dataset caliente a un pool más rápido si ya lo tienes.
- Valida la mejora con los mismos comandos e intervalo. No declares victoria basándote en sensaciones.
- Escribe lo que viste: «mirror-0 latencia de lectura 35ms mientras mirror-1 2ms» es oro para seguimiento.
Lista: decisiones de diseño que previenen incidentes de latencia de lectura
- Elige la topología de vdev según necesidades de IOPS (mirrors para lecturas aleatorias; RAID-Z para capacidad/streaming).
- Configura
ashiftcorrectamente al crear. - Usa tuning a nivel de dataset (
recordsize,atime, compresión) en lugar de soluciones globales. - Mantén los vdevs especiales sanos, en mirror y no casi llenos.
- Programa scrubs y mantenlos consistentes para construir baselines.
- Monitorea la latencia, no sólo throughput y espacio.
Lista: qué no hacer durante un incidente de latencia
- No cambies cinco tunables a la vez. No sabrás qué ayudó.
- No «arregles» la latencia deshabilitando checksums o funciones de integridad. Eso no es ingeniería; es negación.
- No asumas que un pool SSD rápido no puede ser el problema. NVMe también puede encolarse.
- No ignores un vdev fuera de rango. Los pools son tan rápidos como su camino crítico más lento.
Preguntas frecuentes
1) ¿Qué mide exactamente zpool iostat -r?
Informa la latencia de lectura observada en la capa pool/vdev de ZFS durante cada intervalo de muestreo. Piensa «tiempo para satisfacer lecturas vistas por ZFS», incluyendo encolamiento y tiempo de servicio del dispositivo.
2) ¿Por qué mi app está lenta cuando zpool iostat -r parece bien?
Porque el almacenamiento no siempre es el cuello de botella. Demoras de planificación de CPU, contención de locks, red o serialización de la aplicación pueden crear latencia mientras ZFS se mantiene sano. Correlaciona con métricas del sistema y de la app.
3) ¿Por qué la latencia sube durante scrubs si los scrubs son «solo lecturas»?
Los scrubs compiten por el mismo ancho de banda e IOPS que los clientes, y pueden aumentar el movimiento de cabezas en HDD. Incluso en SSD, pueden añadir encolamiento y reducir la efectividad de la caché.
4) ¿Puede L2ARC reducir la latencia de lectura?
Sí—cuando la carga tiene un working set estable que cabe y el host tiene RAM/CPU para gestionarlo. También puede salir mal aumentando overhead y churn de caché. Mide antes y después.
5) ¿RAID-Z es siempre peor para latencia de lectura que mirrors?
Para lecturas aleatorias pequeñas, normalmente sí: los mirrors escalan IOPS con el número de vdevs y tienen reconstrucción más simple. Para lecturas secuenciales grandes, RAID-Z puede ser excelente. Ajusta la topología a la carga.
6) Mi latencia de lectura del pool es alta pero los discos muestran %util bajo. ¿Cómo?
Posibles causas: el cuello de botella está por encima de los discos (CPU, checksum/descompresión, contención), la ventana de medición oculta ráfagas, o el dispositivo es lento por operación sin estar «ocupado» en el sentido clásico. Usa intervalos más cortos y comprueba con otras herramientas.
7) ¿Cuál es la forma más rápida de identificar comportamiento de «un disco malo»?
Compara la latencia por vdev en zpool iostat -v -r y luego revisa await por dispositivo con iostat -x. Si una ruta es consistentemente peor, investiga esa ruta primero.
8) ¿Cambiar recordsize arregla la latencia de lectura de datos existentes?
No directamente. recordsize afecta cómo se dispone la nueva data. Los bloques existentes conservan su estructura hasta que se reescriben (por reescritura/migración/replicación).
9) ¿Debería deshabilitar prefetch para reducir latencia de lectura?
A veces. Prefetch ayuda cargas secuenciales y puede perjudicar patrones mal predichos. No lo apliques por moda; pruébalo en la carga real y mira latencia más misses ARC.
10) ¿Qué número de latencia debería disparar una llamada?
Define umbrales relativos a tu baseline y carga. Una política mejor: alertar en desviación sostenida (p. ej., 3–5× la baseline durante varios minutos) más impacto en usuarios, no por un solo pico.
Conclusión: próximos pasos que realmente puedes hacer
Si quieres mejorar en la latencia ZFS, deja de tratarla como una propiedad mística de los discos. Es una salida medible de topología, carga, comportamiento de caché y trabajo en segundo plano. zpool iostat -r te da lo más cercano a una historia veraz, siempre que le hagas las preguntas correctas.
Haz lo siguiente:
- Ejecuta
zpool iostat -v -r 1 10durante carga normal y guarda la salida como tu baseline. - Programa scrubs de forma consistente y registra perfiles de latencia para detectar fallos lentos temprano.
- Identifica tus 2–3 datasets más sensibles a latencia y audita sus propiedades (
recordsize, compresión, elegibilidad para vdev especial). - Decide si la topología de tu pool coincide con la carga. Si no, acepta que la solución real es arquitectónica, no un tunable.
La latencia no se preocupa por tus intenciones. Mídela, respétala y suele comportarse. Suele.