Tu scrub ha estado “in progress” el tiempo suficiente como para que la gente pregunte si el almacenamiento está encantado. Las aplicaciones se sienten lentas, los paneles muestran una marea de I/O y la ETA o no existe o está mintiendo. Necesitas saber: ¿es un scrub normal y aburrido que está haciendo su trabajo, o es un síntoma de algo que te morderá después?
Esta es la forma orientada a producción de responder esa pregunta. Separaremos la lentitud esperada (la que programas y toleras) de la lentitud patológica (la que arreglas antes de que se convierta en un incendio de tickets de soporte).
Qué hace realmente un scrub (y por qué a veces “lento” es correcto)
Un ZFS scrub no es un benchmark ni una operación de copia. Es una patrulla de integridad de datos. ZFS recorre los bloques asignados en el pool, los lee, verifica checksums y—si la redundancia lo permite—repara corrupción silenciosa reescribiendo datos buenos sobre los malos. Es mantenimiento proactivo, del tipo “encuéntralo antes que el usuario”.
Eso implica dos cosas que sorprenden a la gente:
- Los scrubs son fundamentalmente de lectura intensiva (con escrituras ocasionales cuando ocurren reparaciones). Tu pool puede estar “lento” porque las lecturas son lentas, porque hay contención con cargas reales, o porque ZFS intencionalmente está siendo educado.
- Los scrubs operan a nivel de bloques, no a nivel de archivos. La fragmentación, las elecciones de recordsize y la sobrecarga de metadatos pueden importar más que el MB/s bruto del disco.
Los scrubs también se comportan diferente según la disposición de vdev. Los mirrors tienden a scrubear más rápido y de forma más predecible que RAIDZ, porque los mirrors pueden atender lecturas desde cualquiera de los lados y tienen una matemática de paridad más simple. Los RAIDZ scrubs están bien cuando están sanos, pero pueden convertirse en una caminata larga si tienes vdevs anchos, discos marginales o I/O aleatorio intenso de las aplicaciones.
Regla práctica que uso: el tiempo de scrub es una propiedad observable de tu sistema, no una falla moral. Pero la velocidad del scrub que colapsa, o una ETA que aumenta, es un olor a problema. No siempre un incendio, pero siempre digno de inspección.
Broma corta #1: Un scrub sin ETA es como una interrupción de almacenamiento sin postmortem—técnicamente posible, socialmente inaceptable.
Datos interesantes y un poco de historia
- ZFS popularizó el checksumming end-to-end en el almacenamiento de servidor mainstream. Los checksums se almacenan separados de los datos, por eso ZFS puede detectar “discos mentirosos” que devuelven bloques corruptos sin errores I/O.
- El scrub es la respuesta de ZFS a la “bit rot”—corrupción silenciosa e incremental que los RAID tradicionales a menudo no detectan a menos que ocurra una lectura y se dispare una reconstrucción por paridad.
- El término “scrub” proviene de sistemas de almacenamiento más antiguos que escaneaban periódicamente el medio buscando errores. ZFS lo hizo rutinario y visible para el usuario.
- RAIDZ fue diseñado para evitar el write hole visto en implementaciones clásicas de RAID5/6, manteniendo metadatos transaccionalmente consistentes y semántica copy-on-write.
- ZFS nació en Sun Microsystems y luego se difundió ampliamente vía OpenZFS. El comportamiento moderno de ZFS depende de la versión de OpenZFS, no solo de “ZFS” como marca.
- Los scrubs solían ser más dolorosos en sistemas sin buen scheduling de I/O o donde el throttling de scrub era primitivo. Las pilas modernas de Linux y FreeBSD te dan más palancas, pero también más formas de equivocarte.
- Los metadatos importan. Pools con millones de archivos pequeños pueden scrubear más lento que un pool con menos archivos grandes, incluso si el “espacio usado” parece similar.
- Los discos SMR hicieron los scrubs más impredecibles en el mundo real. Cuando el disco hace garbage collection shingled en segundo plano, las “lecturas” pueden convertirse en “lecturas más drama de reescritura interna”.
- Las matrices empresariales han hecho lecturas de patrulla durante décadas, a menudo de forma invisible. ZFS solo te da la verdad en abierto—y resulta que la verdad puede ser lenta.
Lentitud normal del scrub vs problema real: el modelo mental
“Scrub lento” es ambiguo. Debes precisar qué tipo de lentitud estás viendo. Yo lo divido en cuatro cubetas:
1) Lentitud “gran pool, física normal”
Si tienes cientos de TB y discos giratorios, un scrub que toma días puede ser normal. Está limitado por el ancho de banda de lectura secuencial, la disposición de vdev y el hecho de que los scrubs no siempre obtienen patrones de acceso perfectamente secuenciales (los bloques asignados no son necesariamente contiguos).
Señales de que es normal:
- La tasa de scrub es estable en el transcurso de horas.
- La latencia de disco no se dispara.
- El impacto en las aplicaciones es predecible y acotado.
- No hay errores de checksum ni errores de lectura.
2) Lentitud “intencionalmente throttled”
ZFS a menudo se auto-limitirá en los scrubs para que las cargas de producción no se caigan. Eso significa que tu scrub puede verse decepcionantemente lento mientras el sistema sigue siendo usable. Esto es buen comportamiento de ingeniería. Puedes ajustarlo, pero hazlo deliberadamente.
Señales de que está limitando:
- La CPU está mayormente bien.
- IOPS no están saturados, pero el progreso del scrub avanza lentamente.
- La latencia de la carga se mantiene dentro de los SLO.
3) Lentitud “por contención con la carga”
Si el pool atiende una base de datos ocupada, una granja de VM o una carga de objetos, las lecturas del scrub compiten con las lecturas/escrituras de las aplicaciones. Ahora la velocidad del scrub se convierte en una función de las horas de negocio. Eso no es una falla de ZFS; es un fallo de programación.
Señales de contención:
- La velocidad del scrub varía con los patrones de tráfico.
- Los picos de latencia se correlacionan con los picos de la aplicación.
- Apagar el scrub hace felices a los usuarios otra vez.
4) Lentitud “algo está mal”
Esta es la categoría que realmente te preocupa. La lentitud del scrub se vuelve síntoma: un disco está reintentando lecturas, un controlador está registrando errores, un enlace negoció a 1.5Gbps, un miembro enfermo del vdev arrastra a todos, o hiciste un layout de pool que es bueno para capacidad pero malo para el comportamiento del scrub.
Señales de que probablemente hay un problema real:
- Errores de lectura, errores de checksum o bytes “repaired” que aumentan entre scrubs.
- Un disco muestra latencia mucho mayor o menor rendimiento que sus pares.
- La tasa de scrub colapsa con el tiempo (empieza normal y luego se arrastra).
- Los logs del kernel muestran resets, timeouts o problemas de enlace.
- Los atributos SMART muestran sectores realocados/pending o errores UDMA CRC.
La clave: “lento” no es un diagnóstico. Estás cazando un cuello de botella y luego preguntando si ese cuello es esperado, configurado o está fallando.
Guion de diagnóstico rápido (primero/segundo/tercero)
Cuando estás on-call, no tienes tiempo para un largo seminario filosófico. Necesitas un embudo rápido que estreche el problema a uno de: esperado, contendido, throttled, o roto.
Primero: ¿El scrub está healthy?
- Revisa el estado del pool en busca de errores y la tasa real del scrub.
- Busca cualquier miembro de vdev que esté degraded, faulted o tenga “too many errors.”
- Decisión: si hay errores, trata esto como un incidente de fiabilidad primero y una pregunta de rendimiento después.
Segundo: ¿Un dispositivo está arrastrando todo el vdev?
- Revisa la latencia por disco y los tiempos de servicio de I/O mientras corre el scrub.
- Revisa SMART rápidamente en busca de pending sectors, media errors y link CRC errors.
- Decisión: si un disco está lento o reintentando, reemplázalo o al menos aísla; los scrubs son el canario.
Tercero: ¿Es contención o throttling?
- Correlaciona la velocidad del scrub con métricas de la carga (IOPS, latencia, queue depth).
- Chequea los tunables de ZFS y si el scrub está intencionalmente limitado.
- Decisión: si estás throttled, ajusta con cuidado; si está contendido, reprograma o separa cargas.
Sólo después de esos tres llegas a “preguntas de arquitectura” como ancho de vdev, recordsize, vdevs especiales o añadir dispositivos cache. Si el scrub es lento porque un cable SATA es defectuoso, ningún “tuning” arregla la física.
Tareas prácticas: comandos, qué significa la salida y qué decisión tomar
Las siguientes tareas están diseñadas para ejecutarse mientras hay un scrub activo (o justo después). Cada una incluye un comando realista, salida de ejemplo, qué significa y la siguiente decisión. El prompt y las salidas son ilustrativos, pero los comandos son estándar en entornos reales.
Task 1: Confirmar estado del scrub, tasa y errores
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 01:00:02 2025
12.3T scanned at 612M/s, 8.1T issued at 403M/s, 43.2T total
0B repaired, 18.75% done, 2 days 09:14:33 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
errors: No known data errors
Qué significa: ZFS muestra tanto “scanned” como “issued.” Issued está más cerca de la tasa real de finalización de I/O físico. Si issued es mucho menor que scanned, puedes estar viendo readahead, efectos de cache o espera por dispositivos lentos.
Decisión: Si los contadores READ/WRITE/CKSUM son distintos de cero, deja de tratar esto como “solo lento.” Investiga los dispositivos que fallan antes de tunear.
Task 2: Obtener progreso en una línea repetidamente (útil para canales de incidentes)
cr0x@server:~$ zpool status tank | sed -n '1,12p'
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 01:00:02 2025
12.3T scanned at 612M/s, 8.1T issued at 403M/s, 43.2T total
0B repaired, 18.75% done, 2 days 09:14:33 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
Qué significa: Este es el snippet mínimo viable de estado. Si la ETA sigue aumentando hora a hora, probablemente estés contendido o reintentando lecturas.
Decisión: Si la tasa issued es estable y la ETA disminuye constantemente, probablemente es normal o throttled. Si fluctúa salvajemente, pasa a chequear por-disco.
Task 3: Encontrar qué layout de vdev tienes
cr0x@server:~$ zpool status -P tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000...A1 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000...B2 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000...C3 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000...D4 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000...E5 ONLINE 0 0 0
/dev/disk/by-id/ata-ST12000...F6 ONLINE 0 0 0
Qué significa: RAIDZ2 en un vdev ancho. La velocidad del scrub estará limitada por el disco más lento y la sobrecarga de paridad. Un disco con mal comportamiento puede ralentizar todo el vdev.
Decisión: Si tienes un RAIDZ muy ancho y los scrubs son dolorosos, quizás necesites un cambio arquitectónico más adelante (más vdevs, anchura menor). No intentes “tunear” las leyes de la física.
Task 4: Chequear latencia y utilización por disco durante el scrub (Linux)
cr0x@server:~$ iostat -x 2 3
Linux 6.6.12 (server) 12/25/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
4.21 0.00 2.73 8.14 0.00 84.92
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
sda 112.0 28800.0 0.0 0.00 18.40 257.1 2.0 512.0 4.30 2.10 98.5
sdb 118.0 30208.0 0.0 0.00 17.92 256.0 2.0 512.0 4.10 2.12 97.9
sdc 110.0 28160.0 0.0 0.00 19.30 256.0 2.0 512.0 4.20 2.05 98.2
sdd 15.0 3840.0 0.0 0.00 220.10 256.0 1.0 256.0 10.00 3.90 99.1
sde 115.0 29440.0 0.0 0.00 18.10 256.0 2.0 512.0 4.00 2.08 98.0
sdf 114.0 29184.0 0.0 0.00 18.70 256.0 2.0 512.0 4.20 2.11 98.4
Qué significa: sdd tiene r_await de ~220ms mientras los otros están ~18ms. Ese es tu ancla de scrub. El pool se moverá al ritmo del peor desempeño en un vdev RAIDZ.
Decisión: Inspecciona inmediatamente sdd en busca de errores/logs/SMART. Si es un problema de cable/controlador, arregla eso antes de reemplazar el disco.
Task 5: Revisar logs del kernel por resets/timeouts (Linux)
cr0x@server:~$ sudo dmesg -T | egrep -i 'ata|scsi|reset|timeout|error' | tail -n 12
[Wed Dec 24 13:18:44 2025] ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[Wed Dec 24 13:18:44 2025] ata7.00: failed command: READ FPDMA QUEUED
[Wed Dec 24 13:18:44 2025] ata7: hard resetting link
[Wed Dec 24 13:18:45 2025] ata7: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[Wed Dec 24 13:18:46 2025] sd 6:0:0:0: [sdd] tag#17 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=14s
[Wed Dec 24 13:18:46 2025] blk_update_request: I/O error, dev sdd, sector 123456789 op 0x0:(READ) flags 0x0 phys_seg 8 prio class 0
Qué significa: Reset de enlace más renegociación a 1.5Gbps es territorio clásico de “cable/backplane/puerto malo”. También puede ser un disco muriendo, pero los cables son más baratos y vergonzosamente comunes.
Decisión: Trata como fallo de hardware. Reasienta/reemplaza el cable o muévelo a otro puerto. Luego vuelve a revisar la latencia por disco. Si los errores persisten, reemplaza el disco.
Task 6: Chequeo rápido SMART para el dispositivo lento
cr0x@server:~$ sudo smartctl -a /dev/sdd | egrep -i 'Reallocated_Sector_Ct|Current_Pending_Sector|Offline_Uncorrectable|UDMA_CRC_Error_Count|SMART overall|Power_On_Hours'
SMART overall-health self-assessment test result: PASSED
9 Power_On_Hours 0x0032 086 086 000 Old_age Always - 31245
5 Reallocated_Sector_Ct 0x0033 100 100 010 Pre-fail Always - 0
197 Current_Pending_Sector 0x0012 100 100 000 Old_age Always - 12
198 Offline_Uncorrectable 0x0010 100 100 000 Old_age Offline - 3
199 UDMA_CRC_Error_Count 0x003e 200 199 000 Old_age Always - 27
Qué significa: Pending sectors y offline uncorrectables significan que el disco lucha por leer algunas áreas. Los UDMA CRC errors a menudo apuntan a problemas de cableado/backplane. “PASSED” no es absolución; es marketing.
Decisión: Si existen pending/offline uncorrectables, planifica el reemplazo. Si los CRC errors aumentan, arregla también la ruta (cable/backplane/HBA).
Task 7: Identificar si el pool está haciendo reparaciones (y cuánto)
cr0x@server:~$ zpool status -v tank | sed -n '1,25p'
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 01:00:02 2025
14.8T scanned at 540M/s, 10.2T issued at 372M/s, 43.2T total
256M repaired, 23.61% done, 2 days 05:01:12 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
Qué significa: “repaired” distinto de cero durante el scrub significa que ZFS encontró mismatches de checksum y los corrigió. Ese es el scrub haciendo su trabajo, pero también es evidencia de corrupción en algún lugar (disco, cableado, controlador o memoria).
Decisión: Si las reparaciones son recurrentes entre scrubs, investiga la causa raíz. Una reparación única tras un evento conocido puede estar bien; reparaciones repetidas no lo están.
Task 8: Buscar indicadores de I/O y latencia a nivel ZFS (Linux)
cr0x@server:~$ sudo cat /proc/spl/kstat/zfs/arcstats | egrep '^(hits|misses|size|c_max|demand_data_misses|prefetch_data_misses) ' | head
hits 2876543210
misses 456789012
size 17179869184
c_max 34359738368
demand_data_misses 123456789
prefetch_data_misses 234567890
Qué significa: Las estadísticas ARC te dicen si las lecturas se sirven desde memoria o van al disco. Durante un scrub, el ARC puede ser menos útil porque las lecturas del scrub no siempre son cache-friendly, pero un ARC pequeño con cargas pesadas puede empeorar la contención.
Decisión: Si el ARC está reprimido y la caja está haciendo swap, arregla la presión de memoria primero. No culpes al scrub por un problema de RAM.
Task 9: Ver I/O del pool en tiempo real (Linux con zpool iostat)
cr0x@server:~$ zpool iostat -v tank 2 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 28.1T 15.1T 3.10K 220 380M 12.1M
raidz2-0 28.1T 15.1T 3.10K 220 380M 12.1M
sda - - 520 35 63.5M 2.1M
sdb - - 525 36 64.1M 2.1M
sdc - - 518 35 63.2M 2.0M
sdd - - 110 34 12.9M 2.0M
sde - - 523 35 64.0M 2.1M
sdf - - 524 35 64.3M 2.1M
---------- ----- ----- ----- ----- ----- -----
Qué significa: De nuevo, sdd está rindiendo menos que los otros. En RAIDZ, eso puede reducir el throughput efectivo y aumentar el tiempo del scrub.
Decisión: Si un dispositivo muestra persistentemente menor ancho de banda/ops, céntrate allí. No ajustes tunables globales hasta que la paridad del dispositivo se restaure.
Task 10: Confirmar ashift y propiedades básicas del pool (baseline de rendimiento)
cr0x@server:~$ zdb -C tank | egrep 'ashift|vdev_tree' -n | head -n 8
64: ashift: 12
120: vdev_tree:
121: type: 'root'
122: id: 0
Qué significa: ashift: 12 implica sectores de 4K. Si ves ashift: 9 en discos modernos de 4K, puedes obtener amplificación de escritura y comportamiento extraño de rendimiento. No siempre se notará durante scrub (principalmente lecturas), pero puede empeorar el rendimiento general del pool y la sobrecarga de resilver/scrub.
Decisión: Si ashift está mal, la solución suele ser “reconstruir el pool correctamente”, no “tunar más”. Ponlo en la hoja de ruta.
Task 11: Verificar compresión y recordsize del dataset (interacción con la carga)
cr0x@server:~$ zfs get -o name,property,value -s local compression,recordsize tank/vmstore
NAME PROPERTY VALUE
tank/vmstore compression lz4
tank/vmstore recordsize 128K
Qué significa: Para imágenes VM, recordsize suele establecerse más pequeño (como 16K) según patrones de I/O. Un recordsize grande no es “incorrecto”, pero si tu carga es random 4K, puedes terminar con más lecturas por byte útil durante el scrub y mayor sobrecarga operativa en general.
Decisión: No cambies recordsize a la ligera sobre datos existentes. Pero si el dolor del scrub se correlaciona con un dataset conocido por I/O aleatorio pequeño, revisa el diseño del dataset para la próxima iteración.
Task 12: Verificar vdevs especiales (metadatos) y su salud
cr0x@server:~$ zpool status tank | egrep -n 'special|log|cache|spares' -A3
15: special
16: nvme0n1p2 ONLINE 0 0 0
Qué significa: Si tienes un vdev special (a menudo NVMe) almacenando metadatos/bloques pequeños, su salud y latencia pueden dominar el comportamiento del scrub para pools con mucho metadata. Un vdev special moribundo puede hacer que todo el pool “se sienta” lento incluso si los HDD están bien.
Decisión: Si el scrub está lento en una carga con muchos metadatos, revisa el rendimiento y errores del vdev special temprano.
Task 13: Verificar la ruta real del dispositivo y la velocidad del enlace (falla oculta común)
cr0x@server:~$ sudo hdparm -I /dev/sdd | egrep -i 'Transport|speed|SATA Version' | head -n 5
Transport: Serial, ATA8-AST, SATA 3.1
SATA Version is: SATA 3.1, 6.0 Gb/s (current: 1.5 Gb/s)
Qué significa: El disco soporta 6.0Gb/s pero actualmente está a 1.5Gb/s. Eso es un fuerte indicador de problemas de enlace, no de “ZFS lento”.
Decisión: Arregla la ruta física. Tras la reparación, confirma que negocia a 6.0Gb/s y vuelve a ejecutar iostat.
Task 14: Revisar parámetros relacionados con throttling del scrub (Linux OpenZFS)
cr0x@server:~$ sudo systool -m zfs -a 2>/dev/null | egrep 'zfs_scrub_delay|zfs_top_maxinflight|zfs_vdev_scrub_max_active' | head -n 20
Parameters:
zfs_scrub_delay = "4"
zfs_top_maxinflight = "32"
zfs_vdev_scrub_max_active = "2"
Qué significa: Estos valores influyen cuán agresivamente el scrub emite I/O. Más agresivo no siempre es mejor; puedes aumentar la profundidad de cola y la latencia para aplicaciones, y a veces ralentizar el scrub por thrashing.
Decisión: Si el scrub es lento pero healthy y tienes margen (baja latencia de impacto, baja util), puedes considerar tunear. Si el sistema ya está caliente, no “arregles” haciéndolo pelear más.
Task 15: Confirmar TRIM y comportamiento autotrim (pools SSD)
cr0x@server:~$ zpool get autotrim tank
NAME PROPERTY VALUE SOURCE
tank autotrim off default
Qué significa: En pools SSD, autotrim puede afectar el rendimiento a largo plazo. No afecta directamente la velocidad del scrub, pero cambia cómo se comporta el pool bajo lecturas/escrituras sostenidas y garbage collection, lo que puede hacer los scrubs “aleatoriamente horribles”.
Decisión: Si estás en SSDs y ves caídas periódicas de rendimiento, evalúa activar autotrim en una ventana de cambio controlada.
Task 16: Ver si accidentalmente estás scrubbeando con demasiada frecuencia
cr0x@server:~$ sudo grep -R "zpool scrub" -n /etc/cron* /var/spool/cron 2>/dev/null | head
/etc/cron.monthly/zfs-scrub:4: zpool scrub tank
Qué significa: Los scrubs mensuales son comunes. Los scrubs semanales pueden estar bien para pools pequeños, pero en pools grandes pueden significar que estás casi siempre en scrub, y los operadores empiezan a ignorar la señal.
Decisión: Ajusta la cadencia apropiada al medio y al riesgo. Si el scrub nunca termina antes del siguiente, has convertido las comprobaciones de integridad en ruido de fondo.
Tres micro-historias corporativas desde las trincheras del scrub
Micro-historia 1: El incidente causado por una suposición errónea
Una compañía mediana ejecutaba un clúster de virtualización respaldado por ZFS. Nada exótico: RAIDZ2, grandes discos SATA, un pool por nodo. Los scrubs se programaban mensualmente y siempre tomaban “un rato”. La gente lo aceptó como parte de la vida.
Entonces, un mes la ETA del scrub comenzó a aumentar. No fue dramático al principio—solo un día extra. El on-call asumió que era contención por la carga: trabajos batch de fin de trimestre. Lo dejaron pasar. “Los scrubs son lentos; terminará”.
Dos días después, la latencia de las VM de cara al usuario se disparó, luego se estabilizó, luego volvió a subir. zpool status aún mostraba ONLINE, sin errores obvios. La suposición continuó: “está ocupado”. Así que nadie miró las estadísticas a nivel de disco. Ese fue el error.
Cuando alguien finalmente ejecutó iostat -x, un disco tenía read await de 300–800ms, mientras los otros estaban en 15–25ms. SMART tenía pending sectors. El disco no fallaba rápido; fallaba educadamente, arrastrando al vdev entero mediante reintentos. Ese es el peor tipo porque parece “lentitud normal” hasta que deja de serlo.
Reemplazaron el disco. La tasa del scrub volvió a la normalidad de inmediato. La lección real no fue “reemplazar discos más rápido.” Fue: nunca asumas que la lentitud del scrub es la carga hasta que hayas probado que todos los dispositivos están sanos. El scrub es la única vez que algunos sectores malos se tocan. Es tu sistema de advertencia temprana. Úsalo.
Micro-historia 2: La optimización que salió mal
Otra organización tenía ventanas de mantenimiento estrictas. Querían que los scrubs terminaran durante un fin de semana, sin excepciones. Alguien encontró tunables de scrub y decidió “subirle.” Aumentaron la concurrencia del scrub y redujeron los delays. El scrub se volvió agresivo y el throughput se vio bien—por más o menos una hora.
Luego la latencia de las aplicaciones subió. Los hypervisors comenzaron a reportar stalls de almacenamiento. Los usuarios se quejaron el lunes por la mañana de “lentitud aleatoria.” El equipo culpó primero a la red (como hacen los equipos), luego a ZFS, luego al hypervisor. Triángulo clásico de la negación.
Lo que realmente pasó fue más aburrido: el patrón de I/O del scrub desplazó la cache de la carga y llenó las colas de disco. Los HDDs llegaron a casi 100% de util con altos tiempos de servicio. Algunas lecturas de la aplicación se convirtieron en monstruos de tail-latency. El scrub no terminó ni siquiera mucho más rápido en general—porque a medida que las colas crecían, el throughput efectivo cayó y aumentaron los reintentos.
Revirtieron el tuning y movieron los scrubs a periodos de menor tráfico. La “optimización” funcionó, pero el impacto a nivel sistema fue negativo. El mejor truco de rendimiento en almacenamiento sigue siendo la programación: no luches con tus usuarios.
Broma corta #2: Tunear almacenamiento es como política de oficina—si empujas demasiado, todos se ralentizan y de alguna forma sigue siendo tu culpa.
Micro-historia 3: La práctica aburrida pero correcta que salvó el día
Un equipo fintech ejecutaba OpenZFS en Linux para una carga tipo ledger. Los scrubs se trataban como una actividad formal de mantenimiento: programados, monitorizados y comparados con históricos. Nada de heroísmos. Solo gráficos y disciplina.
Mantenían un runbook simple: después de cada scrub, registrar la duración, el ancho de banda emitido medio y cualquier byte reparado. Si “repaired” era distinto de cero, disparaba una comprobación más profunda: logs del kernel, SMART long test y revisión de cambios de hardware recientes.
Un mes, un scrub completó con una pequeña cantidad reparada—nada alarmante por sí solo. Pero fue el segundo mes consecutivo. Su lógica de baseline lo marcó. El on-call investigó y encontró CRC intermitentes en la ruta de un disco. No eran suficientes para que el disco fallara de inmediato, pero sí para voltear bits ocasionalmente bajo carga. Justo el tipo de defecto que arruina tu día seis meses después.
Cambiaron el cable del backplane y movieron ese disco a otro puerto HBA. Las reparaciones se detuvieron. Sin outage, sin pérdida de datos, sin un informe de incidente dramático. Este es el tipo de victoria que nunca se celebra porque nada explotó. Debería celebrarse de todos modos.
Errores comunes: síntoma → causa raíz → solución
Esta sección es intencionalmente directa. Son patrones que aparecen en producción, repetidamente, porque los humanos son consistentes.
La ETA del scrub aumenta con el tiempo
- Síntoma: ETA pasa de “12 horas” a “2 días” mientras corre el scrub.
- Causa raíz: Un dispositivo reintenta lecturas (problemas de medio) o el enlace está flapping; alternativamente, la contención de la carga aumentó.
- Solución: Ejecuta
iostat -xyzpool iostat -vpara identificar un disco lento; revisadmesgy SMART. Si no hay un disco único lento, correlaciona con la carga y reprograma el scrub.
El scrub es “lento” solo durante horas laborales
- Síntoma: El scrub se arrastra de 9–5 y acelera de noche.
- Causa raíz: Contención con la carga de producción; ZFS y/o el scheduler del OS está priorizando I/O de primer plano.
- Solución: Programa scrubs para ventanas de bajo tráfico; considera throttling en vez de agresividad. No subas la concurrencia del scrub esperando lo contrario.
Un disco muestra wait 10x mayor que los demás
- Síntoma: En
iostat -x, un disco tiene r_await alto o patrones de%utilque no coinciden. - Causa raíz: Disco muriendo, comportamiento SMR bajo estrés, cable/backplane malo, puerto negociado a menor velocidad.
- Solución: Revisa
dmesgy SMART, confirma velocidad de enlace, intercambia cable/puerto, reemplaza disco si aparecen pending sectors o uncorrectables.
El scrub provoca timeouts en las aplicaciones
- Síntoma: Picos de latencia, timeouts, crece la queue depth; el scrub parece “DoS” al sistema.
- Causa raíz: I/O del scrub demasiado agresivo, mala aislamiento de cargas, pocos vdevs, pool HDD sirviendo I/O aleatorio sin suficientes spindles.
- Solución: Reduce la agresividad del scrub; reprograma; añade vdevs o mueve carga a SSD/NVMe; considera vdevs special para casos con muchos metadatos. Deja de esperar que un RAIDZ ancho actúe como un array.
El scrub reporta bytes reparados repetidamente
- Síntoma: Cada scrub repara algunos datos.
- Causa raíz: Fuente crónica de corrupción: disco malo, cable malo, controlador inestable o memoria (sí, memoria).
- Solución: Investiga el camino hardware end-to-end; ejecuta SMART long tests; revisa logs ECC si están disponibles; considera una ventana controlada para pruebas de memoria. Los datos reparados son un regalo—no los ignores.
El scrub es lento en un pool SSD “sin razón”
- Síntoma: Pool NVMe/SSD scrubea más lento de lo esperado, a veces con caídas periódicas.
- Causa raíz: Throttling térmico, garbage collection del SSD, mal comportamiento TRIM, problemas de enlace PCIe, o un vdev special estrangulado.
- Solución: Revisa temperaturas y velocidad del enlace PCIe; evalúa
autotrim; confirma firmware; asegura que el vdev special no esté saturado o con errores.
El scrub nunca termina antes del próximo scrub programado
- Síntoma: Siempre scrubbeando; los operadores dejan de prestarle atención.
- Causa raíz: Pool sobredimensionado para el medio dado, cadencia demasiado frecuente, o el scrub es reiniciado por automatización.
- Solución: Reduce la cadencia; asegúrate de que los scrubs no se reinicien innecesariamente; considera cambios arquitectónicos (más vdevs, medios más rápidos) si las comprobaciones de integridad no completan en una ventana razonable.
La velocidad del scrub está muy por debajo de lo que la matemática de disco sugiere
- Síntoma: “Tenemos N discos, cada uno puede hacer X MB/s, entonces ¿por qué no N×X?”
- Causa raíz: El scrub lee bloques asignados, no necesariamente secuenciales; sobrecarga de metadatos; paridad RAIDZ; fragmentación; y el pool puede estar casi lleno, lo que empeora todo.
- Solución: Compárate con tus propias líneas base históricas de scrub, no con hojas de datos del proveedor. Si estás casi lleno, libera espacio. Si la fragmentación es severa, considera un re-layout planificado mediante replicación a un pool nuevo.
Listas de verificación / planes paso a paso
Paso a paso: Decidir si un scrub lento es “normal”
- Captura el estado actual. Ejecuta
zpool status -v. Guárdalo en tu ticket/chat. - Mira si hay errores. Contadores READ/WRITE/CKSUM distintos de cero o cambios en “repaired” cambian la urgencia.
- Mide la tasa issued. Si issued es estable y dentro de tu rango histórico, probablemente es normal.
- Revisa la latencia por disco. Usa
iostat -x(Linux) e identifica outliers. - Revisa logs. Una línea en
dmesgsobre resets puede explicar días de dolor en el scrub. - Chequea SMART. Pending sectors, uncorrectables y CRC errors deciden si reemplazas hardware.
- Correlaciona con la carga. Si el scrub es lento solo bajo carga, arregla la programación y/o el throttling.
- Solo entonces tunear. Y haz un cambio a la vez con plan de rollback.
Paso a paso: Si encuentras un disco lento durante el scrub
- Confirma que está consistentemente lento:
iostat -x 2 5yzpool iostat -v 2 5. - Revisa negociación de enlace abajo:
hdparm -Ien SATA, o logs del controlador para SAS. - Revisa logs del kernel por resets/timeouts:
dmesg -Tfiltrado. - Revisa SMART: pending/offline uncorrectable sectors significan que vive en tiempo prestado.
- Intercambia lo barato primero (cable/puerto) si la evidencia apunta a problemas de enlace.
- Reemplaza el disco si hay problemas de medio o los errores persisten tras arreglos de la ruta.
- Tras reemplazar, ejecuta otro scrub o al menos un plan de verificación dirigido según tus estándares operativos.
Paso a paso: Si el scrub está healthy pero interrumpe rendimiento
- Confirma que ningún dispositivo está enfermo (latencia outlier, errores).
- Confirma si el scrub ya está throttled (revisa tunables y profundidad de I/O observada).
- Mueve la programación del scrub a periodos de baja carga; escalona entre pools/nodos.
- Si debes scrubear durante horas laborales, limita en vez de acelerar.
- Reevalúa el layout del pool si rutinariamente no puedes completar scrubs en la ventana de mantenimiento.
Preguntas frecuentes
1) ¿Cuál es una velocidad “normal” de scrub en ZFS?
Normal es lo que tu pool hace cuando está sano, con poca carga y sin errores. Usa tu propia duración histórica de scrub y el ancho de banda issued como baseline. Las especificaciones secuenciales del proveedor no son una promesa de scrub.
2) ¿Por qué difiere scanned de issued en zpool status?
“Scanned” refleja el progreso lógico a través de bloques; “issued” refleja el I/O real enviado/completado a los vdevs. Grandes brechas pueden ocurrir por caching, readahead o espera por dispositivos lentos. Si issued es bajo y la latencia es alta, busca un disco ancla.
3) ¿Un scrub lee el espacio libre?
Generalmente, el scrub verifica bloques asignados (lo que realmente está en uso). No es un escaneo total de superficie de cada sector. Por eso un disco puede aún tener sectores malos latentes que solo aparecen al escribir o leer más tarde.
4) ¿Debo parar un scrub si está lento?
Si el scrub está healthy pero impacta los SLO de producción, pausar/parar puede ser razonable—y luego reprogramarlo. Si ves errores o reparaciones, detenerlo solo retrasa información que probablemente necesitas. Atiende la causa hardware subyacente en su lugar.
5) ¿Con qué frecuencia debo hacer scrub?
La cadencia común es mensual para pools HDD grandes, a veces semanal para entornos más pequeños o de mayor riesgo. La respuesta depende del medio, la redundancia y cuán rápido quieres descubrir errores latentes. Si tu cadence supera tu capacidad para terminar scrubs, ajusta—no normalices “siempre en scrub”.
6) El scrub encontró y reparó datos. ¿Estoy a salvo ahora?
Estás más seguro que antes, pero no “terminaste”. Las reparaciones significan que algo se corrompió bajo ZFS. Si las reparaciones se repiten, necesitas un RCA de discos, cables, controladores y potencialmente memoria.
7) ¿RAIDZ es inherentemente lento en scrubs comparado con mirrors?
Los mirrors suelen ser más rápidos y predecibles en lecturas porque pueden balancear carga y no hacen reconstrucción por paridad en lecturas. RAIDZ puede estar bien cuando está sano, pero los vdevs RAIDZ anchos son más sensibles a un disco lento y a patrones I/O aleatorios.
8) ¿Puede el tuning hacer los scrubs dramáticamente más rápidos?
A veces modestamente, si tienes margen y defaults conservadores. Pero el tuning no sustituye a más spindles, mejor medio o arreglar una ruta defectuosa. Además: el tuning puede salir mal y aumentar latencia y reducir throughput efectivo.
9) ¿Por qué el scrub es lento en un pool mayormente vacío?
Porque “vacío” no significa “simple”. Un pool con millones de archivos pequeños, mucho metadata, snapshots o fragmentación puede scrubear lento aun si el espacio usado es bajo. El scrub toca bloques asignados; las asignaciones con mucho metadata no son secuenciales.
10) ¿Cuál es la diferencia entre scrub y resilver, y por qué importa para la lentitud?
El scrub verifica datos existentes y repara corrupción; la resilver reconstruye datos a un dispositivo reemplazado/retornado. La resilver suele tener prioridad y patrones distintos, y puede ser más escritora. Si confundes ambos, malinterpretarás expectativas de rendimiento y urgencia.
Conclusión: pasos prácticos siguientes
Los scrubs lentos no son inherentemente alarmantes. De hecho, un scrub lento en un pool grande y ocupado a menudo indica que ZFS se comporta de forma responsable. Lo que da miedo es la lentitud sin explicación, especialmente cuando viene con outliers por disco, resets del kernel o reparaciones recurrentes.
Usa esta secuencia como tu predeterminada:
- Ejecuta
zpool status -vy decide si esto es un evento de fiabilidad (errores/reparaciones) o un problema de programación/rendimiento. - Ejecuta
iostat -xyzpool iostat -vpara encontrar el dispositivo lento o confirmar contención. - Revisa
dmesgy SMART por fallos obvios en la ruta hardware. - Solo entonces considera ajustes de tunning y cambios de programación, y mide el impacto contra tu baseline histórico.
Una idea parafraseada de W. Edwards Deming encaja en el trabajo operativo: “Without data, you’re just someone with an opinion.” La lentitud del scrub es tu oportunidad para recopilar datos antes de recopilar outages.