Los problemas de desalineación son de esos que vuelven supersticiosos a los SRE. Los gráficos parecen encantados: picos de latencia cuando nada cambió, IOPS que se niegan a escalar, SSD que rinden como HDD en pruebas sintéticas. Y entonces lo encuentras: ashift está mal, y el pool ha estado haciendo trabajo extra en cada escritura desde el primer día.
Esto no es un artículo de “lee la página del manual”. Es la guía de campo que desearías haber tenido antes de crear ese pool: qué controla realmente ashift, por qué es persistente, cómo demostrar que te está perjudicando y las maneras menos peligrosas de recuperar un rendimiento sensato en producción.
Qué es ashift (y qué no es)
ashift es la forma que tiene ZFS de decir: “Cuando aloco bloques en disco, trataré el tamaño mínimo de escritura del dispositivo como 2^ashift bytes.” Si ashift=12, ZFS asigna en sectores de 4096 bytes. Si ashift=9, asigna en sectores de 512 bytes. Esa única decisión determina si muchas de tus escrituras son limpias, operaciones de E/S únicas —o ciclos costosos de lectura-modificación-escritura que convierten cargas de escritura aleatoria pequeñas en un puré de latencias.
La ashiftness no es una perilla de ajuste que puedas cambiar cualquier martes por la tarde. Se establece al crear el vdev y está efectivamente integrada en cómo el pool organiza los bloques. A veces puedes reemplazar un vdev por uno nuevo con diferente ashift durante una migración/reconstrucción, pero no puedes “dar la vuelta al ashift” en el sitio y hacer que los bloques existentes se realineen mágicamente. ZFS es potente; no es una máquina del tiempo.
Lo que controla ashift
- Unidad mínima de asignación en cada vdev: el “tamaño de sector” que ZFS asume para ese dispositivo.
- Alineación de las escrituras de ZFS a límites amigables para el dispositivo.
- Riesgo de amplificación para escrituras pequeñas: un ashift incorrecto puede forzar más E/S de las esperadas.
Lo que no controla ashift
- Tamaño de bloque del dataset (eso es
recordsizepara sistemas de archivos yvolblocksizepara zvols). - Compresión, checksum o las matemáticas de paridad de RAIDZ.
- La velocidad de tu CPU—aunque los errores de ashift pueden ser tan malos que parecen problemas de CPU porque todo espera a E/S.
Una matización importante más: ashift es por vdev, no “por pool” en algún sentido abstracto. Cuando dices “mi pool tiene ashift 12”, lo que usualmente quieres decir es “todos los vdevs del pool tienen ashift=12.” Pueden existir vdevs con ashift mezclado, y rara vez es una fiesta que quieras organizar.
Primer chiste (mantenerlo corto): Lo bueno de ashift es que es una decisión única. Lo malo de ashift es que es una decisión única.
Por qué un ashift incorrecto duele tanto
El precipicio de rendimiento viene de cómo los dispositivos realmente escriben datos. Muchos discos y SSD exponen sectores lógicos de 512 bytes por compatibilidad, pero su unidad interna de escritura “física” es de 4K (o mayor). Si ZFS cree que puede escribir fragmentos de 512B (ashift=9) en un dispositivo que en realidad quiere escrituras de 4K, el dispositivo puede tener que realizar un ciclo de lectura-modificación-escritura (RMW):
- Leer el bloque físico completo de 4K en la caché interna
- Modificar la porción de 512B que cambió
- Escribir de nuevo el bloque completo de 4K
Son tres operaciones donde esperabas una. Y como esas operaciones se serializan dentro del dispositivo, la cola de latencia se estira aunque la media parezca “bien”. En sistemas reales, no es raro ver una caída de ~2× en el rendimiento o mucho peor en escrituras aleatorias pequeñas, además de un aumento dramático en la latencia p99.
Por qué “mitad del rendimiento” no es exageración
Cuando ashift es demasiado pequeño, ZFS emitirá escrituras más pequeñas. Los dispositivos que no pueden escribir esos tamaños de forma nativa pagan un impuesto RMW. Si tu carga de trabajo es:
- intensa en sincronización (bases de datos, NFS con sync, virtualización con barreras de escritura),
- escrituras aleatorias de bloques pequeños (metadatos de VM, WAL/redo logs de BD, journaling),
- o RAIDZ encima de desalineación (paridad + RMW es un tipo especial de dolor),
ese impuesto aparece como profundidad de cola, luego como latencia, y luego como “¿por qué nuestro servicio empezó a agotar tiempos?”
Ashift demasiado grande: la compensación más silenciosa
Existe el error opuesto: elegir un ashift mayor del necesario, como ashift=13 (8K) en un dispositivo 4K real. Esto generalmente no mata el rendimiento; “solo” aumenta el overhead de espacio y puede reducir la eficiencia para bloques muy pequeños. Operacionalmente suele ser la dirección más segura: espacio desperdiciado es molesto, pero la latencia impredecible es lo que hace que te llamen a altas horas.
Segundo chiste: Si pones mal el ashift, ZFS no se enfadará—simplemente se pondrá lento. Es como el sistema de archivos más pasivo-agresivo posible.
Hechos y contexto histórico que vale la pena conocer
Esto no es trivia por la trivia. Explica por qué ashift sigue siendo una trampa en 2025.
- Los sectores de 512 bytes dominaron durante décadas, porque los primeros controladores de disco, sistemas de archivos y firmware se estandarizaron en torno a ello. La inercia de compatibilidad es real.
- Los discos “Advanced Format” (4K) se volvieron mainstream para reducir overhead y aumentar la eficiencia de capacidad; muchos aún presentan 512e (emulación de 512 bytes) al SO.
- Algunos dispositivos mienten—a propósito. Reportan sectores lógicos de 512 aun cuando su tamaño interno de programa/borrado es 4K o mayor, porque ciertos SO y bootloaders históricamente asumían 512.
- ZFS se diseñó priorizando la integridad de datos; el asignador y el modelo de transacciones asumen que la alineación importa, pero no siempre pueden confiar en los reportes del disco.
- Ashift se volvió “pegajoso” por diseño. Permitir que el tamaño de sector cambie bajo un pool en vivo arriesgaría corromper supuestos sobre el layout en disco.
- Los SSD introdujeron nuevas “realidades físicas”: las páginas NAND y los bloques de borrado no encajan limpiamente con 512 o 4K, pero la alineación a 4K sigue siendo una base sólida para evitar amplificación de escritura.
- RAIDZ hace la alineación más sensible. Los cálculos de paridad y el ancho de la franja interactúan con los límites de sector; la desalineación puede multiplicar el dolor.
- La virtualización añadió otra capa de engaño: un disco virtual puede reportar sectores de 512 mientras el almacenamiento subyacente es 4K-native; ashift debe coincidir con el nivel físico real.
- En los primeros días de adopción de OpenZFS en Linux, muchos administradores migraron desde hábitos de ext4/mdadm y trataron ZFS como “otra capa RAID”, ignorando ashift por completo.
Tres micro-historias del mundo corporativo
Micro-historia #1: Un incidente causado por una suposición errónea
Empezó como una renovación rutinaria de la plataforma: nuevos hosts hypervisor, nuevos “enterprise SSDs” y un nuevo pool ZFS para servir almacenamiento de VM. El equipo hizo lo que los equipos hacen bajo presión: copiaron el comando zpool create del año anterior desde una wiki, lo ejecutaron, vieron el pool en línea y siguieron. Nadie miró ashift porque “los SSD son rápidos”.
Dos semanas después, el volumen de tickets subió: lentitud intermitente en una API orientada al cliente. Los gráficos eran confusos. CPU bien. Red bien. Los nodos de base de datos parecían aburridos. Pero la plataforma de VM mostraba picos en la latencia de almacenamiento—ráfagas cortas, justo lo suficiente para provocar timeouts.
El primer on-call pensó en vecinos ruidosos. El segundo sospechó un SSD fallando. El tercero hizo algo poco glamuroso: comparó las propiedades ZFS del clúster nuevo con las del viejo. Ahí saltó: el pool viejo tenía ashift=12. El nuevo era ashift=9.
Los discos declaraban sectores lógicos de 512, así que ZFS “amablemente” eligió alineación de 512 bytes. Bajo una carga VM de escrituras aleatorias, esos “enterprise SSDs” estaban haciendo ciclos RMW internos. El incidente no fue un fallo catastrófico único; fue muerte por latencia de cola. La solución no fue rápida: no podían cambiar ashift en el sitio. Construyeron un pool nuevo con ashift=12, migraron VMs en vivo donde fue posible, migraron en frío el resto, y aprendieron a confiar pero verificar los reportes de hardware.
¿Qué cambiaron después? Su checklist de construcción ganó un nuevo punto: “Registrar ashift por vdev antes de poner datos.” Fue aburrido. También evitó que esta clase de incidente se repitiera.
Micro-historia #2: Una optimización que salió mal
Otra organización tuvo un problema de rendimiento, y hicieron lo que hacen las organizaciones que persiguen rendimiento: optimizar. Habían leído que sectores más grandes pueden ser buenos, así que decidieron estandarizar en ashift=13 (8K) “para coincidir con los internals de SSD modernos.” Reconstruyeron un pool, se sintieron orgullosos y lo pusieron en producción para una carga mixta: archivos de configuración pequeños, capas de contenedor y un sistema CI con mucho metadata y chatty.
Los benchmarks iniciales parecían bien—porque su prueba era en su mayoría rendimiento secuencial. Luego el sistema CI empezó a ralentizarse. La queja no era velocidad bruta; era amplificación: muchos archivos pequeños y escrituras pequeñas significaban que ZFS estaba asignando en chunks mínimos de 8K. El uso de espacio subió más de lo esperado, los snapshots crecían agresivamente y el pool alcanzó alarmas de capacidad antes de lo previsto.
Ahora la parte divertida: la presión de capacidad cambia el comportamiento. El espacio libre disminuye, los metaslabs se fragmentan, la asignación se vuelve más cara, y el sistema que “rindió mejor en benchmarks” empezó a sentirse peor bajo carga real. Su optimización no causó problemas de corrección, pero convirtió un proyecto de rendimiento en uno de gestión de capacidad. Así es como terminas en reuniones con finanzas, lo cual rara vez mejora la latencia.
No eliminaron ashift=13 por completo. Aprendieron a aplicarlo intencionalmente: datasets de bloque grande, ciertos targets de backup y tipos de vdev específicos donde el tradeoff tenía sentido. Para pools de propósito general, volvieron a la línea base aburrida: ashift=12 en dispositivos clase 4K.
Micro-historia #3: Una práctica aburrida pero correcta que salvó el día
Un equipo de almacenamiento con el que trabajé tenía una costumbre que parecía paranoia: cada vez que aprovisionaban discos nuevos, ejecutaban un pequeño script de “comprobación de la verdad” antes de construir pools. Recogía tamaños de sector con lsblk, consultaba la topología HBA y guardaba resúmenes de smartctl en el ticket. También forzaban ashift=12 salvo que tuvieran una razón sólida para no hacerlo.
Un día, procurement cambió un modelo de disco por restricciones de la cadena de suministro. Mismo fabricante, misma capacidad, mismas afirmaciones comerciales. Pero el lote de reemplazo se comportó diferente: exponía sectores lógicos de 512 y “amablemente” enmascaraba su comportamiento físico 4K. El SO estaba feliz de cualquier manera.
La comprobación de la verdad señaló la inconsistencia respecto a lotes anteriores. El equipo no se puso en pánico; simplemente hizo lo que decía el checklist: crear un pequeño pool de prueba, confirmar la selección de ashift y benchmarkear escrituras aleatorias sincronizadas. Los números olían a desalineación.
Forzaron ashift=12 durante la creación, repitieron las pruebas y el rendimiento encajó. Sin incidente. Sin impacto al cliente. Solo una orden de cambio con pruebas adjuntas. Ese es el tipo de “aburrido” que hace que los sistemas sean fiables.
Tareas prácticas: comandos + interpretación (12+)
Todas las tareas abajo asumen OpenZFS en Linux salvo indicación, pero la mayoría de comandos se aplican de forma similar en illumos/FreeBSD con pequeñas diferencias de ruta. Úsalos como un kit de herramientas: verifica ashift, detecta síntomas de desalineación y planifica la remediación.
Task 1: Listar valores ashift de los vdev (la verdad sobre el terreno)
cr0x@server:~$ sudo zdb -C tank | sed -n '/vdev_tree/{:a;n;/}/q;p;ba}'
Interpretación: Busca entradas ashift bajo cada leaf vdev. Si ves ashift: 9 en cualquier SSD/HDD moderno de clase 4K, probablemente tienes un problema. Si algunos vdevs muestran 12 y otros 9, tienes inconsistencia que puede complicar expectativas de rendimiento y expansiones futuras.
Task 2: Comprobación rápida de ashift con un one-liner (leaf vdevs)
cr0x@server:~$ sudo zdb -C tank | awk '/path:|ashift:/{printf "%s ",$0} /ashift:/{print ""}'
Interpretación: Imprime rutas de dispositivo junto a ashift. Útil en respuesta a incidentes cuando necesitas respuestas rápidas, no bonitas.
Task 3: Ver qué piensa el SO sobre los tamaños de sector
cr0x@server:~$ lsblk -o NAME,MODEL,SIZE,PHY-SeC,LOG-SeC,ROTA,TYPE
NAME MODEL SIZE PHY-SEC LOG-SEC ROTA TYPE
sda INTEL SSDPE2KX040T 3.7T 4096 512 0 disk
sdb INTEL SSDPE2KX040T 3.7T 4096 512 0 disk
Interpretación: Si PHY-SEC es 4096 y LOG-SEC es 512 (512e), el dispositivo es una trampa clásica para ashift. ZFS podría elegir 9 si confía en el tamaño lógico. Generalmente quieres ashift=12 aquí.
Task 4: Verificar bloques lógicos/físicos reportados por el dispositivo vía sysfs (Linux)
cr0x@server:~$ for d in /sys/block/sd*/queue; do \
dev=$(basename "$(dirname "$d")"); \
printf "%s logical=%s physical=%s\n" \
"$dev" \
"$(cat "$d/logical_block_size")" \
"$(cat "$d/physical_block_size")"; \
done | head
sda logical=512 physical=4096
sdb logical=512 physical=4096
Interpretación: Misma historia que lsblk, pero scriptable y fiable. Captura esto en los logs de construcción; acelera investigaciones futuras.
Task 5: Confirmar topología del pool y detectar tipos de vdev mezclados
cr0x@server:~$ zpool status -v 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
Interpretación: Esto no muestra ashift, pero te dice la forma. RAIDZ + errores de ashift tienden a manifestarse como “por qué la latencia de pequeñas escrituras es terrible.” Los vdevs en espejo son más tolerantes pero aún sufren con ashift incorrecto en SSDs.
Task 6: Comprobar propiedades del dataset que interactúan con síntomas de ashift
cr0x@server:~$ zfs get -o name,property,value -s local,default recordsize,compression,atime,sync tank/vmstore
NAME PROPERTY VALUE
tank/vmstore recordsize 128K
tank/vmstore compression zstd
tank/vmstore atime off
tank/vmstore sync standard
Interpretación: Los problemas de ashift son más visibles en escrituras sincronizadas pequeñas. Si ejecutas imágenes de VM en un dataset filesystem, recordsize quizá no sea el culpable principal, pero afecta la forma de E/S. Para zvols, revisa volblocksize en su lugar.
Task 7: Para almacenamiento respaldado por zvol, comprobar volblocksize (y aceptar el dolor)
cr0x@server:~$ zfs get -o name,property,value volblocksize,compression,sync tank/zvol0
NAME PROPERTY VALUE
tank/zvol0 volblocksize 8K
tank/zvol0 compression zstd
tank/zvol0 sync standard
Interpretación: Si volblocksize es más pequeño que el tamaño de escritura mínimo efectivo del dispositivo, un ashift incorrecto complica el problema. Quieres una alineación limpia en toda la pila.
Task 8: Observar E/S y latencia en tiempo real (nivel ZFS)
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 2.10T 1.50T 250 900 12.0M 85.0M
raidz2-0 2.10T 1.50T 250 900 12.0M 85.0M
sda - - 40 150 2.0M 14.0M
sdb - - 38 145 1.9M 13.8M
...
Interpretación: Si las operaciones de escritura son altas pero el ancho de banda es moderado, probablemente estás en territorio de E/S pequeñas. Ahí es donde ashift incorrecto puede convertir una carga razonable en un molino de latencias.
Task 9: Observar E/S y latencia en tiempo real (nivel dispositivo)
cr0x@server:~$ iostat -x 1 5
Device r/s w/s r_await w_await aqu-sz %util
sda 55.0 220.0 0.70 18.50 3.10 98.0
sdb 52.0 215.0 0.65 19.10 3.05 97.5
Interpretación: Alto w_await con utilización cercana al 100% en SSD durante un ancho de banda modesto es un olor clásico. No prueba que ashift esté mal, pero indica que el dolor está debajo de ZFS, no en la app.
Task 10: Medir comportamiento de escrituras sincronizadas (la carga que expone la desalineación)
cr0x@server:~$ sudo fio --name=sync4k --directory=/tank/test \
--rw=randwrite --bs=4k --iodepth=16 --numjobs=4 --size=2G \
--fsync=1 --direct=1 --time_based --runtime=30 --group_reporting
sync4k: (groupid=0, jobs=4): err= 0: pid=1234: Fri Dec 1 12:00:00 2025
write: IOPS=4200, BW=16.4MiB/s (17.2MB/s), lat (usec): min=180, avg=3100, max=55000
Interpretación: Si esperabas IOPS mucho más altas de SSDs y ves latencia media de varios milisegundos, tienes un problema en la pila de almacenamiento. Ashift incorrecto es una causa frecuente, especialmente si los mismos discos rinden bien fuera de ZFS.
Task 11: Comparar con escrituras de bloque mayor para separar “impuesto por escrituras pequeñas” de lentitud general
cr0x@server:~$ sudo fio --name=write128k --directory=/tank/test \
--rw=write --bs=128k --iodepth=32 --numjobs=1 --size=8G \
--direct=1 --time_based --runtime=30 --group_reporting
write128k: (groupid=0, jobs=1): err= 0: pid=1301: Fri Dec 1 12:01:00 2025
write: IOPS=2400, BW=300MiB/s (315MB/s), lat (usec): min=250, avg=400, max=8000
Interpretación: Si las escrituras secuenciales grandes se ven decentes pero las escritas sincronizadas de 4K son terribles, sospecha de amplificación y alineación más que de “el pool está simplemente lento”.
Task 12: Comprobar comportamiento sync de ZFS y si tu carga lo fuerza
cr0x@server:~$ zfs get -o name,property,value sync tank
NAME PROPERTY VALUE
tank sync standard
Interpretación: Muchas cargas en producción dependen de la semántica sync para corrección. Desactivar sync para “arreglar rendimiento” es comprar velocidad a cambio de riesgo de pérdida de datos. Si ashift está mal, sync=disabled puede ocultar el problema hasta el próximo incidente.
Task 13: Comprobar si tienes vdevs especiales y confirmar su ashift también
cr0x@server:~$ zpool status tank | sed -n '/special/,$p'
special
mirror-1
nvme0n1p2
nvme1n1p2
cr0x@server:~$ sudo zdb -C tank | awk '/special|path:|ashift:/{print}'
Interpretación: Los vdevs special almacenan metadata (y opcionalmente bloques pequeños). Si su ashift difiere o es incorrecto para los NVMe, puedes crear cuellos de botella de metadata que parezcan “ZFS está lento”, pero en realidad es “E/S de metadata desalineada y triste”.
Task 14: Confirmar qué ashift elegiría ZFS antes de comprometerte (pool de prueba)
cr0x@server:~$ sudo zpool create -o ashift=12 testpool mirror /dev/sdg /dev/sdh
cr0x@server:~$ sudo zdb -C testpool | awk '/path:|ashift:/{print}'
path: '/dev/sdg'
ashift: 12
path: '/dev/sdh'
ashift: 12
cr0x@server:~$ sudo zpool destroy testpool
Interpretación: Este es el momento más seguro para “arreglar ashift”: antes de que existan datos. Crea un pool pequeño de prueba, verifica ashift en la configuración y destrúyelo. Es un seguro barato.
Task 15: Probar por ti mismo que ashift solo se fija con reconstrucción/migración
cr0x@server:~$ sudo zpool get ashift tank
NAME PROPERTY VALUE SOURCE
tank ashift - -
Interpretación: Mucha gente espera una propiedad a nivel pool. Esa salida es el punto: ashift no es una simple propiedad de pool que puedas alternar. Debes inspeccionar la configuración del vdev.
Guía rápida de diagnóstico
Esta es la versión “estás de guardia y la base de datos está agotando tiempo”. El objetivo es separar rápidamente la desalineación de ashift de las otras docena de maneras en que el almacenamiento puede arruinar tu día.
Paso 1: Confirma que tratas con latencia de almacenamiento, no CPU o red
- Revisa síntomas en la aplicación: timeouts, bloqueos de fsync, picos de “IO wait” en VM.
- En Linux, busca IO wait y crecimiento de la cola de ejecución.
cr0x@server:~$ uptime
12:03:22 up 10 days, 4:11, 2 users, load average: 8.20, 7.10, 6.80
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 7 0 123456 7890 987654 0 0 120 9800 500 900 10 8 40 42 0
Interpretación: Alto wa (IO wait) junto con procesos bloqueados (b) es una pista fuerte: el kernel espera en almacenamiento.
Paso 2: Identifica si el dolor viene de escrituras pequeñas y comportamiento sync-heavy
cr0x@server:~$ sudo zpool iostat -v tank 1 3
Interpretación: Operaciones de escritura altas con ancho de banda relativamente bajo sugiere escrituras pequeñas. Ahí es donde la desalineación aparece primero.
Paso 3: Comprueba latencia y utilización de dispositivos
cr0x@server:~$ iostat -x 1 3
Interpretación: Si los SSD muestran alta utilización y alto w_await durante un rendimiento modesto, sospecha amplificación de escritura bajo ZFS.
Paso 4: Verifica ashift por vdev (no adivines)
cr0x@server:~$ sudo zdb -C tank | awk '/path:|ashift:/{print}'
Interpretación: Si ves ashift: 9 en dispositivos de clase 4K, encontraste un sospechoso principal.
Paso 5: Correlaciona con lo que dicen los tamaños de sector
cr0x@server:~$ lsblk -o NAME,PHY-SeC,LOG-SeC,MODEL /dev/sda
Interpretación: Si físico es 4096 y lógico es 512, y ashift es 9, tu pila está desalineada por diseño.
Paso 6: Decide: mitigar ahora vs arreglar correctamente
- Mitigaciones: reducir presión de sync (con cuidado), mover datasets con muchas escrituras, añadir SLOG si procede, reducir presión de fragmentación.
- Arreglo correcto: reconstruir/migrar a un pool con ashift correcto.
Interpretación: Si esto es producción y los datos importan, la solución correcta casi siempre es “construir un pool nuevo y migrar”. El resto es triage.
Errores comunes: síntomas y soluciones
Error 1: Confiar en el tamaño de sector reportado por el disco
Síntoma: Nuevo pool en discos “modernos” rinde raro en escrituras aleatorias 4K; los SSD muestran alta utilización con bajo ancho de banda.
Por qué ocurre: Los dispositivos 512e reportan 512 lógicos por compatibilidad; ZFS puede elegir ashift=9 a menos que fuerces 12.
Solución: Para la mayoría de dispositivos modernos, usa explícitamente -o ashift=12 al crear con zpool create, y verifica con zdb -C. Si ya está creado y es incorrecto, planifica reconstrucción/migración.
Error 2: Suponer que puedes cambiar ashift después
Síntoma: Alguien intenta zpool set ashift=12 tank y falla o nada cambia; el rendimiento sigue mal.
Por qué ocurre: Ashift está embebido en la configuración del vdev y en el comportamiento de asignación en disco.
Solución: Crea un pool nuevo con ashift correcto y migra datos. Para algunas topologías puedes reemplazar dispositivos/vdevs uno a uno (los espejos son más amables que RAIDZ), pero eso sigue siendo una reconstrucción.
Error 3: Sobrecorregir con ashift demasiado grande en todas partes
Síntoma: El rendimiento parece bien, pero el uso de espacio es inesperadamente alto; los snapshots crecen más rápido; el pool alcanza alarmas de capacidad antes.
Por qué ocurre: Un ashift mayor incrementa el tamaño mínimo de asignación.
Solución: Usa ashift=12 como línea base; considera valores mayores solo para dispositivos/cargas donde hayas medido beneficios y aceptado el overhead.
Error 4: “Arreglar” rendimiento deshabilitando sync
Síntoma: La latencia mejora de inmediato, la dirección declara victoria y luego un corte de energía o kernel panic trae sorpresas desagradables.
Por qué ocurre: Las escrituras sync son caras; desactivar sync sacrifica corrección por velocidad.
Solución: Mantén sync=standard a menos que puedas aceptar formalmente riesgo de pérdida de datos. Si la carga sync es pesada, considera un dispositivo SLOG adecuado, afina la carga o arregla la desalineación subyacente.
Error 5: Mezclar vdevs con distinto ashift o clases de dispositivo
Síntoma: El rendimiento del pool varía impredeciblemente; las expansiones cambian perfiles de latencia; ciertos datasets se vuelven “aleatoriamente” más lentos.
Por qué ocurre: ZFS reparte asignaciones entre vdevs; vdevs más lentos o desalineados pueden dominar la latencia de cola.
Solución: Mantén vdevs homogéneos en rendimiento y supuestos de ashift cuando sea posible. Si debes mezclar, aísla las cargas en pools separados.
Listas de verificación / plan paso a paso
Lista A: Construir un pool nuevo (hazlo bien la primera vez)
- Inventario de dispositivos y captura de tamaños de bloque físico/lógico.
- Decidir ashift baseline (típicamente 12 para HDD/SSD modernos).
- Crear un pool de prueba temporal, verificar ashift con
zdb -C, destruirlo. - Crear el pool real con ashift explícito.
- Validar rendimiento con escrituras aleatorias pequeñas y comportamiento sync antes de que lleguen datos de producción.
cr0x@server:~$ lsblk -o NAME,MODEL,PHY-SeC,LOG-SeC,ROTA,SIZE
cr0x@server:~$ sudo zpool create -o ashift=12 tank raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf
cr0x@server:~$ sudo zdb -C tank | awk '/path:|ashift:/{print}'
cr0x@server:~$ zpool status tank
Interpretación: Lo importante no es el comando; es la verificación. Si no compruebas ashift inmediatamente, solo lo harás más tarde cuando duela.
Lista B: Migrar desde un pool con ashift incorrecto minimizando el drama
- Construir un pool nuevo con ashift correcto, idealmente en hardware nuevo o dispositivos recién preparados.
- Replicar datasets con ZFS send/receive para preservar snapshots y propiedades.
- Cortar clientes con una ventana de mantenimiento controlada (o corte por etapas si el entorno lo permite).
- Mantener el pool antiguo en solo-lectura por una ventana de rollback si puedes permitirlo.
cr0x@server:~$ sudo zpool create -o ashift=12 tank2 mirror /dev/sdg /dev/sdh
cr0x@server:~$ sudo zfs snapshot -r tank@pre-migrate
cr0x@server:~$ sudo zfs send -R tank@pre-migrate | sudo zfs receive -F tank2
cr0x@server:~$ zfs list -r tank2
Interpretación: Esta es la solución “limpia”: mover datos a un pool correctamente alineado. Es operativamente sencilla, testeable y reversible si mantienes la fuente un tiempo.
Lista C: Si estás atrapado con ashift incorrecto por ahora (triage, no cura)
- Identifica los peores culpables: datasets o zvols con escrituras sincronizadas pequeñas intensas.
- Mueve esas cargas primero (incluso a un pequeño pool correctamente alineado) para reducir latencia de cola.
- Confirma que no estés en niveles altos de llenado del pool; la presión de capacidad empeora todo.
- Mide antes/después con el mismo job de fio, misma ventana de tiempo y captura de
zpool iostat.
cr0x@server:~$ zfs list -o name,used,avail,refer,mountpoint -r tank
cr0x@server:~$ zpool list -o name,size,alloc,free,capacity,health tank
cr0x@server:~$ sudo fio --name=triage --directory=/tank/test --rw=randwrite --bs=4k --fsync=1 --iodepth=8 --numjobs=2 --size=1G --runtime=20 --time_based --direct=1 --group_reporting
Interpretación: Si no puedes reconstruir inmediatamente, aísla las cargas más sensibles a latencia y reduce su exposición al pool desalineado. Pero trátalo como una estrategia temporal de contención.
Preguntas frecuentes
1) ¿Qué ashift debo usar para discos modernos?
Para la mayoría de HDD y SSD modernos, ashift=12 es la opción sensata por defecto. Alinea asignaciones a 4K y evita las peores penalidades de desalineación en dispositivos 512e.
2) ¿Cuándo sería correcto usar ashift=9?
Raramente, en dispositivos verdaderamente 512-native donde tengas evidencia sólida de que las escrituras de 512B se soportan eficientemente de extremo a extremo. En la práctica, la mayoría de administradores eligen 12 para evitar ser engañados por reportes de compatibilidad.
3) ¿Puedo cambiar ashift después de crear el pool?
No in situ para vdevs/datos existentes. Puedes migrar construyendo un pool nuevo y moviendo datos, o en algunos diseños reemplazar dispositivos/vdevs como parte de una estrategia de reconstrucción. Pero no hay un “toggle” que realinee bloques existentes.
4) ¿Cómo compruebo ashift en un pool en vivo?
Usa zdb -C <pool> y busca ashift bajo cada leaf vdev. No existe una propiedad simple de zpool get que lo reporte de forma fiable como un único valor.
5) Si pongo ashift=12 en un dispositivo 512-native, ¿romperá algo?
No romperá la corrección, pero puede desperdiciar espacio y reducir ligeramente la eficiencia para bloques muy pequeños. Normalmente, la seguridad operacional de evitar desalineación compensa el coste de espacio.
6) ¿Por qué un ashift incorrecto aparece más con virtualización y bases de datos?
Porque esas cargas generan muchas escrituras aleatorias pequeñas y a menudo requieren semántica sync. Esa combinación magnifica los impuestos RMW y la latencia de cola.
7) ¿Importa recordsize/volblocksize si ashift es correcto?
Sí. Ashift evita las peores patologías de alineación en el límite del dispositivo, pero el tamaño de bloque de tu carga sigue determinando patrones de E/S, amplificación y comportamiento de caché. Piensa en ashift como “no pisar un rastrillo” y en recordsize como “caminar eficientemente”.
8) Tengo un vdev special (metadata) en NVMe. ¿Debo preocuparme también por ashift allí?
Absolutamente. Los vdev special pueden convertirse en la compuerta de latencia para cargas ricas en metadata. Si están desalineados o mal emparejados, pueden estrechar todo el pool de formas que no parecen “un disco lento”, sino “todo está inestable”.
9) ¿Es ashift la única razón por la que ZFS puede ser lento?
No. Fragmentación, un pool sobrellenado, una mala elección de SLOG, peculiaridades del controlador, discos SMR, problemas de profundidad de cola y desajuste de carga pueden perjudicar. La razón por la que ashift recibe atención especial es que puede perjudicar silenciosamente el rendimiento desde el día uno y no se arregla con un simple cambio de propiedad.
10) ¿Cuál es el enfoque operativo más seguro?
Estandariza: inventaría tamaños de sector, por defecto usa ashift=12, verifica inmediatamente después de crear el pool y guarda la evidencia. Trata ashift como el nivel RAID: una decisión de diseño, no un parámetro de ajuste.
Conclusión
Ashift es uno de esos detalles que parece demasiado pequeño para importar—hasta que importa más que el modelo de tu CPU, tu tejido de red y la mitad de tu trabajo de ajuste combinado. Lo silencioso es el peligro: un ashift incorrecto no falla de forma ruidosa. Simplemente vierte rendimiento hasta el suelo y convierte cargas previsibles en loterías de latencia.
La mentalidad de producción es simple: no confíes en el marketing del dispositivo, no confíes en la autodetección por defecto y no despliegues un pool que no hayas interrogado con zdb -C. Si ya tienes un pool con ashift incorrecto, no pierdas semanas puliendo síntomas. Construye el pool correctamente alineado y migra con un plan. El pager te lo agradecerá, aunque nunca lo diga.