Problema

En entornos de virtualización con Proxmox, el número de operaciones FSYNC por segundo suele ser un buen indicador de cuán rápido el hipervisor puede confirmar escrituras en disco. Cuando el valor es bajo, las VM y los contenedores experimentan latencias altas en I/O, especialmente en cargas de trabajo que dependen de bases de datos, logs o snapshots. El patrón típico es un pool ZFS configurado sobre discos mecánicos (SAS o SATA) que, pese a ofrecer redundancia, entrega menos de 100 FSYNC/s, mientras que una solución basada en SSD puede alcanzar varios miles. El problema se vuelve crítico cuando se intenta combinar almacenamiento de máquinas virtuales y datos de respaldo en el mismo conjunto de discos, o cuando se ignoran parámetros de sincronización que ZFS aplica por defecto.

Causa

  1. Latencia inherente de los discos mecánicos
    Los discos de 10 K RPM tienen tiempos de búsqueda y rotación que limitan la frecuencia de commits. ZFS escribe metadatos y bloques de datos en transacciones de 5 s por defecto; cada transacción implica un FSYNC. Con varios discos en ZRAID10, la mejora es marginal porque el cuello de botella sigue siendo la velocidad de rotación.

  2. Configuración de pool inadecuada para la carga

    • ZRAID2 (o RAID‑Z2) está pensado para tolerar dos fallos simultáneos, pero implica más cálculos de paridad y más escrituras de metadatos.
    • ZRAID10 mejora la latencia al distribuir datos y copias, pero sigue dependiendo de la velocidad del medio subyacente.
    • ZRAID1 con dos SSD reduce dramáticamente la latencia porque los SSD pueden confirmar escrituras en microsegundos.
  3. Parámetros de sincronización por defecto
    ZFS habilita sync=standard, lo que obliga a que cada fsync() del cliente se convierta en una escritura física. En discos mecánicos esto se traduce en esperas de varios milisegundos por operación. Opciones como sync=disabled o atime=off pueden eliminar la mayor parte de la carga, pero a costa de perder consistencia ante cortes de energía.

  4. Hardware RAID vs. ZFS nativo
    Controladores como el PERC H730P gestionan caché de escritura y pueden agrupar varios discos en RAID1, ofreciendo un rendimiento de FSYNC superior al de ZFS puro en algunos casos, siempre que la caché esté habilitada y alimentada por batería.

  5. Falta de SSD para caché o log
    ZFS permite asignar dispositivos de tipo log (SLOG) y cache (L2ARC). Sin un SLOG dedicado, cada transacción depende del pool principal, lo que penaliza los FSYNC en discos lentos.

Solución

1. Rediseñar la topología del pool

  • Separar workloads: Usa SSD exclusivamente para OS, VM y contenedores críticos. Configura un pool rpool en ZRAID1 con 2 x SSD (mirrored).
  • Reservar discos mecánicos para backups, archivos estáticos y streams. Crea un pool backup en ZRAID10 con los 10 discos SAS. Esta separación evita que la latencia de los discos mecánicos afecte a los FSYNC de las VM.

2. Añadir un SLOG basado en SSD

Instala un SSD de alta resistencia (por ejemplo, Intel Optane o un modelo con Endurance > 1 PBW) y asígnalo como log al pool de VM:

zpool add rpool log /dev/disk/by-id/ssd-optane

El SLOG almacena temporalmente los commits de sync=standard, permitiendo que el pool principal siga escribiendo a su ritmo mientras el SLOG confirma rápidamente.

3. Ajustar parámetros de sincronización

Para entornos donde la pérdida de datos ante un corte de energía es aceptable (p. ej., homelab sin SLA), desactivar sync brinda ganancias drásticas:

zfs set sync=disabled rpool

Si se necesita mantener la integridad, usar sync=always solo en datasets críticos y dejar el resto en standard.

