Los discos nuevos mienten. No con malicia—más como un vendedor que promete rendimiento “hasta” cierto punto y pasa por alto la letra pequeña sobre el comportamiento en estado estable. Construyes un pool ZFS nuevo, ejecutas un benchmark rápido y todo parece glorioso. Luego pones una carga real y el gráfico de latencia empieza a hacer arte impresionista.
zpool initialize existe para reducir esa brecha entre “nuevo y brillante” y “producción y gruñón”. Escribe deliberadamente a lo largo del vdev para que ZFS no descubra comportamientos de ruta lenta en el peor momento posible—como el primer lunes después de una migración.
Qué hace realmente zpool initialize (y qué no hace)
A grandes rasgos, zpool initialize escribe en todo el espacio de direcciones de los vdevs de nivel superior en un pool. Piénsalo como un preacondicionamiento: fuerza al pool a tocar todas las regiones de los discos para que no te sorprenda más tarde cuando áreas frías, nunca escritas, se comporten distinto que las partes calientes que casualmente benchmarkeaste.
En muchos dispositivos de almacenamiento—especialmente SSDs, pero también comportamientos tipo SMR modernos y algunas optimizaciones de firmware de discos—el rendimiento cambia después de que el dispositivo ha sido escrito de extremo a extremo al menos una vez. Recién salido de la caja, la unidad puede aparecer más rápida porque no ha tenido que hacer la contabilidad interna que eventualmente tendrá que hacer. Una vez que escribes ampliamente en ella, la empujas hacia el “estado estable”, que es con lo que vivirás durante años.
Initialize no es scrub, y no es resilver
- Scrub lee y verifica bloques de datos existentes y los repara usando redundancia. Se trata de la integridad de datos ya escritos.
- Resilver reconstruye datos faltantes en un disco de reemplazo, basado en bloques asignados. Se trata de restaurar redundancia.
- Initialize se trata de escribir a lo largo del dispositivo para evitar sorpresas de “primera escritura en esta región” bajo carga de producción.
Initialize tampoco arregla mágicamente un mal diseño. Si construiste un pool con el ashift incorrecto, un vdev de paridad única para una carga intensiva de escrituras, o un HBA con firmware roto, la inicialización no te absolverá. Solo te ayudará a descubrir el dolor más temprano, lo cual sigue siendo una victoria.
Una verdad operativa franca: initialize es una quema controlada. Estás gastando I/O ahora para evitar I/O caótico después.
Por qué deberías importarte: el precipicio de latencia
La mayoría de los incidentes de rendimiento en almacenamiento no son sobre throughput. Son sobre latencia en la cola alta: percentiles 99 y 99.9. Las bases de datos no se caen porque las escrituras medias sean 1 ms; se caen porque una pequeña fracción llega a 200 ms, se acumula y convierte tu profundidad de cola en un atasco de tráfico.
He aquí el patrón clásico en un pool recién creado:
- Haces pruebas con
fioen un pool vacío: latencia impresionante y estable. - Pones en producción: sigue bien por un tiempo, porque estás escribiendo secuencialmente en espacio fresco.
- Cruzas algún umbral: la asignación se dispersa, el churn de metadatos aumenta y el dispositivo inicia recolección de basura interna o remapeo shingled.
- Aparecen picos de latencia al azar, y no puedes reproducirlos fácilmente en laboratorio porque tu pool de laboratorio siempre está “demasiado vacío” o “demasiado nuevo”.
Initialize reduce la cantidad de eventos de “la primera vez que hemos tocado esta región”. No es una bala de plata, pero es una de las pocas herramientas que te permite provocar problemas de rendimiento en el momento que tú decidas.
Broma #1: Los SSDs nuevos benchmarkean como becarios—rápidos, entusiastas y completamente no probados bajo presión real.
La versión operativa de “estado estable”
Los ingenieros suelen decir “estado estable” como si fuera un concepto matemático ordenado. En producción, significa: el pool ha vivido suficientes escrituras, TRIMs, sobreescrituras y churn de metadatos como para dejar de cambiar de personalidad cada semana. Initialize te ayuda a llegar allí antes de que tus clientes lo hagan por ti.
Si administras pools ZFS grandes para bases de datos, flotas de VM, almacenes de objetos o plataformas de logs, te importa la predictibilidad. La inicialización trata de predictibilidad.
Datos interesantes y un poco de historia
El almacenamiento es una discusión de larga duración entre la física y el marketing. Algunos puntos de contexto ayudan a explicar por qué zpool initialize existe y por qué importa.
- ZFS fue diseñado para tratar los discos como poco fiables. Checksumming de extremo a extremo y auto-reparación son funciones centrales, no añadidos.
- “Scrub” precede a “initialize” como hábito operativo. El scrubbing surgió de la necesidad de detectar proactivamente errores latentes de sectores antes de que falle un segundo disco.
- El rendimiento de SSD es famosamente distinto “nuevo” vs “usado”. Muchos controladores frontan rendimiento escribiendo en capas de traducción de flash vacías; después pagas el coste de la limpieza interna.
- TRIM/UNMAP cambió la historia. Antes del soporte generalizado de TRIM, los SSD podían ensuciarse y permanecer sucios; ahora el host puede decirle al disco qué bloques están libres, pero el comportamiento aún varía.
- El dolor de reconstrucción RAID moldeó las operaciones modernas. Largos resilvers y ventanas de reconstrucción se convirtieron en un riesgo de fiabilidad al aumentar el tamaño de discos. Initialize no acorta resilver directamente, pero te ayuda a observar el comportamiento del vdev temprano.
- El firmware moderno de HDD tiene cachés y gestión de zonas complejas. Incluso los discos convencionales pueden tener estrategias de firmware que se comportan distinto en áreas “nunca escritas” frente a áreas “previa-mente escritas”.
- El comportamiento de asignación de ZFS cambia conforme los pools se llenan. La fragmentación y la selección de metaslabs evolucionan; el rendimiento de los primeros momentos no es representativo.
- La portabilidad de OpenZFS cambió detalles de implementación. Características como la inicialización evolucionaron entre plataformas, y el comportamiento/disponibilidad depende de la versión de OpenZFS y la integración con el SO.
Una idea para llevar en la cabeza, parafraseando a John Ousterhout (Stanford, ingeniero de sistemas): idea parafraseada: los problemas de rendimiento vienen de lo que no mediste, no de lo que mediste.
Initialize es una manera de medir el futuro ahora.
Cuándo ejecutar initialize (y cuándo no)
Ejecuta cuando
- Pool nuevo, carga real próximamente. Especialmente si la latencia importa y el pool se llenará rápido.
- Después de reemplazar discos en un vdev, cuando quieres que el medio de reemplazo se “caliente” a lo largo de su espacio antes de horas pico.
- Tras cambios de hardware (nuevo HBA, actualización de firmware) cuando quieres detectar timeouts extraños y rutas lentas temprano.
- Antes de un corte de migración. Quieres comportamiento predecible durante los primeros días de producción, no tormentas de GC sorpresa.
Sé cauteloso o evítalo cuando
- Ya estás limitado en IOPS por capacidad. La inicialización añade carga de escritura. En pools ocupados puede amplificar el dolor.
- Lo haces “solo porque sí”. Si no puedes explicar el modo de fallo que previenes, lo ejecutarás en el momento equivocado y culparás a ZFS por hacer exactamente lo que pediste.
- Dependes de márgenes de resistencia de escritura. Initialize escribe mucho. En SSDs de consumidor con resistencia limitada, no es gratis. Decide conscientemente.
Initialize vs alternativas (y por qué sigo prefiriendo initialize)
La gente intenta replicar la inicialización con dd, fio o llenando un dataset con ceros. “Funciona” en el sentido de que escribes el disco, pero suele ser menos controlado y menos integrado con ZFS. Initialize es consciente del pool y pensado para esta tarea.
Dicho esto: la inicialización no reemplaza la planificación. Elige redundancia sensata, configura ashift correctamente, no sobreasignes HBAs y no conectes un pool a un controlador que cree que la recuperación de errores significa “meditar durante 120 segundos”.
Tareas prácticas: comandos, salidas, decisiones
A continuación hay tareas probadas en campo que uso al poner en marcha o estabilizar pools. Cada una tiene: el comando, qué significa una salida típica y qué decisión tomo a partir de ello. Si las haces en orden, evitarás el pánico de “ejecutamos initialize y el pool se volvió lento” porque sabrás qué era “lento” antes de empezar.
Tarea 1: Confirmar OpenZFS y soporte de la característica
cr0x@server:~$ zfs version
zfs-2.2.4-0ubuntu1
zfs-kmod-2.2.4-0ubuntu1
Qué significa: Estás en OpenZFS 2.2.x; la inicialización está soportada en builds modernos de OpenZFS (los detalles por plataforma varían).
Decisión: Si estás en ZFS muy antiguo (o un fork de proveedor), confirma que zpool initialize existe y se comporta como esperas antes de apostar producción a ello.
Tarea 2: Inventario de pools y salud antes de tocar nada
cr0x@server:~$ zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 10.9T 1.23T 9.67T - - 2% 11% 1.00x ONLINE -
Qué significa: El pool está poco usado, baja fragmentación, saludable.
Decisión: Inicializar en un pool mayormente vacío es lo más fácil. En un pool casi lleno o muy fragmentado, programa con cuidado y monitoriza la latencia en la cola alta.
Tarea 3: Obtener topología de vdev y registrar IDs de dispositivo (no solo /dev/sdX)
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:54 with 0 errors on Sun Dec 15 03:10:41 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1234 ONLINE 0 0 0
ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1235 ONLINE 0 0 0
ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1236 ONLINE 0 0 0
ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1237 ONLINE 0 0 0
ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1238 ONLINE 0 0 0
ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1239 ONLINE 0 0 0
errors: No known data errors
Qué significa: Los dispositivos están referenciados por identificadores estables. Bien.
Decisión: Si ves nombres /dev/sdX, arregla eso antes de cualquier mantenimiento. La enumeración de dispositivos cambia con el arranque en Linux por diversión.
Tarea 4: Comprobar ashift indirectamente (tamaños de sector) antes de culpar al rendimiento
cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_tree' -n | head
49: vdev_tree:
68: ashift: 12
Qué significa: ashift=12 implica sectores de 4K. Eso suele ser correcto para discos modernos.
Decisión: Si descubres ashift=9 en dispositivos nativos 4K, arregla el diseño del pool (normalmente reconstruir). Initialize no salvará un desalineamiento.
Tarea 5: Línea base de latencia y throughput antes de initialize
cr0x@server:~$ zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.23T 9.67T 12 85 2.1M 48.3M
raidz2-0 1.23T 9.67T 12 85 2.1M 48.3M
... - - 2 14 350K 8.2M
... - - 2 14 360K 8.1M
---------- ----- ----- ----- ----- ----- -----
Qué significa: Tienes una línea base. No estarás adivinando después.
Decisión: Si las escrituras de base ya están limitadas, programa la inicialización en horas muertas y considera limitar la tasa mediante controles de I/O del sistema (cgroups/ionice) en lugar de esperar que “no sea tan malo”.
Tarea 6: Comprobar trabajo en segundo plano existente (scrub/resilver) antes de comenzar
cr0x@server:~$ zpool status tank | sed -n '1,25p'
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:54 with 0 errors on Sun Dec 15 03:10:41 2025
config:
...
Qué significa: No hay scrub/resilver en curso.
Decisión: No apiles operaciones pesadas en segundo plano. Si hay un resilver en ejecución, tu prioridad es la restauración de redundancia, no el preacondicionamiento.
Tarea 7: Iniciar la inicialización (pool completo)
cr0x@server:~$ sudo zpool initialize tank
Qué significa: El comando retorna rápido; la inicialización se ejecuta de forma asíncrona.
Decisión: Empieza a monitorizar inmediatamente. Si lo “disparas y olvidas”, luego descubrirás que chocó con un job por lotes y culparás a lo equivocado.
Tarea 8: Verificar que la inicialización realmente está en marcha
cr0x@server:~$ zpool status tank | sed -n '1,35p'
pool: tank
state: ONLINE
scan: initialize in progress since Mon Dec 22 10:14:09 2025
1.12T scanned at 5.43G/s, 312G issued at 1.50G/s, 10.9T total
0B initialized, 2.78% done, 02:01:18 to go
config:
...
Qué significa: Ves “initialize in progress” con progreso y ETA. Nota que “scanned” y “issued” son diferentes; issued es la carga de escritura real.
Decisión: Si el progreso está atascado (ETA creciendo, issued cerca de cero), sospecha timeouts de dispositivo, inanición de cola o cargas competidoras.
Tarea 9: Pausar la inicialización cuando la producción esté en llamas
cr0x@server:~$ sudo zpool initialize -s tank
Qué significa: Detiene (suspende) el escaneo de initialize.
Decisión: Usa esto cuando los presupuestos de latencia se estén violando. No “aprietes los dientes” en un sistema caliente; crearás un incidente mayor que el que intentabas prevenir.
Tarea 10: Reanudar la inicialización
cr0x@server:~$ sudo zpool initialize tank
Qué significa: Reanuda desde donde quedó.
Decisión: Reanuda durante ventanas más tranquilas. Si tu carga nunca tiene ventanas tranquilas, eso es un problema de planificación de capacidad, no un problema de ZFS.
Tarea 11: Inicializar solo un vdev específico (preacondicionamiento quirúrgico)
cr0x@server:~$ sudo zpool initialize tank ata-SAMSUNG_MZ7L33T8HBLA-00007_S6Y0NX0W1238
Qué significa: Apunta al vdev hoja nombrado (dependiente de plataforma/versión; la dirección de topología debe coincidir con zpool status).
Decisión: Útil después de reemplazar un solo disco en un mirror/grupo raidz cuando quieres que el recién llegado deje de comportarse como un dispositivo nuevo mientras sus hermanos están “curtidos”.
Tarea 12: Vigilar comportamiento por disco mientras initialize corre
cr0x@server:~$ iostat -x 1 5
Linux 6.8.0-48-generic (server) 12/22/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
3.12 0.00 1.88 6.44 0.00 88.56
Device r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 180.00 0.00 184320.0 2048.0 8.20 45.6 5.1 92.0
sdb 0.00 177.00 0.00 181248.0 2048.0 8.10 46.2 5.2 91.4
Qué significa: Alto %util y await elevado son esperados durante escrituras secuenciales pesadas, pero observa si un disco tiene await dramáticamente peor que sus pares.
Decisión: Si un único disco es el outlier, trátalo como hardware/firmware sospechoso o un problema de path (lane SAS, expander, cable). La inicialización es una gran forma de sacar esto a la luz.
Tarea 13: Confirmar soporte TRIM y si está activado (pools SSD)
cr0x@server:~$ zpool get autotrim tank
NAME PROPERTY VALUE SOURCE
tank autotrim off default
Qué significa: Autotrim está off. Eso no es automáticamente malo, pero es una elección deliberada.
Decisión: Para muchos pools SSD, habilitar autotrim ayuda al rendimiento en estado estable a largo plazo. Si lo activas, monitoriza por cualquier rareza de firmware y regresión de rendimiento en tu entorno.
Tarea 14: Activar autotrim (si decides que es correcto)
cr0x@server:~$ sudo zpool set autotrim=on tank
Qué significa: ZFS emitirá TRIMs para bloques liberados (los detalles de implementación varían por SO y versión de OpenZFS).
Decisión: Haz esto cuando confíes en el firmware de tus SSDs y quieras rendimiento consistente a largo plazo. Si tus SSDs son conocidos por portarse mal con TRIM bajo carga, mantenlo desactivado y confía en trims manuales periódicos en ventanas de mantenimiento.
Tarea 15: Monitorizar indicadores de latencia de ZFS vía zpool iostat
cr0x@server:~$ zpool iostat -l -v tank 1 3
operations bandwidth
pool read write read write
--------------------------- ----- ----- ----- -----
tank 10 950 1.2M 1.10G
raidz2-0 10 950 1.2M 1.10G
ata-...1234 2 160 120K 190M
ata-...1235 2 158 110K 188M
--------------------------- ----- ----- ----- -----
Qué significa: Ancho de banda de escritura pesado consistente con initialize. Si las lecturas siguen bajas y la latencia de la aplicación sufre, puede que estés saturando las mismas colas usadas para I/O de primer plano.
Decisión: Si las lecturas de primer plano se están quedando sin recursos, detén o reprograma initialize. “Pero la inicialización es secuencial” no garantiza que no afecte la latencia de lecturas aleatorias.
Tarea 16: Validar contadores de errores durante initialize
cr0x@server:~$ zpool status -v tank | sed -n '1,80p'
pool: tank
state: ONLINE
scan: initialize in progress since Mon Dec 22 10:14:09 2025
6.02T scanned at 4.91G/s, 1.88T issued at 1.53G/s, 10.9T total
0B initialized, 17.2% done, 01:38:02 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-...1234 ONLINE 0 0 0
ata-...1235 ONLINE 0 0 0
ata-...1236 ONLINE 0 0 0
ata-...1237 ONLINE 0 0 0
ata-...1238 ONLINE 0 0 0
ata-...1239 ONLINE 0 0 0
errors: No known data errors
Qué significa: No hay errores de lectura/escritura/checksum mientras se golpean los discos. Eso es exactamente lo que quieres conocer temprano.
Decisión: Cualquier contador de errores que aumente durante initialize es un regalo. Trátalo como una advertencia temprana y comienza a aislar rutas de hardware antes de confiar datos a ellas.
Tarea 17: Correlacionar logs del kernel por resets/timeouts
cr0x@server:~$ sudo dmesg -T | tail -n 12
[Mon Dec 22 10:41:02 2025] sd 2:0:12:0: [sdl] tag#8121 FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_OK
[Mon Dec 22 10:41:02 2025] sd 2:0:12:0: [sdl] tag#8121 CDB: Write(16) 8a 00 00 00 00 1a 5f 2b 40 00 00 02 00 00 00
[Mon Dec 22 10:41:03 2025] blk_update_request: I/O error, dev sdl, sector 442446848 op 0x1:(WRITE) flags 0x0 phys_seg 32 prio class 0
Qué significa: El kernel está viendo timeouts y errores de escritura en un dispositivo. ZFS puede reintentar; tu aplicación verá picos de latencia; tus ventanas de resilver se convertirán en pesadillas.
Decisión: Detén initialize, investiga cableado/HBA/expander/firmware del disco y ejecuta SMART y diagnósticos de enlace dirigidos. No sigas escribiendo esperando que el problema “se queme”. Así terminas con una noche de viernes desagradable.
Tarea 18: Comprobar SMART y registros de error (ejemplo SATA)
cr0x@server:~$ sudo smartctl -a /dev/sdl | sed -n '1,40p'
smartctl 7.4 2023-08-01 r5530 [x86_64-linux-6.8.0-48-generic] (local build)
=== START OF INFORMATION SECTION ===
Device Model: SAMSUNG MZ7L33T8HBLA-00007
Serial Number: S6Y0NX0W1238
Firmware Version: EDA7202Q
User Capacity: 3,840,755,982,336 bytes [3.84 TB]
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
...
Qué significa: Puedes confirmar versión de firmware y salud básica. Lo interesante suele estar en el log de errores e indicadores de desgaste más abajo.
Decisión: Si el firmware es problemático en tu flota, estandariza. Mezclar firmware en un vdev es una forma sutil de crear dolores sutiles.
Tarea 19: Observar espacio del pool y fragmentación mientras se llena (initialize no arregla esto)
cr0x@server:~$ zpool list -o name,size,alloc,free,cap,frag,health tank
NAME SIZE ALLOC FREE CAP FRAG HEALTH
tank 10.9T 1.23T 9.67T 11% 2% ONLINE
Qué significa: Baja fragmentación y bajo uso de capacidad. Tienes margen.
Decisión: Si operas rutinariamente por encima de ~80% de capacidad en pools activos, tu verdadero problema de rendimiento es que te quedas sin espacio contiguo y las metaslabs se vuelven más restringidas. Initialize no cambiará eso.
Guion rápido de diagnóstico
Ejecutaste zpool initialize (o heredaste un sistema donde está en ejecución), y la latencia es mala. Necesitas responder una pregunta rápido: ¿es la inicialización el cuello de botella, o solo está exponiendo un eslabón débil?
Primero: confirma qué trabajo en segundo plano está activo
- Ejecuta
zpool status. Si vesinitialize in progress, has encontrado una fuente mayor de carga de escritura. - Comprueba si hay un scrub o resilver también en ejecución. Si sí, detén el menos crítico.
cr0x@server:~$ zpool status -x
all pools are healthy
Decisión: Salud no es rendimiento. “ONLINE” solo significa que no hay corrupción conocida o fallo de dispositivo ahora. Continúa.
Segundo: determina si el cuello de botella es un solo disco/ruta o todo el vdev
- Usa
iostat -xozpool iostat -vy busca un dispositivo conawaitmucho peor o throughput mucho más bajo. - Si un dispositivo es lento, arrastra al vdev. RAIDZ y mirrors pagan por el miembro más lento de formas distintas.
Tercero: comprueba logs del kernel por resets/timeouts
- Los time-outs en
dmesgsuelen ser los verdaderos culpables. Initialize solo aumenta la probabilidad de verlos. - Las tormentas de resets suelen correlacionar con una ranura específica, cable, puerto de expander o problema de alimentación.
Cuarto: verifica que no estés simplemente saturando colas
- Si todos los discos muestran alta utilización y sin errores, puede que estés alcanzando límites de ancho de banda/IOPS.
- Detén o suspende initialize, confirma que la latencia se recupera y luego prográmalo en horas de menor actividad.
Quinto: sanity-check de decisiones de diseño del pool
ashiftincorrecto causa dolor permanente y estructural.- Desajustes de recordsize/volblocksize no romperán initialize, pero pueden crear conclusiones de rendimiento engañosas.
- Operar con altos porcentajes de llenado empeora todo, siempre.
Este guion no es glamoroso, pero es rápido. Estás intentando decidir si pausar initialize, cambiar hardware, o aceptar que estás viendo al sistema hacer exactamente tanto I/O como puede.
Tres mini-historias corporativas desde la trinchera
1) El incidente causado por una suposición equivocada
La compañía tenía un plan de migración limpio: pool ZFS nuevo en SSDs, replicar datasets, cortar en un domingo tranquilo. Hicieron un benchmark rápido el sábado y celebraron los resultados. Los números parecían heroicos—especialmente en un pool vacío. Asumieron que “SSD nuevo + ZFS” significaba que la primera semana sería la más fácil.
Omitieron la inicialización porque no estaba en el runbook, y porque “no queremos desgastar los discos”. Esa línea siempre suena sensata hasta que te das cuenta de que la carga escribirá esos bytes de todos modos—solo que en momentos aleatorios, durante horas laborales, con clientes mirando.
Lunes por la mañana: picos de latencia en VMs. No continuos, no predecibles. Lo suficientemente agudos como para que algunos servicios entraran en tormentas de reintentos. Todos persiguieron la red primero (porque siempre se persigue la red primero), luego la programación del hipervisor, luego la base de datos. Los gráficos de almacenamiento mostraban utilización media bien por debajo del máximo, lo que lo hacía más confuso. No era un problema de throughput.
Cuando finalmente correlacionaron los picos con la amplificación de escrituras dentro de los SSDs—visible a través de métricas de latencia a nivel de dispositivo—el patrón quedó obvio: las primeras escrituras aterrizaban en bloques “fáciles” y libres. A medida que la asignación se expandió y la limpieza interna del SSD entró en acción, la latencia en cola saltó. Básicamente hicieron “initialize en producción”, un estallido caótico a la vez.
Pausaron jobs intensivos en escritura, ejecutaron zpool initialize por las noches durante una semana y los picos de latencia se calmaron. La lección duradera no fue “siempre inicializar”. Fue: no hagas benchmarking en vacío. Vacío es un entorno de demo, no una carga real.
2) La optimización que salió mal
Otra organización tenía la costumbre de “optimizar” todo. Leyeron que la inicialización son escrituras secuenciales y asumieron que sería inofensiva si la limitaban. Así que ejecutaron initialize durante horas laborales en un clúster de almacenamiento compartido, esperando que la planificación de I/O de fondo la mantuviera educada.
Para ser extra cuidadosos, también lanzaron un scrub “para asegurarse de que todo esté bien”. En teoría sonaba como higiene: initialize calienta, scrub valida, todos duermen tranquilos. En la realidad apilaron dos escaneos grandes que compiten por I/O y caché, mientras la I/O de aplicaciones ya era no trivial.
El resultado fue un incidente a cámara lenta. Nada falló rotundamente. Ninguna luz roja obvia. Pero las latencias p99 se duplicaron, luego se triplicaron. El SRE de guardia no vio un solo humo evidente. CPU bien. Red bien. Pool “ONLINE”. Los usuarios no estaban bien.
El contragolpe fue sutil: la carga de fondo combinada hizo que el sistema pasara más tiempo en colas y menos tiempo haciendo trabajo útil. Peor, las apps respondieron aumentando paralelismo y reintentos, lo que generó más I/O aleatorio y empeoró la eficiencia de los escaneos. Bucle de retroalimentación clásico.
Lo arreglaron siendo aburridos: nunca ejecutar initialize y scrub juntos, y nunca asumir que “I/O de fondo secuencial” es automáticamente inofensivo. Además añadieron un panel simple: “¿Algún pool está haciendo un scan?” Previno futuras “optimizaciónes útiles”.
3) La práctica aburrida pero correcta que salvó el día
Un equipo fintech usaba ZFS para una plataforma con muchos logs. Su cultura era agresivamente poco romántica: todo tenía un runbook, y cada runbook tenía “prechecks”. No porque amaran papeleo. Porque odiaban sorpresas.
Cuando desplegaron una nueva estantería de SSDs, el runbook requería: registrar IDs de dispositivo, confirmar uniformidad de firmware, baselinar zpool iostat, ejecutar initialize durante una ventana programada y vigilar logs del kernel por resets. La ventana de initialize era larga y aburrida. El ingeniero de guardia la rotaba como ver secar pintura, excepto que la pintura no te manda páginas.
A mitad de la inicialización, un disco empezó a lanzar timeouts intermitentes. No suficientes para fallar inmediatamente, pero sí para aparecer en dmesg y como picos ocasionales de latencia en iostat. Detuvieron initialize, reemplazaron el disco y reiniciaron. El proveedor luego confirmó un problema de firmware afectando a un subconjunto de esa remesa.
Si no hubieran inicializado, ese disco podría haber seguido funcionando mal durante semanas hasta que un día de tráfico pico lo forzara al modo de fallo. La práctica “aburrida” no los hizo más rápidos; los hizo menos sorprendidos. Esa es la mejor moneda.
Broma #2: El mejor incidente de almacenamiento es el que solo experimentas como una invitación en el calendario.
Errores comunes: síntomas → causa raíz → solución
1) Síntoma: “Initialize dejó mi pool lento”
Causa raíz: Initialize es I/O de escritura sostenido y compite con tráfico de primer plano; tu sistema no tenía margen de IOPS.
Solución: Suspende initialize durante el pico (zpool initialize -s), programa en horas muertas y haz líneas base antes/después para poder probar causalidad.
2) Síntoma: Progreso atascado en un porcentaje, ETA sigue creciendo
Causa raíz: Un dispositivo está haciendo timeouts o la ruta de I/O es inestable; ZFS está reintentando o esperando comandos lentos.
Solución: Revisa dmesg por resets/timeouts, ejecuta SMART, verifica cableado/firmware del HBA y considera aislar el disco sospechoso.
3) Síntoma: Un disco está al 100% de util; otros están tranquilos
Causa raíz: Disco defectuoso, problema de negociación de enlace o un dispositivo en un vdev RAIDZ que arrastra al grupo por su latencia pobre.
Solución: Compara await y throughput por disco. Cambia la ranura/cable. Si el problema sigue con el disco, reemplázalo. Si se queda con la ranura, arregla la ruta.
4) Síntoma: Inicialización termina, pero la carga aún tiene gran latencia en cola
Causa raíz: No era un problema de “disco nuevo”. Probablemente el pool está demasiado lleno, diseño de vdev erróneo, ashift inadecuado o la carga es muy sincrónica sin SLOG apropiado.
Solución: Revisa capacidad del pool (zpool list), fragmentación y settings de datasets; evalúa la redundancia y añade vdevs o rediseña si es necesario.
5) Síntoma: Pool muestra errores durante initialize
Causa raíz: Initialize está exponiendo hardware marginal. Es una buena noticia entregada bruscamente.
Solución: Trátalo como un evento pre-fallo: recoge logs, reemplaza el componente y vuelve a ejecutar initialize en el medio de reemplazo.
6) Síntoma: Ejecutaste initialize esperando que “verifique” el pool
Causa raíz: Confusión con scrub. Initialize escribe; scrub verifica checksums existentes.
Solución: Usa zpool scrub para validación de integridad. Usa initialize para preacondicionamiento. No las confundas.
7) Síntoma: Rendimiento empeoró tras habilitar autotrim junto con initialize
Causa raíz: El firmware/ruta no aguanta escrituras sostenidas concurrentes más la carga de TRIM, o la implementación provoca trabajo de fondo adicional en el momento equivocado.
Solución: No introduzcas dos variables grandes a la vez. Estabiliza primero: ejecuta initialize con autotrim sin cambios, luego evalúa autotrim por separado con monitorización.
8) Síntoma: Inicializaste un pool durante resilver y ahora todo está en llamas
Causa raíz: Apilaste dos operaciones I/O-intensivas y sensibles a latencia. Resilver necesita terminar; la redundancia está en riesgo.
Solución: Para initialize. Deja que resilver finalice. Luego inicializa en un momento más calmado, opcionalmente solo el dispositivo reemplazado.
Listas de verificación / plan paso a paso
Lista A: Puesta en marcha de un pool nuevo con inicialización (mentalidad productiva)
- Registrar entorno: Versión de ZFS, kernel del SO, modelo/firmware del HBA. Consistencia vence a la astucia.
- Construir pool con IDs de dispositivo estables (WWN/ATA IDs). Nunca confíes en
/dev/sdX. - Verificar topología con
zpool statusy confirmar que la redundancia coincide con la carga. - Confirmar
ashiftusandozdb -C. Si está mal, detente y reconstruye ahora. Tu futuro yo no lo arreglará después. - Baselinar rendimiento con
zpool iostatyiostat -xa nivel de dispositivo en carga ligera. - Comprobar errores en
dmesgantes de empezar. Si el kernel ya se queja, initialize convertirá quejas en outages. - Iniciar initialize y monitorizar inmediatamente el progreso vía
zpool status. - Vigilar métricas por disco para outliers. Un outlier es un problema de hardware hasta demostrar lo contrario.
- Parar ante errores e investigar. No normalices fallos de hardware con “solo es inicialización”.
- Tras la finalización, repite las líneas base y registra los números de estado estable. Esto será tu referencia “conocida buena”.
Lista B: Después de reemplazar un disco en un vdev existente
- Deja que el resilver termine. Verifica que
zpool statusesté limpio. - Ejecuta
smartctl -aen el disco nuevo y confirma que el firmware coincide con el estándar de la flota. - Inicializa solo el dispositivo nuevo (si tu entorno lo soporta) para preacondicionarlo.
- Monitoriza
dmesgpor resets/timeouts; a menudo son problemas de ranura/path revelados por escrituras sostenidas. - Documenta lo que cambió (serial, ranura, firmware). Cuando ocurra el siguiente incidente, querrás correlacionar.
Lista C: Operar en un pool ocupado (no seas héroe)
- Decide el objetivo: reducir picos futuros de latencia, o validar estabilidad de hardware? Si ninguno, no lo ejecutes.
- Elige una ventana: tráfico bajo, poca actividad de jobs por lotes.
- Fija expectativas: publica que la carga de escritura en segundo plano aumentará y que la latencia puede subir.
- Inicia initialize y vigila los dashboards de p99 de latencia.
- Tener una condición de parada: si la latencia supera un umbral, suspende initialize. Sé disciplinado.
- Reanuda después. Completar es agradable; impacto controlado es mejor.
Preguntas frecuentes
1) ¿zpool initialize borra datos?
Está diseñado para ser seguro en un pool en uso, pero escribe a lo largo del vdev. Debes tratarlo como una operación de escritura en segundo plano intensiva, no como un borrado destructivo. Aun así: no lo ejecutes en un pool que no puedas permitirte estresar sin monitorización y posibilidad de revertir.
2) ¿Initialize es lo mismo que “burn-in” para discos?
Relacionado, no idéntico. El burn-in suele incluir tests SMART largos, patrones de lectura/escritura, ciclos de temperatura y monitorización fuera de ZFS. Initialize está integrado en ZFS como preacondicionamiento. Haz ambos si te importa la fiabilidad.
3) ¿Debo inicializar pools HDD también?
A veces. Los HDD no tienen capas de traducción de flash, pero el firmware moderno aún puede comportarse distinto en regiones intactas. Más importante, initialize es una buena forma de exponer discos marginales o enlaces defectuosos con I/O sostenido. Si tu pool ya está ocupado y estable, el beneficio puede no justificar la carga.
4) ¿Cuánto tarda la inicialización?
A grandes rasgos: tamaño del pool dividido por el ancho de banda de escritura sostenido que puedas permitirte. La paridad RAIDZ, límites del controlador y cargas competidoras importan. Confía en zpool status para estimaciones en vivo, pero recuerda que la ETA es una conjetura bajo contención.
5) ¿Debo ejecutar scrub después de initialize?
No automáticamente. Scrub verifica bloques existentes y repara mediante redundancia. Tras la construcción de un pool nuevo, un scrub no es mala idea como comprobación de cordura, pero no apiles scrub e initialize simultáneamente. Espárcalos.
6) ¿Initialize ayuda con tiempos de resilver futuros?
No directamente. El tiempo de resilver depende de datos asignados, rendimiento del vdev y carga del sistema. Initialize puede revelar discos/rutas débiles temprano y reducir sorpresas de rendimiento, lo que indirectamente ayuda a sobrevivir resilvers sin drama.
7) Si mi carga es mayormente lecturas—¿aún necesito initialize?
Si realmente es lectura-mayoritariamente y no llenas el pool rápido, initialize tiene menos valor. Pero si te importa el rendimiento predecible bajo escrituras ocasionales intensivas (reconstrucciones, jobs por lotes, ráfagas de logs), puede seguir valiendo la pena.
8) ¿Initialize reemplaza a TRIM?
No. Initialize escribe; TRIM informa al dispositivo qué bloques están libres. Abordan mecanismos diferentes. En pools SSD, a menudo quieres ambos: initialize para preacondicionar y TRIM (autotrim o periódico) para mantener comportamiento en estado estable.
9) ¿Puedo limitar la velocidad de la inicialización?
ZFS no ofrece un control universal único de “velocidad de initialize” en todos los entornos. Prácticamente, gestionas el impacto mediante programación, suspensión/reanudación y control de prioridad I/O a nivel sistema (cuando esté soportado). La mejor limitación es “no lo ejecutes a mediodía”.
10) ¿Cómo sé que la inicialización tuvo éxito?
zpool status mostrará que initialize completó. Más importante: deberías ver: no nuevos errores de dispositivo, latencia de dispositivo estable y menos “picos misteriosos” cuando el pool empiece a llenarse.
Conclusión: próximos pasos que no te morderán después
Si estás construyendo nuevos pools ZFS sobre medios modernos, trata zpool initialize como tratas los simulacros de incendio: inconveniente, controlado y muchísimo preferible al incidente real. Ejecútalo cuando tengas margen, mide antes y después, y toma cualquier error como una señal seria—no ruido.
Próximos pasos prácticos:
- Elige un pool no crítico y añade initialize al runbook de construcción, incluyendo condiciones explícitas de parada.
- Estandariza el nombrado de dispositivos (WWN/ATA IDs) y líneas base de firmware para que los diagnósticos no se conviertan en arqueología.
- Construye un pequeño panel de control: scans ZFS actuales (scrub/resilver/initialize), latencia por disco y tasas de errores del kernel.
- Toma una decisión de política: cuándo ejecutar initialize (pool nuevo, después de reemplazos, antes de migraciones) y cuándo no.
Los discos nuevos siempre intentarán impresionarte. Tu trabajo es hacer que se comporten cuando nadie los esté mirando.