Desactivar la actualización de tiempo de acceso (atime) y habilitar TRIM en SSD mejora el rendimiento de lecturas y evita escrituras innecesarias:

zfs set atime=off rpool
zfs set com.sun:auto-snapshot=false rpool   # opcional, evita snapshots automáticos

Para SSD con soporte de TRIM:

zpool set autotrim=on rpool

4. Optimizar el tamaño de la caché de escritura

Ajustar recordsize y primarycache según la carga:

zfs set recordsize=128K backup
zfs set primarycache=metadata backup

Los bloques más grandes reducen la cantidad de transacciones y, por tanto, los FSYNC.

5. Evaluar hardware RAID cuando sea necesario

Si el controlador RAID dispone de caché con batería (BBU) y está bien configurado, puede superar a ZFS en FSYNC para discos mecánicos. En ese caso, crea el pool sobre el dispositivo virtual del RAID y mantén el SLOG en SSD para los workloads críticos.

6. Monitorear y validar

Utiliza pveperf o fio para medir FSYNC antes y después de los cambios. Un salto típico pasa de < 100 FSYNC/s a > 3 000 FSYNC/s con SSD + SLOG, y a > 20 000 FSYNC/s cuando se desactiva sync en discos SAS.

Cuándo aplicar esta solución

  • Síntomas: alta latencia en VM, errores de timeout en bases de datos, métricas de pveperf con FSYNC < 200 s.
  • Entornos: homelabs, pruebas de desarrollo, o servidores con carga mixta donde la pérdida ocasional de datos es tolerable.
  • No aplicar: entornos de producción con requisitos de alta disponibilidad y protección contra cortes de energía, a menos que se implemente un SLOG con batería o un UPS que garantice integridad del SLOG.

Código

# Crear pool de sistema en SSD (mirrored)
zpool create -f rpool mirror /dev/disk/by-id/ssd1 /dev/disk/by-id/ssd2

# Añadir SLOG de alta resistencia
zpool add rpool log /dev/disk/by-id/ssd-optane

# Crear pool de backup en discos SAS (ZRAID10)
zpool create -f backup raidz1 /dev/disk/by-id/sas1 /dev/disk/by-id/sas2 \
    /dev/disk/by-id/sas3 /dev/disk/by-id/sas4 /dev/disk/by-id/sas5 \
    /dev/disk/by-id/sas6 /dev/disk/by-id/sas7 /dev/disk/by-id/sas8 \
    /dev/disk/by-id/sas9 /dev/disk/by-id/sas10

# Desactivar sync en pool de backup (solo si el riesgo es aceptable)
zfs set sync=disabled backup

# Optimizar parámetros
zfs set atime=off rpool
zpool set autotrim=on rpool
zfs set recordsize=128K backup
zfs set primarycache=metadata backup

Verificación

  1. Ejecutar pveperf antes de los cambios y guardar los valores de FSYNCS/SEC.
  2. Aplicar la nueva arquitectura y los ajustes de ZFS.
  3. Volver a correr pveperf. Un incremento de al menos 5× indica que el SLOG y los SSD están funcionando correctamente.
  4. Simular una caída de energía (desconectar la alimentación) y comprobar la integridad de los datasets críticos. Si se usó sync=disabled, validar que los snapshots recientes siguen consistentes gracias al SLOG.

Notas adicionales

  • Un SLOG sin respaldo de batería pierde datos si el servidor se apaga abruptamente; combina el SSD con una UPS para mitigar el riesgo.
  • En discos SAS de 10 K RPM, la mejora de FSYNC al desactivar sync puede ser de 10‑20×, pero la pérdida de consistencia es real.
  • Mantener los firmware de los controladores RAID y de los SSD actualizados evita cuellos de rendimiento inesperados.
  • Si el pool de backup se usa también para streaming de video o cámaras, considera habilitar compression=lz4 para reducir I/O sin impactar mucho la CPU.